18dbe44cbSFlorian Hahn //===-- Annotation2Metadata.cpp - Add !annotation metadata. ---------------===// 28dbe44cbSFlorian Hahn // 38dbe44cbSFlorian Hahn // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48dbe44cbSFlorian Hahn // See https://llvm.org/LICENSE.txt for license information. 58dbe44cbSFlorian Hahn // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68dbe44cbSFlorian Hahn // 78dbe44cbSFlorian Hahn //===----------------------------------------------------------------------===// 88dbe44cbSFlorian Hahn // 98dbe44cbSFlorian Hahn // Add !annotation metadata for entries in @llvm.global.anotations, generated 108dbe44cbSFlorian Hahn // using __attribute__((annotate("_name"))) on functions in Clang. 118dbe44cbSFlorian Hahn // 128dbe44cbSFlorian Hahn //===----------------------------------------------------------------------===// 138dbe44cbSFlorian Hahn 148dbe44cbSFlorian Hahn #include "llvm/Transforms/IPO/Annotation2Metadata.h" 158dbe44cbSFlorian Hahn #include "llvm/Analysis/OptimizationRemarkEmitter.h" 168dbe44cbSFlorian Hahn #include "llvm/IR/Constants.h" 178dbe44cbSFlorian Hahn #include "llvm/IR/Function.h" 188dbe44cbSFlorian Hahn #include "llvm/IR/InstIterator.h" 198dbe44cbSFlorian Hahn #include "llvm/IR/Module.h" 208dbe44cbSFlorian Hahn 218dbe44cbSFlorian Hahn using namespace llvm; 228dbe44cbSFlorian Hahn 238dbe44cbSFlorian Hahn #define DEBUG_TYPE "annotation2metadata" 248dbe44cbSFlorian Hahn 258dbe44cbSFlorian Hahn static bool convertAnnotation2Metadata(Module &M) { 268dbe44cbSFlorian Hahn // Only add !annotation metadata if the corresponding remarks pass is also 278dbe44cbSFlorian Hahn // enabled. 288dbe44cbSFlorian Hahn if (!OptimizationRemarkEmitter::allowExtraAnalysis(M.getContext(), 298dbe44cbSFlorian Hahn "annotation-remarks")) 308dbe44cbSFlorian Hahn return false; 318dbe44cbSFlorian Hahn 328dbe44cbSFlorian Hahn auto *Annotations = M.getGlobalVariable("llvm.global.annotations"); 338dbe44cbSFlorian Hahn auto *C = dyn_cast_or_null<Constant>(Annotations); 348dbe44cbSFlorian Hahn if (!C || C->getNumOperands() != 1) 358dbe44cbSFlorian Hahn return false; 368dbe44cbSFlorian Hahn 378dbe44cbSFlorian Hahn C = cast<Constant>(C->getOperand(0)); 388dbe44cbSFlorian Hahn 398dbe44cbSFlorian Hahn // Iterate over all entries in C and attach !annotation metadata to suitable 408dbe44cbSFlorian Hahn // entries. 418dbe44cbSFlorian Hahn for (auto &Op : C->operands()) { 428dbe44cbSFlorian Hahn // Look at the operands to check if we can use the entry to generate 438dbe44cbSFlorian Hahn // !annotation metadata. 448dbe44cbSFlorian Hahn auto *OpC = dyn_cast<ConstantStruct>(&Op); 458dbe44cbSFlorian Hahn if (!OpC || OpC->getNumOperands() != 4) 468dbe44cbSFlorian Hahn continue; 474c3e25d3SNikita Popov auto *StrC = dyn_cast<GlobalValue>(OpC->getOperand(1)->stripPointerCasts()); 488dbe44cbSFlorian Hahn if (!StrC) 498dbe44cbSFlorian Hahn continue; 508dbe44cbSFlorian Hahn auto *StrData = dyn_cast<ConstantDataSequential>(StrC->getOperand(0)); 518dbe44cbSFlorian Hahn if (!StrData) 528dbe44cbSFlorian Hahn continue; 534c3e25d3SNikita Popov auto *Fn = dyn_cast<Function>(OpC->getOperand(0)->stripPointerCasts()); 548dbe44cbSFlorian Hahn if (!Fn) 558dbe44cbSFlorian Hahn continue; 568dbe44cbSFlorian Hahn 578dbe44cbSFlorian Hahn // Add annotation to all instructions in the function. 588dbe44cbSFlorian Hahn for (auto &I : instructions(Fn)) 598dbe44cbSFlorian Hahn I.addAnnotationMetadata(StrData->getAsCString()); 608dbe44cbSFlorian Hahn } 618dbe44cbSFlorian Hahn return true; 628dbe44cbSFlorian Hahn } 638dbe44cbSFlorian Hahn 648dbe44cbSFlorian Hahn PreservedAnalyses Annotation2MetadataPass::run(Module &M, 658dbe44cbSFlorian Hahn ModuleAnalysisManager &AM) { 66*c0cb758eSArthur Eubanks return convertAnnotation2Metadata(M) ? PreservedAnalyses::none() 67*c0cb758eSArthur Eubanks : PreservedAnalyses::all(); 688dbe44cbSFlorian Hahn } 69