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/Transforms/IPO.h" 21 22 using namespace llvm; 23 24 #define DEBUG_TYPE "annotation2metadata" 25 26 static bool convertAnnotation2Metadata(Module &M) { 27 // Only add !annotation metadata if the corresponding remarks pass is also 28 // enabled. 29 if (!OptimizationRemarkEmitter::allowExtraAnalysis(M.getContext(), 30 "annotation-remarks")) 31 return false; 32 33 auto *Annotations = M.getGlobalVariable("llvm.global.annotations"); 34 auto *C = dyn_cast_or_null<Constant>(Annotations); 35 if (!C || C->getNumOperands() != 1) 36 return false; 37 38 C = cast<Constant>(C->getOperand(0)); 39 40 // Iterate over all entries in C and attach !annotation metadata to suitable 41 // entries. 42 for (auto &Op : C->operands()) { 43 // Look at the operands to check if we can use the entry to generate 44 // !annotation metadata. 45 auto *OpC = dyn_cast<ConstantStruct>(&Op); 46 if (!OpC || OpC->getNumOperands() != 4) 47 continue; 48 auto *StrC = dyn_cast<GlobalValue>(OpC->getOperand(1)->stripPointerCasts()); 49 if (!StrC) 50 continue; 51 auto *StrData = dyn_cast<ConstantDataSequential>(StrC->getOperand(0)); 52 if (!StrData) 53 continue; 54 auto *Fn = dyn_cast<Function>(OpC->getOperand(0)->stripPointerCasts()); 55 if (!Fn) 56 continue; 57 58 // Add annotation to all instructions in the function. 59 for (auto &I : instructions(Fn)) 60 I.addAnnotationMetadata(StrData->getAsCString()); 61 } 62 return true; 63 } 64 65 PreservedAnalyses Annotation2MetadataPass::run(Module &M, 66 ModuleAnalysisManager &AM) { 67 return convertAnnotation2Metadata(M) ? PreservedAnalyses::none() 68 : PreservedAnalyses::all(); 69 } 70