1 //===-- AnnotationRemarks.cpp - Generate remarks for annotated instrs. ----===// 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 // Generate remarks for instructions marked with !annotation. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Transforms/Scalar/AnnotationRemarks.h" 14 #include "llvm/ADT/MapVector.h" 15 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 16 #include "llvm/Analysis/TargetLibraryInfo.h" 17 #include "llvm/IR/Function.h" 18 #include "llvm/IR/InstIterator.h" 19 #include "llvm/InitializePasses.h" 20 #include "llvm/Pass.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Transforms/Scalar.h" 23 24 using namespace llvm; 25 using namespace llvm::ore; 26 27 #define DEBUG_TYPE "annotation-remarks" 28 #define REMARK_PASS DEBUG_TYPE 29 30 static void runImpl(Function &F) { 31 if (!OptimizationRemarkEmitter::allowExtraAnalysis(F, REMARK_PASS)) 32 return; 33 34 OptimizationRemarkEmitter ORE(&F); 35 // For now, just generate a summary of the annotated instructions. 36 MapVector<StringRef, unsigned> Mapping; 37 for (Instruction &I : instructions(F)) { 38 if (!I.hasMetadata(LLVMContext::MD_annotation)) 39 continue; 40 for (const MDOperand &Op : 41 I.getMetadata(LLVMContext::MD_annotation)->operands()) { 42 auto Iter = Mapping.insert({cast<MDString>(Op.get())->getString(), 0}); 43 Iter.first->second++; 44 } 45 } 46 47 Instruction *IP = &*F.begin()->begin(); 48 for (const auto &KV : Mapping) 49 ORE.emit(OptimizationRemarkAnalysis(REMARK_PASS, "AnnotationSummary", IP) 50 << "Annotated " << NV("count", KV.second) << " instructions with " 51 << NV("type", KV.first)); 52 } 53 54 namespace { 55 56 struct AnnotationRemarksLegacy : public FunctionPass { 57 static char ID; 58 59 AnnotationRemarksLegacy() : FunctionPass(ID) { 60 initializeAnnotationRemarksLegacyPass(*PassRegistry::getPassRegistry()); 61 } 62 63 bool runOnFunction(Function &F) override { 64 runImpl(F); 65 return false; 66 } 67 68 void getAnalysisUsage(AnalysisUsage &AU) const override { 69 AU.setPreservesAll(); 70 } 71 }; 72 73 } // end anonymous namespace 74 75 char AnnotationRemarksLegacy::ID = 0; 76 77 INITIALIZE_PASS_BEGIN(AnnotationRemarksLegacy, "annotation-remarks", 78 "Annotation Remarks", false, false) 79 INITIALIZE_PASS_END(AnnotationRemarksLegacy, "annotation-remarks", 80 "Annotation Remarks", false, false) 81 82 FunctionPass *llvm::createAnnotationRemarksLegacyPass() { 83 return new AnnotationRemarksLegacy(); 84 } 85 86 PreservedAnalyses AnnotationRemarksPass::run(Function &F, 87 FunctionAnalysisManager &AM) { 88 runImpl(F); 89 return PreservedAnalyses::all(); 90 } 91