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 
runImpl(Function & F)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 
AnnotationRemarksLegacy__anon1a556cbb0111::AnnotationRemarksLegacy59   AnnotationRemarksLegacy() : FunctionPass(ID) {
60     initializeAnnotationRemarksLegacyPass(*PassRegistry::getPassRegistry());
61   }
62 
runOnFunction__anon1a556cbb0111::AnnotationRemarksLegacy63   bool runOnFunction(Function &F) override {
64     runImpl(F);
65     return false;
66   }
67 
getAnalysisUsage__anon1a556cbb0111::AnnotationRemarksLegacy68   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 
createAnnotationRemarksLegacyPass()82 FunctionPass *llvm::createAnnotationRemarksLegacyPass() {
83   return new AnnotationRemarksLegacy();
84 }
85 
run(Function & F,FunctionAnalysisManager & AM)86 PreservedAnalyses AnnotationRemarksPass::run(Function &F,
87                                              FunctionAnalysisManager &AM) {
88   runImpl(F);
89   return PreservedAnalyses::all();
90 }
91