Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- Transforms/Instrumentation/InstrProfiling.h --------------*- C++ -*-===// |
| 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 | /// \file |
||
| 9 | /// This file provides the interface for LLVM's PGO Instrumentation lowering |
||
| 10 | /// pass. |
||
| 11 | //===----------------------------------------------------------------------===// |
||
| 12 | |||
| 13 | #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H |
||
| 14 | #define LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H |
||
| 15 | |||
| 16 | #include "llvm/ADT/DenseMap.h" |
||
| 17 | #include "llvm/ADT/StringRef.h" |
||
| 18 | #include "llvm/IR/IntrinsicInst.h" |
||
| 19 | #include "llvm/IR/PassManager.h" |
||
| 20 | #include "llvm/ProfileData/InstrProf.h" |
||
| 21 | #include "llvm/Transforms/Instrumentation.h" |
||
| 22 | #include <cstdint> |
||
| 23 | #include <cstring> |
||
| 24 | #include <vector> |
||
| 25 | |||
| 26 | namespace llvm { |
||
| 27 | |||
| 28 | class TargetLibraryInfo; |
||
| 29 | using LoadStorePair = std::pair<Instruction *, Instruction *>; |
||
| 30 | |||
| 31 | /// Instrumentation based profiling lowering pass. This pass lowers |
||
| 32 | /// the profile instrumented code generated by FE or the IR based |
||
| 33 | /// instrumentation pass. |
||
| 34 | class InstrProfiling : public PassInfoMixin<InstrProfiling> { |
||
| 35 | public: |
||
| 36 | InstrProfiling() : IsCS(false) {} |
||
| 37 | InstrProfiling(const InstrProfOptions &Options, bool IsCS = false) |
||
| 38 | : Options(Options), IsCS(IsCS) {} |
||
| 39 | |||
| 40 | PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); |
||
| 41 | bool run(Module &M, |
||
| 42 | std::function<const TargetLibraryInfo &(Function &F)> GetTLI); |
||
| 43 | |||
| 44 | private: |
||
| 45 | InstrProfOptions Options; |
||
| 46 | Module *M; |
||
| 47 | Triple TT; |
||
| 48 | std::function<const TargetLibraryInfo &(Function &F)> GetTLI; |
||
| 49 | struct PerFunctionProfileData { |
||
| 50 | uint32_t NumValueSites[IPVK_Last + 1]; |
||
| 51 | GlobalVariable *RegionCounters = nullptr; |
||
| 52 | GlobalVariable *DataVar = nullptr; |
||
| 53 | |||
| 54 | PerFunctionProfileData() { |
||
| 55 | memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last + 1)); |
||
| 56 | } |
||
| 57 | }; |
||
| 58 | DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap; |
||
| 59 | /// If runtime relocation is enabled, this maps functions to the load |
||
| 60 | /// instruction that produces the profile relocation bias. |
||
| 61 | DenseMap<const Function *, LoadInst *> FunctionToProfileBiasMap; |
||
| 62 | std::vector<GlobalValue *> CompilerUsedVars; |
||
| 63 | std::vector<GlobalValue *> UsedVars; |
||
| 64 | std::vector<GlobalVariable *> ReferencedNames; |
||
| 65 | GlobalVariable *NamesVar; |
||
| 66 | size_t NamesSize; |
||
| 67 | |||
| 68 | // Is this lowering for the context-sensitive instrumentation. |
||
| 69 | bool IsCS; |
||
| 70 | |||
| 71 | // vector of counter load/store pairs to be register promoted. |
||
| 72 | std::vector<LoadStorePair> PromotionCandidates; |
||
| 73 | |||
| 74 | int64_t TotalCountersPromoted = 0; |
||
| 75 | |||
| 76 | /// Lower instrumentation intrinsics in the function. Returns true if there |
||
| 77 | /// any lowering. |
||
| 78 | bool lowerIntrinsics(Function *F); |
||
| 79 | |||
| 80 | /// Register-promote counter loads and stores in loops. |
||
| 81 | void promoteCounterLoadStores(Function *F); |
||
| 82 | |||
| 83 | /// Returns true if relocating counters at runtime is enabled. |
||
| 84 | bool isRuntimeCounterRelocationEnabled() const; |
||
| 85 | |||
| 86 | /// Returns true if profile counter update register promotion is enabled. |
||
| 87 | bool isCounterPromotionEnabled() const; |
||
| 88 | |||
| 89 | /// Count the number of instrumented value sites for the function. |
||
| 90 | void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins); |
||
| 91 | |||
| 92 | /// Replace instrprof.value.profile with a call to runtime library. |
||
| 93 | void lowerValueProfileInst(InstrProfValueProfileInst *Ins); |
||
| 94 | |||
| 95 | /// Replace instrprof.cover with a store instruction to the coverage byte. |
||
| 96 | void lowerCover(InstrProfCoverInst *Inc); |
||
| 97 | |||
| 98 | /// Replace instrprof.increment with an increment of the appropriate value. |
||
| 99 | void lowerIncrement(InstrProfIncrementInst *Inc); |
||
| 100 | |||
| 101 | /// Force emitting of name vars for unused functions. |
||
| 102 | void lowerCoverageData(GlobalVariable *CoverageNamesVar); |
||
| 103 | |||
| 104 | /// Compute the address of the counter value that this profiling instruction |
||
| 105 | /// acts on. |
||
| 106 | Value *getCounterAddress(InstrProfInstBase *I); |
||
| 107 | |||
| 108 | /// Get the region counters for an increment, creating them if necessary. |
||
| 109 | /// |
||
| 110 | /// If the counter array doesn't yet exist, the profile data variables |
||
| 111 | /// referring to them will also be created. |
||
| 112 | GlobalVariable *getOrCreateRegionCounters(InstrProfInstBase *Inc); |
||
| 113 | |||
| 114 | /// Create the region counters. |
||
| 115 | GlobalVariable *createRegionCounters(InstrProfInstBase *Inc, StringRef Name, |
||
| 116 | GlobalValue::LinkageTypes Linkage); |
||
| 117 | |||
| 118 | /// Emit the section with compressed function names. |
||
| 119 | void emitNameData(); |
||
| 120 | |||
| 121 | /// Emit value nodes section for value profiling. |
||
| 122 | void emitVNodes(); |
||
| 123 | |||
| 124 | /// Emit runtime registration functions for each profile data variable. |
||
| 125 | void emitRegistration(); |
||
| 126 | |||
| 127 | /// Emit the necessary plumbing to pull in the runtime initialization. |
||
| 128 | /// Returns true if a change was made. |
||
| 129 | bool emitRuntimeHook(); |
||
| 130 | |||
| 131 | /// Add uses of our data variables and runtime hook. |
||
| 132 | void emitUses(); |
||
| 133 | |||
| 134 | /// Create a static initializer for our data, on platforms that need it, |
||
| 135 | /// and for any profile output file that was specified. |
||
| 136 | void emitInitialization(); |
||
| 137 | }; |
||
| 138 | |||
| 139 | } // end namespace llvm |
||
| 140 | |||
| 141 | #endif // LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H |