1 //===- Transforms/Instrumentation/InstrProfiling.h --------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// This file provides the interface for LLVM's PGO Instrumentation lowering 11 /// pass. 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_TRANSFORMS_INSTRPROFILING_H 15 #define LLVM_TRANSFORMS_INSTRPROFILING_H 16 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/IR/IntrinsicInst.h" 20 #include "llvm/IR/PassManager.h" 21 #include "llvm/ProfileData/InstrProf.h" 22 #include "llvm/Transforms/Instrumentation.h" 23 #include <cstddef> 24 #include <cstdint> 25 #include <cstring> 26 #include <vector> 27 28 namespace llvm { 29 30 class TargetLibraryInfo; 31 using LoadStorePair = std::pair<Instruction *, Instruction *>; 32 33 /// Instrumentation based profiling lowering pass. This pass lowers 34 /// the profile instrumented code generated by FE or the IR based 35 /// instrumentation pass. 36 class InstrProfiling : public PassInfoMixin<InstrProfiling> { 37 public: 38 InstrProfiling() = default; InstrProfiling(const InstrProfOptions & Options)39 InstrProfiling(const InstrProfOptions &Options) : Options(Options) {} 40 41 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 42 bool run(Module &M, const TargetLibraryInfo &TLI); 43 44 private: 45 InstrProfOptions Options; 46 Module *M; 47 Triple TT; 48 const TargetLibraryInfo *TLI; 49 struct PerFunctionProfileData { 50 uint32_t NumValueSites[IPVK_Last + 1]; 51 GlobalVariable *RegionCounters = nullptr; 52 GlobalVariable *DataVar = nullptr; 53 PerFunctionProfileDataPerFunctionProfileData54 PerFunctionProfileData() { 55 memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last + 1)); 56 } 57 }; 58 DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap; 59 std::vector<GlobalValue *> UsedVars; 60 std::vector<GlobalVariable *> ReferencedNames; 61 GlobalVariable *NamesVar; 62 size_t NamesSize; 63 64 // vector of counter load/store pairs to be register promoted. 65 std::vector<LoadStorePair> PromotionCandidates; 66 67 // The start value of precise value profile range for memory intrinsic sizes. 68 int64_t MemOPSizeRangeStart; 69 // The end value of precise value profile range for memory intrinsic sizes. 70 int64_t MemOPSizeRangeLast; 71 72 int64_t TotalCountersPromoted = 0; 73 74 /// Lower instrumentation intrinsics in the function. Returns true if there 75 /// any lowering. 76 bool lowerIntrinsics(Function *F); 77 78 /// Register-promote counter loads and stores in loops. 79 void promoteCounterLoadStores(Function *F); 80 81 /// Returns true if profile counter update register promotion is enabled. 82 bool isCounterPromotionEnabled() const; 83 84 /// Count the number of instrumented value sites for the function. 85 void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins); 86 87 /// Replace instrprof_value_profile with a call to runtime library. 88 void lowerValueProfileInst(InstrProfValueProfileInst *Ins); 89 90 /// Replace instrprof_increment with an increment of the appropriate value. 91 void lowerIncrement(InstrProfIncrementInst *Inc); 92 93 /// Force emitting of name vars for unused functions. 94 void lowerCoverageData(GlobalVariable *CoverageNamesVar); 95 96 /// Get the region counters for an increment, creating them if necessary. 97 /// 98 /// If the counter array doesn't yet exist, the profile data variables 99 /// referring to them will also be created. 100 GlobalVariable *getOrCreateRegionCounters(InstrProfIncrementInst *Inc); 101 102 /// Emit the section with compressed function names. 103 void emitNameData(); 104 105 /// Emit value nodes section for value profiling. 106 void emitVNodes(); 107 108 /// Emit runtime registration functions for each profile data variable. 109 void emitRegistration(); 110 111 /// Emit the necessary plumbing to pull in the runtime initialization. 112 /// Returns true if a change was made. 113 bool emitRuntimeHook(); 114 115 /// Add uses of our data variables and runtime hook. 116 void emitUses(); 117 118 /// Create a static initializer for our data, on platforms that need it, 119 /// and for any profile output file that was specified. 120 void emitInitialization(); 121 }; 122 123 } // end namespace llvm 124 125 #endif // LLVM_TRANSFORMS_INSTRPROFILING_H 126