1 //===-- Annotation2Metadata.cpp - Add !annotation metadata. ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Add !annotation metadata for entries in @llvm.global.anotations, generated 10 // using __attribute__((annotate("_name"))) on functions in Clang. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/IPO/Annotation2Metadata.h" 15 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 16 #include "llvm/IR/Constants.h" 17 #include "llvm/IR/Function.h" 18 #include "llvm/IR/InstIterator.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/InitializePasses.h" 21 #include "llvm/Pass.h" 22 #include "llvm/Transforms/IPO.h" 23 24 using namespace llvm; 25 26 #define DEBUG_TYPE "annotation2metadata" 27 28 static bool convertAnnotation2Metadata(Module &M) { 29 // Only add !annotation metadata if the corresponding remarks pass is also 30 // enabled. 31 if (!OptimizationRemarkEmitter::allowExtraAnalysis(M.getContext(), 32 "annotation-remarks")) 33 return false; 34 35 auto *Annotations = M.getGlobalVariable("llvm.global.annotations"); 36 auto *C = dyn_cast_or_null<Constant>(Annotations); 37 if (!C || C->getNumOperands() != 1) 38 return false; 39 40 C = cast<Constant>(C->getOperand(0)); 41 42 // Iterate over all entries in C and attach !annotation metadata to suitable 43 // entries. 44 for (auto &Op : C->operands()) { 45 // Look at the operands to check if we can use the entry to generate 46 // !annotation metadata. 47 auto *OpC = dyn_cast<ConstantStruct>(&Op); 48 if (!OpC || OpC->getNumOperands() != 4) 49 continue; 50 auto *StrC = dyn_cast<GlobalValue>(OpC->getOperand(1)->stripPointerCasts()); 51 if (!StrC) 52 continue; 53 auto *StrData = dyn_cast<ConstantDataSequential>(StrC->getOperand(0)); 54 if (!StrData) 55 continue; 56 auto *Fn = dyn_cast<Function>(OpC->getOperand(0)->stripPointerCasts()); 57 if (!Fn) 58 continue; 59 60 // Add annotation to all instructions in the function. 61 for (auto &I : instructions(Fn)) 62 I.addAnnotationMetadata(StrData->getAsCString()); 63 } 64 return true; 65 } 66 67 namespace { 68 struct Annotation2MetadataLegacy : public ModulePass { 69 static char ID; 70 71 Annotation2MetadataLegacy() : ModulePass(ID) { 72 initializeAnnotation2MetadataLegacyPass(*PassRegistry::getPassRegistry()); 73 } 74 75 bool runOnModule(Module &M) override { return convertAnnotation2Metadata(M); } 76 77 void getAnalysisUsage(AnalysisUsage &AU) const override { 78 AU.setPreservesAll(); 79 } 80 }; 81 82 } // end anonymous namespace 83 84 char Annotation2MetadataLegacy::ID = 0; 85 86 INITIALIZE_PASS_BEGIN(Annotation2MetadataLegacy, DEBUG_TYPE, 87 "Annotation2Metadata", false, false) 88 INITIALIZE_PASS_END(Annotation2MetadataLegacy, DEBUG_TYPE, 89 "Annotation2Metadata", false, false) 90 91 ModulePass *llvm::createAnnotation2MetadataLegacyPass() { 92 return new Annotation2MetadataLegacy(); 93 } 94 95 PreservedAnalyses Annotation2MetadataPass::run(Module &M, 96 ModuleAnalysisManager &AM) { 97 convertAnnotation2Metadata(M); 98 return PreservedAnalyses::all(); 99 } 100