10b57cec5SDimitry Andric //===-- InstrProfiling.cpp - Frontend instrumentation based profiling -----===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 9*c9157d92SDimitry Andric // This pass lowers instrprof_* intrinsics emitted by an instrumentor. 100b57cec5SDimitry Andric // It also builds the data structures and initialization code needed for 110b57cec5SDimitry Andric // updating execution counts and emitting the profile at runtime. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "llvm/Transforms/Instrumentation/InstrProfiling.h" 160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 17*c9157d92SDimitry Andric #include "llvm/ADT/STLExtras.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 200b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 210b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h" 220b57cec5SDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h" 230b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 240b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 250b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 260b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 27*c9157d92SDimitry Andric #include "llvm/IR/CFG.h" 280b57cec5SDimitry Andric #include "llvm/IR/Constant.h" 290b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 300eae32dcSDimitry Andric #include "llvm/IR/DIBuilder.h" 310b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 320eae32dcSDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 330b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 340b57cec5SDimitry Andric #include "llvm/IR/Function.h" 350b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 360b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 370b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h" 380b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 390b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 400b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 410b57cec5SDimitry Andric #include "llvm/IR/Module.h" 420b57cec5SDimitry Andric #include "llvm/IR/Type.h" 43480093f4SDimitry Andric #include "llvm/InitializePasses.h" 440b57cec5SDimitry Andric #include "llvm/Pass.h" 450b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 460eae32dcSDimitry Andric #include "llvm/ProfileData/InstrProfCorrelator.h" 470b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 480b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 490b57cec5SDimitry Andric #include "llvm/Support/Error.h" 500b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 51fe013be4SDimitry Andric #include "llvm/TargetParser/Triple.h" 52*c9157d92SDimitry Andric #include "llvm/Transforms/Instrumentation.h" 53*c9157d92SDimitry Andric #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h" 54*c9157d92SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 550b57cec5SDimitry Andric #include "llvm/Transforms/Utils/ModuleUtils.h" 560b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SSAUpdater.h" 570b57cec5SDimitry Andric #include <algorithm> 580b57cec5SDimitry Andric #include <cassert> 590b57cec5SDimitry Andric #include <cstdint> 600b57cec5SDimitry Andric #include <string> 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric using namespace llvm; 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric #define DEBUG_TYPE "instrprof" 650b57cec5SDimitry Andric 660eae32dcSDimitry Andric namespace llvm { 67*c9157d92SDimitry Andric // TODO: Remove -debug-info-correlate in next LLVM release, in favor of 68*c9157d92SDimitry Andric // -profile-correlate=debug-info. 69*c9157d92SDimitry Andric cl::opt<bool> DebugInfoCorrelate( 70*c9157d92SDimitry Andric "debug-info-correlate", 71*c9157d92SDimitry Andric cl::desc("Use debug info to correlate profiles. (Deprecated, use " 72*c9157d92SDimitry Andric "-profile-correlate=debug-info)"), 730eae32dcSDimitry Andric cl::init(false)); 74*c9157d92SDimitry Andric 75*c9157d92SDimitry Andric cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate( 76*c9157d92SDimitry Andric "profile-correlate", 77*c9157d92SDimitry Andric cl::desc("Use debug info or binary file to correlate profiles."), 78*c9157d92SDimitry Andric cl::init(InstrProfCorrelator::NONE), 79*c9157d92SDimitry Andric cl::values(clEnumValN(InstrProfCorrelator::NONE, "", 80*c9157d92SDimitry Andric "No profile correlation"), 81*c9157d92SDimitry Andric clEnumValN(InstrProfCorrelator::DEBUG_INFO, "debug-info", 82*c9157d92SDimitry Andric "Use debug info to correlate"), 83*c9157d92SDimitry Andric clEnumValN(InstrProfCorrelator::BINARY, "binary", 84*c9157d92SDimitry Andric "Use binary to correlate"))); 850eae32dcSDimitry Andric } // namespace llvm 860eae32dcSDimitry Andric 870b57cec5SDimitry Andric namespace { 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric cl::opt<bool> DoHashBasedCounterSplit( 900b57cec5SDimitry Andric "hash-based-counter-split", 910b57cec5SDimitry Andric cl::desc("Rename counter variable of a comdat function based on cfg hash"), 920b57cec5SDimitry Andric cl::init(true)); 930b57cec5SDimitry Andric 944824e7fdSDimitry Andric cl::opt<bool> 954824e7fdSDimitry Andric RuntimeCounterRelocation("runtime-counter-relocation", 965ffd83dbSDimitry Andric cl::desc("Enable relocating counters at runtime."), 975ffd83dbSDimitry Andric cl::init(false)); 985ffd83dbSDimitry Andric 990b57cec5SDimitry Andric cl::opt<bool> ValueProfileStaticAlloc( 1000b57cec5SDimitry Andric "vp-static-alloc", 1010b57cec5SDimitry Andric cl::desc("Do static counter allocation for value profiler"), 1020b57cec5SDimitry Andric cl::init(true)); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric cl::opt<double> NumCountersPerValueSite( 1050b57cec5SDimitry Andric "vp-counters-per-site", 1060b57cec5SDimitry Andric cl::desc("The average number of profile counters allocated " 1070b57cec5SDimitry Andric "per value profiling site."), 1080b57cec5SDimitry Andric // This is set to a very small value because in real programs, only 1090b57cec5SDimitry Andric // a very small percentage of value sites have non-zero targets, e.g, 1/30. 1100b57cec5SDimitry Andric // For those sites with non-zero profile, the average number of targets 1110b57cec5SDimitry Andric // is usually smaller than 2. 1120b57cec5SDimitry Andric cl::init(1.0)); 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric cl::opt<bool> AtomicCounterUpdateAll( 11581ad6265SDimitry Andric "instrprof-atomic-counter-update-all", 1160b57cec5SDimitry Andric cl::desc("Make all profile counter updates atomic (for testing only)"), 1170b57cec5SDimitry Andric cl::init(false)); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric cl::opt<bool> AtomicCounterUpdatePromoted( 12081ad6265SDimitry Andric "atomic-counter-update-promoted", 1210b57cec5SDimitry Andric cl::desc("Do counter update using atomic fetch add " 1220b57cec5SDimitry Andric " for promoted counters only"), 1230b57cec5SDimitry Andric cl::init(false)); 1240b57cec5SDimitry Andric 1255ffd83dbSDimitry Andric cl::opt<bool> AtomicFirstCounter( 12681ad6265SDimitry Andric "atomic-first-counter", 1275ffd83dbSDimitry Andric cl::desc("Use atomic fetch add for first counter in a function (usually " 1285ffd83dbSDimitry Andric "the entry counter)"), 1295ffd83dbSDimitry Andric cl::init(false)); 1305ffd83dbSDimitry Andric 1310b57cec5SDimitry Andric // If the option is not specified, the default behavior about whether 1320b57cec5SDimitry Andric // counter promotion is done depends on how instrumentaiton lowering 1330b57cec5SDimitry Andric // pipeline is setup, i.e., the default value of true of this option 1340b57cec5SDimitry Andric // does not mean the promotion will be done by default. Explicitly 1350b57cec5SDimitry Andric // setting this option can override the default behavior. 13681ad6265SDimitry Andric cl::opt<bool> DoCounterPromotion("do-counter-promotion", 1370b57cec5SDimitry Andric cl::desc("Do counter register promotion"), 1380b57cec5SDimitry Andric cl::init(false)); 1390b57cec5SDimitry Andric cl::opt<unsigned> MaxNumOfPromotionsPerLoop( 14081ad6265SDimitry Andric "max-counter-promotions-per-loop", cl::init(20), 1410b57cec5SDimitry Andric cl::desc("Max number counter promotions per loop to avoid" 1420b57cec5SDimitry Andric " increasing register pressure too much")); 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric // A debug option 1450b57cec5SDimitry Andric cl::opt<int> 14681ad6265SDimitry Andric MaxNumOfPromotions("max-counter-promotions", cl::init(-1), 1470b57cec5SDimitry Andric cl::desc("Max number of allowed counter promotions")); 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric cl::opt<unsigned> SpeculativeCounterPromotionMaxExiting( 15081ad6265SDimitry Andric "speculative-counter-promotion-max-exiting", cl::init(3), 1510b57cec5SDimitry Andric cl::desc("The max number of exiting blocks of a loop to allow " 1520b57cec5SDimitry Andric " speculative counter promotion")); 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric cl::opt<bool> SpeculativeCounterPromotionToLoop( 15581ad6265SDimitry Andric "speculative-counter-promotion-to-loop", 1560b57cec5SDimitry Andric cl::desc("When the option is false, if the target block is in a loop, " 1570b57cec5SDimitry Andric "the promotion will be disallowed unless the promoted counter " 1580b57cec5SDimitry Andric " update can be further/iteratively promoted into an acyclic " 1590b57cec5SDimitry Andric " region.")); 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric cl::opt<bool> IterativeCounterPromotion( 16281ad6265SDimitry Andric "iterative-counter-promotion", cl::init(true), 1630b57cec5SDimitry Andric cl::desc("Allow counter promotion across the whole loop nest.")); 1640b57cec5SDimitry Andric 165e8d8bef9SDimitry Andric cl::opt<bool> SkipRetExitBlock( 16681ad6265SDimitry Andric "skip-ret-exit-block", cl::init(true), 167e8d8bef9SDimitry Andric cl::desc("Suppress counter promotion if exit blocks contain ret.")); 168e8d8bef9SDimitry Andric 169*c9157d92SDimitry Andric using LoadStorePair = std::pair<Instruction *, Instruction *>; 170*c9157d92SDimitry Andric 171*c9157d92SDimitry Andric class InstrLowerer final { 172*c9157d92SDimitry Andric public: 173*c9157d92SDimitry Andric InstrLowerer(Module &M, const InstrProfOptions &Options, 174*c9157d92SDimitry Andric std::function<const TargetLibraryInfo &(Function &F)> GetTLI, 175*c9157d92SDimitry Andric bool IsCS) 176*c9157d92SDimitry Andric : M(M), Options(Options), TT(Triple(M.getTargetTriple())), IsCS(IsCS), 177*c9157d92SDimitry Andric GetTLI(GetTLI) {} 178*c9157d92SDimitry Andric 179*c9157d92SDimitry Andric bool lower(); 180*c9157d92SDimitry Andric 181*c9157d92SDimitry Andric private: 182*c9157d92SDimitry Andric Module &M; 183*c9157d92SDimitry Andric const InstrProfOptions Options; 184*c9157d92SDimitry Andric const Triple TT; 185*c9157d92SDimitry Andric // Is this lowering for the context-sensitive instrumentation. 186*c9157d92SDimitry Andric const bool IsCS; 187*c9157d92SDimitry Andric 188*c9157d92SDimitry Andric std::function<const TargetLibraryInfo &(Function &F)> GetTLI; 189*c9157d92SDimitry Andric struct PerFunctionProfileData { 190*c9157d92SDimitry Andric uint32_t NumValueSites[IPVK_Last + 1] = {}; 191*c9157d92SDimitry Andric GlobalVariable *RegionCounters = nullptr; 192*c9157d92SDimitry Andric GlobalVariable *DataVar = nullptr; 193*c9157d92SDimitry Andric GlobalVariable *RegionBitmaps = nullptr; 194*c9157d92SDimitry Andric uint32_t NumBitmapBytes = 0; 195*c9157d92SDimitry Andric 196*c9157d92SDimitry Andric PerFunctionProfileData() = default; 197*c9157d92SDimitry Andric }; 198*c9157d92SDimitry Andric DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap; 199*c9157d92SDimitry Andric /// If runtime relocation is enabled, this maps functions to the load 200*c9157d92SDimitry Andric /// instruction that produces the profile relocation bias. 201*c9157d92SDimitry Andric DenseMap<const Function *, LoadInst *> FunctionToProfileBiasMap; 202*c9157d92SDimitry Andric std::vector<GlobalValue *> CompilerUsedVars; 203*c9157d92SDimitry Andric std::vector<GlobalValue *> UsedVars; 204*c9157d92SDimitry Andric std::vector<GlobalVariable *> ReferencedNames; 205*c9157d92SDimitry Andric GlobalVariable *NamesVar = nullptr; 206*c9157d92SDimitry Andric size_t NamesSize = 0; 207*c9157d92SDimitry Andric 208*c9157d92SDimitry Andric // vector of counter load/store pairs to be register promoted. 209*c9157d92SDimitry Andric std::vector<LoadStorePair> PromotionCandidates; 210*c9157d92SDimitry Andric 211*c9157d92SDimitry Andric int64_t TotalCountersPromoted = 0; 212*c9157d92SDimitry Andric 213*c9157d92SDimitry Andric /// Lower instrumentation intrinsics in the function. Returns true if there 214*c9157d92SDimitry Andric /// any lowering. 215*c9157d92SDimitry Andric bool lowerIntrinsics(Function *F); 216*c9157d92SDimitry Andric 217*c9157d92SDimitry Andric /// Register-promote counter loads and stores in loops. 218*c9157d92SDimitry Andric void promoteCounterLoadStores(Function *F); 219*c9157d92SDimitry Andric 220*c9157d92SDimitry Andric /// Returns true if relocating counters at runtime is enabled. 221*c9157d92SDimitry Andric bool isRuntimeCounterRelocationEnabled() const; 222*c9157d92SDimitry Andric 223*c9157d92SDimitry Andric /// Returns true if profile counter update register promotion is enabled. 224*c9157d92SDimitry Andric bool isCounterPromotionEnabled() const; 225*c9157d92SDimitry Andric 226*c9157d92SDimitry Andric /// Count the number of instrumented value sites for the function. 227*c9157d92SDimitry Andric void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins); 228*c9157d92SDimitry Andric 229*c9157d92SDimitry Andric /// Replace instrprof.value.profile with a call to runtime library. 230*c9157d92SDimitry Andric void lowerValueProfileInst(InstrProfValueProfileInst *Ins); 231*c9157d92SDimitry Andric 232*c9157d92SDimitry Andric /// Replace instrprof.cover with a store instruction to the coverage byte. 233*c9157d92SDimitry Andric void lowerCover(InstrProfCoverInst *Inc); 234*c9157d92SDimitry Andric 235*c9157d92SDimitry Andric /// Replace instrprof.timestamp with a call to 236*c9157d92SDimitry Andric /// INSTR_PROF_PROFILE_SET_TIMESTAMP. 237*c9157d92SDimitry Andric void lowerTimestamp(InstrProfTimestampInst *TimestampInstruction); 238*c9157d92SDimitry Andric 239*c9157d92SDimitry Andric /// Replace instrprof.increment with an increment of the appropriate value. 240*c9157d92SDimitry Andric void lowerIncrement(InstrProfIncrementInst *Inc); 241*c9157d92SDimitry Andric 242*c9157d92SDimitry Andric /// Force emitting of name vars for unused functions. 243*c9157d92SDimitry Andric void lowerCoverageData(GlobalVariable *CoverageNamesVar); 244*c9157d92SDimitry Andric 245*c9157d92SDimitry Andric /// Replace instrprof.mcdc.tvbitmask.update with a shift and or instruction 246*c9157d92SDimitry Andric /// using the index represented by the a temp value into a bitmap. 247*c9157d92SDimitry Andric void lowerMCDCTestVectorBitmapUpdate(InstrProfMCDCTVBitmapUpdate *Ins); 248*c9157d92SDimitry Andric 249*c9157d92SDimitry Andric /// Replace instrprof.mcdc.temp.update with a shift and or instruction using 250*c9157d92SDimitry Andric /// the corresponding condition ID. 251*c9157d92SDimitry Andric void lowerMCDCCondBitmapUpdate(InstrProfMCDCCondBitmapUpdate *Ins); 252*c9157d92SDimitry Andric 253*c9157d92SDimitry Andric /// Compute the address of the counter value that this profiling instruction 254*c9157d92SDimitry Andric /// acts on. 255*c9157d92SDimitry Andric Value *getCounterAddress(InstrProfCntrInstBase *I); 256*c9157d92SDimitry Andric 257*c9157d92SDimitry Andric /// Get the region counters for an increment, creating them if necessary. 258*c9157d92SDimitry Andric /// 259*c9157d92SDimitry Andric /// If the counter array doesn't yet exist, the profile data variables 260*c9157d92SDimitry Andric /// referring to them will also be created. 261*c9157d92SDimitry Andric GlobalVariable *getOrCreateRegionCounters(InstrProfCntrInstBase *Inc); 262*c9157d92SDimitry Andric 263*c9157d92SDimitry Andric /// Create the region counters. 264*c9157d92SDimitry Andric GlobalVariable *createRegionCounters(InstrProfCntrInstBase *Inc, 265*c9157d92SDimitry Andric StringRef Name, 266*c9157d92SDimitry Andric GlobalValue::LinkageTypes Linkage); 267*c9157d92SDimitry Andric 268*c9157d92SDimitry Andric /// Compute the address of the test vector bitmap that this profiling 269*c9157d92SDimitry Andric /// instruction acts on. 270*c9157d92SDimitry Andric Value *getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I); 271*c9157d92SDimitry Andric 272*c9157d92SDimitry Andric /// Get the region bitmaps for an increment, creating them if necessary. 273*c9157d92SDimitry Andric /// 274*c9157d92SDimitry Andric /// If the bitmap array doesn't yet exist, the profile data variables 275*c9157d92SDimitry Andric /// referring to them will also be created. 276*c9157d92SDimitry Andric GlobalVariable *getOrCreateRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc); 277*c9157d92SDimitry Andric 278*c9157d92SDimitry Andric /// Create the MC/DC bitmap as a byte-aligned array of bytes associated with 279*c9157d92SDimitry Andric /// an MC/DC Decision region. The number of bytes required is indicated by 280*c9157d92SDimitry Andric /// the intrinsic used (type InstrProfMCDCBitmapInstBase). This is called 281*c9157d92SDimitry Andric /// as part of setupProfileSection() and is conceptually very similar to 282*c9157d92SDimitry Andric /// what is done for profile data counters in createRegionCounters(). 283*c9157d92SDimitry Andric GlobalVariable *createRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc, 284*c9157d92SDimitry Andric StringRef Name, 285*c9157d92SDimitry Andric GlobalValue::LinkageTypes Linkage); 286*c9157d92SDimitry Andric 287*c9157d92SDimitry Andric /// Set Comdat property of GV, if required. 288*c9157d92SDimitry Andric void maybeSetComdat(GlobalVariable *GV, Function *Fn, StringRef VarName); 289*c9157d92SDimitry Andric 290*c9157d92SDimitry Andric /// Setup the sections into which counters and bitmaps are allocated. 291*c9157d92SDimitry Andric GlobalVariable *setupProfileSection(InstrProfInstBase *Inc, 292*c9157d92SDimitry Andric InstrProfSectKind IPSK); 293*c9157d92SDimitry Andric 294*c9157d92SDimitry Andric /// Create INSTR_PROF_DATA variable for counters and bitmaps. 295*c9157d92SDimitry Andric void createDataVariable(InstrProfCntrInstBase *Inc); 296*c9157d92SDimitry Andric 297*c9157d92SDimitry Andric /// Emit the section with compressed function names. 298*c9157d92SDimitry Andric void emitNameData(); 299*c9157d92SDimitry Andric 300*c9157d92SDimitry Andric /// Emit value nodes section for value profiling. 301*c9157d92SDimitry Andric void emitVNodes(); 302*c9157d92SDimitry Andric 303*c9157d92SDimitry Andric /// Emit runtime registration functions for each profile data variable. 304*c9157d92SDimitry Andric void emitRegistration(); 305*c9157d92SDimitry Andric 306*c9157d92SDimitry Andric /// Emit the necessary plumbing to pull in the runtime initialization. 307*c9157d92SDimitry Andric /// Returns true if a change was made. 308*c9157d92SDimitry Andric bool emitRuntimeHook(); 309*c9157d92SDimitry Andric 310*c9157d92SDimitry Andric /// Add uses of our data variables and runtime hook. 311*c9157d92SDimitry Andric void emitUses(); 312*c9157d92SDimitry Andric 313*c9157d92SDimitry Andric /// Create a static initializer for our data, on platforms that need it, 314*c9157d92SDimitry Andric /// and for any profile output file that was specified. 315*c9157d92SDimitry Andric void emitInitialization(); 316*c9157d92SDimitry Andric }; 317*c9157d92SDimitry Andric 3180b57cec5SDimitry Andric /// 3190b57cec5SDimitry Andric /// A helper class to promote one counter RMW operation in the loop 3200b57cec5SDimitry Andric /// into register update. 3210b57cec5SDimitry Andric /// 3220b57cec5SDimitry Andric /// RWM update for the counter will be sinked out of the loop after 3230b57cec5SDimitry Andric /// the transformation. 3240b57cec5SDimitry Andric /// 3250b57cec5SDimitry Andric class PGOCounterPromoterHelper : public LoadAndStorePromoter { 3260b57cec5SDimitry Andric public: 3270b57cec5SDimitry Andric PGOCounterPromoterHelper( 3280b57cec5SDimitry Andric Instruction *L, Instruction *S, SSAUpdater &SSA, Value *Init, 3290b57cec5SDimitry Andric BasicBlock *PH, ArrayRef<BasicBlock *> ExitBlocks, 3300b57cec5SDimitry Andric ArrayRef<Instruction *> InsertPts, 3310b57cec5SDimitry Andric DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCands, 3320b57cec5SDimitry Andric LoopInfo &LI) 3330b57cec5SDimitry Andric : LoadAndStorePromoter({L, S}, SSA), Store(S), ExitBlocks(ExitBlocks), 3340b57cec5SDimitry Andric InsertPts(InsertPts), LoopToCandidates(LoopToCands), LI(LI) { 3350b57cec5SDimitry Andric assert(isa<LoadInst>(L)); 3360b57cec5SDimitry Andric assert(isa<StoreInst>(S)); 3370b57cec5SDimitry Andric SSA.AddAvailableValue(PH, Init); 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric void doExtraRewritesBeforeFinalDeletion() override { 3410b57cec5SDimitry Andric for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { 3420b57cec5SDimitry Andric BasicBlock *ExitBlock = ExitBlocks[i]; 3430b57cec5SDimitry Andric Instruction *InsertPos = InsertPts[i]; 3440b57cec5SDimitry Andric // Get LiveIn value into the ExitBlock. If there are multiple 3450b57cec5SDimitry Andric // predecessors, the value is defined by a PHI node in this 3460b57cec5SDimitry Andric // block. 3470b57cec5SDimitry Andric Value *LiveInValue = SSA.GetValueInMiddleOfBlock(ExitBlock); 3480b57cec5SDimitry Andric Value *Addr = cast<StoreInst>(Store)->getPointerOperand(); 3490b57cec5SDimitry Andric Type *Ty = LiveInValue->getType(); 3500b57cec5SDimitry Andric IRBuilder<> Builder(InsertPos); 35181ad6265SDimitry Andric if (auto *AddrInst = dyn_cast_or_null<IntToPtrInst>(Addr)) { 35281ad6265SDimitry Andric // If isRuntimeCounterRelocationEnabled() is true then the address of 35381ad6265SDimitry Andric // the store instruction is computed with two instructions in 35481ad6265SDimitry Andric // InstrProfiling::getCounterAddress(). We need to copy those 35581ad6265SDimitry Andric // instructions to this block to compute Addr correctly. 35681ad6265SDimitry Andric // %BiasAdd = add i64 ptrtoint <__profc_>, <__llvm_profile_counter_bias> 35781ad6265SDimitry Andric // %Addr = inttoptr i64 %BiasAdd to i64* 35881ad6265SDimitry Andric auto *OrigBiasInst = dyn_cast<BinaryOperator>(AddrInst->getOperand(0)); 35981ad6265SDimitry Andric assert(OrigBiasInst->getOpcode() == Instruction::BinaryOps::Add); 36081ad6265SDimitry Andric Value *BiasInst = Builder.Insert(OrigBiasInst->clone()); 361*c9157d92SDimitry Andric Addr = Builder.CreateIntToPtr(BiasInst, 362*c9157d92SDimitry Andric PointerType::getUnqual(Ty->getContext())); 36381ad6265SDimitry Andric } 3640b57cec5SDimitry Andric if (AtomicCounterUpdatePromoted) 3650b57cec5SDimitry Andric // automic update currently can only be promoted across the current 3660b57cec5SDimitry Andric // loop, not the whole loop nest. 3670b57cec5SDimitry Andric Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, LiveInValue, 368fe6060f1SDimitry Andric MaybeAlign(), 3690b57cec5SDimitry Andric AtomicOrdering::SequentiallyConsistent); 3700b57cec5SDimitry Andric else { 3710b57cec5SDimitry Andric LoadInst *OldVal = Builder.CreateLoad(Ty, Addr, "pgocount.promoted"); 3720b57cec5SDimitry Andric auto *NewVal = Builder.CreateAdd(OldVal, LiveInValue); 3730b57cec5SDimitry Andric auto *NewStore = Builder.CreateStore(NewVal, Addr); 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric // Now update the parent loop's candidate list: 3760b57cec5SDimitry Andric if (IterativeCounterPromotion) { 3770b57cec5SDimitry Andric auto *TargetLoop = LI.getLoopFor(ExitBlock); 3780b57cec5SDimitry Andric if (TargetLoop) 3790b57cec5SDimitry Andric LoopToCandidates[TargetLoop].emplace_back(OldVal, NewStore); 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric private: 3860b57cec5SDimitry Andric Instruction *Store; 3870b57cec5SDimitry Andric ArrayRef<BasicBlock *> ExitBlocks; 3880b57cec5SDimitry Andric ArrayRef<Instruction *> InsertPts; 3890b57cec5SDimitry Andric DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCandidates; 3900b57cec5SDimitry Andric LoopInfo &LI; 3910b57cec5SDimitry Andric }; 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric /// A helper class to do register promotion for all profile counter 3940b57cec5SDimitry Andric /// updates in a loop. 3950b57cec5SDimitry Andric /// 3960b57cec5SDimitry Andric class PGOCounterPromoter { 3970b57cec5SDimitry Andric public: 3980b57cec5SDimitry Andric PGOCounterPromoter( 3990b57cec5SDimitry Andric DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCands, 4000b57cec5SDimitry Andric Loop &CurLoop, LoopInfo &LI, BlockFrequencyInfo *BFI) 40104eeddc0SDimitry Andric : LoopToCandidates(LoopToCands), L(CurLoop), LI(LI), BFI(BFI) { 4020b57cec5SDimitry Andric 4035ffd83dbSDimitry Andric // Skip collection of ExitBlocks and InsertPts for loops that will not be 4045ffd83dbSDimitry Andric // able to have counters promoted. 4050b57cec5SDimitry Andric SmallVector<BasicBlock *, 8> LoopExitBlocks; 4060b57cec5SDimitry Andric SmallPtrSet<BasicBlock *, 8> BlockSet; 4075ffd83dbSDimitry Andric 4080b57cec5SDimitry Andric L.getExitBlocks(LoopExitBlocks); 4095ffd83dbSDimitry Andric if (!isPromotionPossible(&L, LoopExitBlocks)) 4105ffd83dbSDimitry Andric return; 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric for (BasicBlock *ExitBlock : LoopExitBlocks) { 413*c9157d92SDimitry Andric if (BlockSet.insert(ExitBlock).second && 414*c9157d92SDimitry Andric llvm::none_of(predecessors(ExitBlock), [&](const BasicBlock *Pred) { 415*c9157d92SDimitry Andric return llvm::isPresplitCoroSuspendExitEdge(*Pred, *ExitBlock); 416*c9157d92SDimitry Andric })) { 4170b57cec5SDimitry Andric ExitBlocks.push_back(ExitBlock); 4180b57cec5SDimitry Andric InsertPts.push_back(&*ExitBlock->getFirstInsertionPt()); 4190b57cec5SDimitry Andric } 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric bool run(int64_t *NumPromoted) { 4240b57cec5SDimitry Andric // Skip 'infinite' loops: 4250b57cec5SDimitry Andric if (ExitBlocks.size() == 0) 4260b57cec5SDimitry Andric return false; 427e8d8bef9SDimitry Andric 428e8d8bef9SDimitry Andric // Skip if any of the ExitBlocks contains a ret instruction. 429e8d8bef9SDimitry Andric // This is to prevent dumping of incomplete profile -- if the 430e8d8bef9SDimitry Andric // the loop is a long running loop and dump is called in the middle 431e8d8bef9SDimitry Andric // of the loop, the result profile is incomplete. 432e8d8bef9SDimitry Andric // FIXME: add other heuristics to detect long running loops. 433e8d8bef9SDimitry Andric if (SkipRetExitBlock) { 434bdd1243dSDimitry Andric for (auto *BB : ExitBlocks) 435e8d8bef9SDimitry Andric if (isa<ReturnInst>(BB->getTerminator())) 436e8d8bef9SDimitry Andric return false; 437e8d8bef9SDimitry Andric } 438e8d8bef9SDimitry Andric 4390b57cec5SDimitry Andric unsigned MaxProm = getMaxNumOfPromotionsInLoop(&L); 4400b57cec5SDimitry Andric if (MaxProm == 0) 4410b57cec5SDimitry Andric return false; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric unsigned Promoted = 0; 4440b57cec5SDimitry Andric for (auto &Cand : LoopToCandidates[&L]) { 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric SmallVector<PHINode *, 4> NewPHIs; 4470b57cec5SDimitry Andric SSAUpdater SSA(&NewPHIs); 4480b57cec5SDimitry Andric Value *InitVal = ConstantInt::get(Cand.first->getType(), 0); 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric // If BFI is set, we will use it to guide the promotions. 4510b57cec5SDimitry Andric if (BFI) { 4520b57cec5SDimitry Andric auto *BB = Cand.first->getParent(); 4530b57cec5SDimitry Andric auto InstrCount = BFI->getBlockProfileCount(BB); 4540b57cec5SDimitry Andric if (!InstrCount) 4550b57cec5SDimitry Andric continue; 4560b57cec5SDimitry Andric auto PreheaderCount = BFI->getBlockProfileCount(L.getLoopPreheader()); 4570b57cec5SDimitry Andric // If the average loop trip count is not greater than 1.5, we skip 4580b57cec5SDimitry Andric // promotion. 45981ad6265SDimitry Andric if (PreheaderCount && (*PreheaderCount * 3) >= (*InstrCount * 2)) 4600b57cec5SDimitry Andric continue; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric PGOCounterPromoterHelper Promoter(Cand.first, Cand.second, SSA, InitVal, 4640b57cec5SDimitry Andric L.getLoopPreheader(), ExitBlocks, 4650b57cec5SDimitry Andric InsertPts, LoopToCandidates, LI); 4660b57cec5SDimitry Andric Promoter.run(SmallVector<Instruction *, 2>({Cand.first, Cand.second})); 4670b57cec5SDimitry Andric Promoted++; 4680b57cec5SDimitry Andric if (Promoted >= MaxProm) 4690b57cec5SDimitry Andric break; 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric (*NumPromoted)++; 4720b57cec5SDimitry Andric if (MaxNumOfPromotions != -1 && *NumPromoted >= MaxNumOfPromotions) 4730b57cec5SDimitry Andric break; 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << Promoted << " counters promoted for loop (depth=" 4770b57cec5SDimitry Andric << L.getLoopDepth() << ")\n"); 4780b57cec5SDimitry Andric return Promoted != 0; 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric private: 4820b57cec5SDimitry Andric bool allowSpeculativeCounterPromotion(Loop *LP) { 4830b57cec5SDimitry Andric SmallVector<BasicBlock *, 8> ExitingBlocks; 4840b57cec5SDimitry Andric L.getExitingBlocks(ExitingBlocks); 4850b57cec5SDimitry Andric // Not considierered speculative. 4860b57cec5SDimitry Andric if (ExitingBlocks.size() == 1) 4870b57cec5SDimitry Andric return true; 4880b57cec5SDimitry Andric if (ExitingBlocks.size() > SpeculativeCounterPromotionMaxExiting) 4890b57cec5SDimitry Andric return false; 4900b57cec5SDimitry Andric return true; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric 4935ffd83dbSDimitry Andric // Check whether the loop satisfies the basic conditions needed to perform 4945ffd83dbSDimitry Andric // Counter Promotions. 4954824e7fdSDimitry Andric bool 4964824e7fdSDimitry Andric isPromotionPossible(Loop *LP, 4975ffd83dbSDimitry Andric const SmallVectorImpl<BasicBlock *> &LoopExitBlocks) { 4980b57cec5SDimitry Andric // We can't insert into a catchswitch. 4990b57cec5SDimitry Andric if (llvm::any_of(LoopExitBlocks, [](BasicBlock *Exit) { 5000b57cec5SDimitry Andric return isa<CatchSwitchInst>(Exit->getTerminator()); 5010b57cec5SDimitry Andric })) 5025ffd83dbSDimitry Andric return false; 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric if (!LP->hasDedicatedExits()) 5055ffd83dbSDimitry Andric return false; 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric BasicBlock *PH = LP->getLoopPreheader(); 5080b57cec5SDimitry Andric if (!PH) 5095ffd83dbSDimitry Andric return false; 5105ffd83dbSDimitry Andric 5115ffd83dbSDimitry Andric return true; 5125ffd83dbSDimitry Andric } 5135ffd83dbSDimitry Andric 5145ffd83dbSDimitry Andric // Returns the max number of Counter Promotions for LP. 5155ffd83dbSDimitry Andric unsigned getMaxNumOfPromotionsInLoop(Loop *LP) { 5165ffd83dbSDimitry Andric SmallVector<BasicBlock *, 8> LoopExitBlocks; 5175ffd83dbSDimitry Andric LP->getExitBlocks(LoopExitBlocks); 5185ffd83dbSDimitry Andric if (!isPromotionPossible(LP, LoopExitBlocks)) 5190b57cec5SDimitry Andric return 0; 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric SmallVector<BasicBlock *, 8> ExitingBlocks; 5220b57cec5SDimitry Andric LP->getExitingBlocks(ExitingBlocks); 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric // If BFI is set, we do more aggressive promotions based on BFI. 5250b57cec5SDimitry Andric if (BFI) 5260b57cec5SDimitry Andric return (unsigned)-1; 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric // Not considierered speculative. 5290b57cec5SDimitry Andric if (ExitingBlocks.size() == 1) 5300b57cec5SDimitry Andric return MaxNumOfPromotionsPerLoop; 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric if (ExitingBlocks.size() > SpeculativeCounterPromotionMaxExiting) 5330b57cec5SDimitry Andric return 0; 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric // Whether the target block is in a loop does not matter: 5360b57cec5SDimitry Andric if (SpeculativeCounterPromotionToLoop) 5370b57cec5SDimitry Andric return MaxNumOfPromotionsPerLoop; 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric // Now check the target block: 5400b57cec5SDimitry Andric unsigned MaxProm = MaxNumOfPromotionsPerLoop; 5410b57cec5SDimitry Andric for (auto *TargetBlock : LoopExitBlocks) { 5420b57cec5SDimitry Andric auto *TargetLoop = LI.getLoopFor(TargetBlock); 5430b57cec5SDimitry Andric if (!TargetLoop) 5440b57cec5SDimitry Andric continue; 5450b57cec5SDimitry Andric unsigned MaxPromForTarget = getMaxNumOfPromotionsInLoop(TargetLoop); 5460b57cec5SDimitry Andric unsigned PendingCandsInTarget = LoopToCandidates[TargetLoop].size(); 5470b57cec5SDimitry Andric MaxProm = 5480b57cec5SDimitry Andric std::min(MaxProm, std::max(MaxPromForTarget, PendingCandsInTarget) - 5490b57cec5SDimitry Andric PendingCandsInTarget); 5500b57cec5SDimitry Andric } 5510b57cec5SDimitry Andric return MaxProm; 5520b57cec5SDimitry Andric } 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCandidates; 5550b57cec5SDimitry Andric SmallVector<BasicBlock *, 8> ExitBlocks; 5560b57cec5SDimitry Andric SmallVector<Instruction *, 8> InsertPts; 5570b57cec5SDimitry Andric Loop &L; 5580b57cec5SDimitry Andric LoopInfo &LI; 5590b57cec5SDimitry Andric BlockFrequencyInfo *BFI; 5600b57cec5SDimitry Andric }; 5610b57cec5SDimitry Andric 562e8d8bef9SDimitry Andric enum class ValueProfilingCallType { 563e8d8bef9SDimitry Andric // Individual values are tracked. Currently used for indiret call target 564e8d8bef9SDimitry Andric // profiling. 565e8d8bef9SDimitry Andric Default, 566e8d8bef9SDimitry Andric 567e8d8bef9SDimitry Andric // MemOp: the memop size value profiling. 568e8d8bef9SDimitry Andric MemOp 569e8d8bef9SDimitry Andric }; 570e8d8bef9SDimitry Andric 5710b57cec5SDimitry Andric } // end anonymous namespace 5720b57cec5SDimitry Andric 573*c9157d92SDimitry Andric PreservedAnalyses InstrProfilingLoweringPass::run(Module &M, 574*c9157d92SDimitry Andric ModuleAnalysisManager &AM) { 5758bcb0991SDimitry Andric FunctionAnalysisManager &FAM = 5768bcb0991SDimitry Andric AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 5778bcb0991SDimitry Andric auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { 5788bcb0991SDimitry Andric return FAM.getResult<TargetLibraryAnalysis>(F); 5798bcb0991SDimitry Andric }; 580*c9157d92SDimitry Andric InstrLowerer Lowerer(M, Options, GetTLI, IsCS); 581*c9157d92SDimitry Andric if (!Lowerer.lower()) 5820b57cec5SDimitry Andric return PreservedAnalyses::all(); 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric return PreservedAnalyses::none(); 5850b57cec5SDimitry Andric } 5860b57cec5SDimitry Andric 587*c9157d92SDimitry Andric bool InstrLowerer::lowerIntrinsics(Function *F) { 5880b57cec5SDimitry Andric bool MadeChange = false; 5890b57cec5SDimitry Andric PromotionCandidates.clear(); 5900b57cec5SDimitry Andric for (BasicBlock &BB : *F) { 591349cc55cSDimitry Andric for (Instruction &Instr : llvm::make_early_inc_range(BB)) { 59204eeddc0SDimitry Andric if (auto *IPIS = dyn_cast<InstrProfIncrementInstStep>(&Instr)) { 59304eeddc0SDimitry Andric lowerIncrement(IPIS); 5940b57cec5SDimitry Andric MadeChange = true; 59504eeddc0SDimitry Andric } else if (auto *IPI = dyn_cast<InstrProfIncrementInst>(&Instr)) { 59604eeddc0SDimitry Andric lowerIncrement(IPI); 59704eeddc0SDimitry Andric MadeChange = true; 598fe013be4SDimitry Andric } else if (auto *IPC = dyn_cast<InstrProfTimestampInst>(&Instr)) { 599fe013be4SDimitry Andric lowerTimestamp(IPC); 600fe013be4SDimitry Andric MadeChange = true; 6011fd87a68SDimitry Andric } else if (auto *IPC = dyn_cast<InstrProfCoverInst>(&Instr)) { 6021fd87a68SDimitry Andric lowerCover(IPC); 6031fd87a68SDimitry Andric MadeChange = true; 60404eeddc0SDimitry Andric } else if (auto *IPVP = dyn_cast<InstrProfValueProfileInst>(&Instr)) { 60504eeddc0SDimitry Andric lowerValueProfileInst(IPVP); 6060b57cec5SDimitry Andric MadeChange = true; 607*c9157d92SDimitry Andric } else if (auto *IPMP = dyn_cast<InstrProfMCDCBitmapParameters>(&Instr)) { 608*c9157d92SDimitry Andric IPMP->eraseFromParent(); 609*c9157d92SDimitry Andric MadeChange = true; 610*c9157d92SDimitry Andric } else if (auto *IPBU = dyn_cast<InstrProfMCDCTVBitmapUpdate>(&Instr)) { 611*c9157d92SDimitry Andric lowerMCDCTestVectorBitmapUpdate(IPBU); 612*c9157d92SDimitry Andric MadeChange = true; 613*c9157d92SDimitry Andric } else if (auto *IPTU = dyn_cast<InstrProfMCDCCondBitmapUpdate>(&Instr)) { 614*c9157d92SDimitry Andric lowerMCDCCondBitmapUpdate(IPTU); 615*c9157d92SDimitry Andric MadeChange = true; 6160b57cec5SDimitry Andric } 6170b57cec5SDimitry Andric } 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric if (!MadeChange) 6210b57cec5SDimitry Andric return false; 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric promoteCounterLoadStores(F); 6240b57cec5SDimitry Andric return true; 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 627*c9157d92SDimitry Andric bool InstrLowerer::isRuntimeCounterRelocationEnabled() const { 628fe6060f1SDimitry Andric // Mach-O don't support weak external references. 629fe6060f1SDimitry Andric if (TT.isOSBinFormatMachO()) 630fe6060f1SDimitry Andric return false; 631fe6060f1SDimitry Andric 6325ffd83dbSDimitry Andric if (RuntimeCounterRelocation.getNumOccurrences() > 0) 6335ffd83dbSDimitry Andric return RuntimeCounterRelocation; 6345ffd83dbSDimitry Andric 635fe6060f1SDimitry Andric // Fuchsia uses runtime counter relocation by default. 6365ffd83dbSDimitry Andric return TT.isOSFuchsia(); 6375ffd83dbSDimitry Andric } 6385ffd83dbSDimitry Andric 639*c9157d92SDimitry Andric bool InstrLowerer::isCounterPromotionEnabled() const { 6400b57cec5SDimitry Andric if (DoCounterPromotion.getNumOccurrences() > 0) 6410b57cec5SDimitry Andric return DoCounterPromotion; 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric return Options.DoCounterPromotion; 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric 646*c9157d92SDimitry Andric void InstrLowerer::promoteCounterLoadStores(Function *F) { 6470b57cec5SDimitry Andric if (!isCounterPromotionEnabled()) 6480b57cec5SDimitry Andric return; 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric DominatorTree DT(*F); 6510b57cec5SDimitry Andric LoopInfo LI(DT); 6520b57cec5SDimitry Andric DenseMap<Loop *, SmallVector<LoadStorePair, 8>> LoopPromotionCandidates; 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric std::unique_ptr<BlockFrequencyInfo> BFI; 6550b57cec5SDimitry Andric if (Options.UseBFIInPromotion) { 6560b57cec5SDimitry Andric std::unique_ptr<BranchProbabilityInfo> BPI; 6578bcb0991SDimitry Andric BPI.reset(new BranchProbabilityInfo(*F, LI, &GetTLI(*F))); 6580b57cec5SDimitry Andric BFI.reset(new BlockFrequencyInfo(*F, *BPI, LI)); 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric for (const auto &LoadStore : PromotionCandidates) { 6620b57cec5SDimitry Andric auto *CounterLoad = LoadStore.first; 6630b57cec5SDimitry Andric auto *CounterStore = LoadStore.second; 6640b57cec5SDimitry Andric BasicBlock *BB = CounterLoad->getParent(); 6650b57cec5SDimitry Andric Loop *ParentLoop = LI.getLoopFor(BB); 6660b57cec5SDimitry Andric if (!ParentLoop) 6670b57cec5SDimitry Andric continue; 6680b57cec5SDimitry Andric LoopPromotionCandidates[ParentLoop].emplace_back(CounterLoad, CounterStore); 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric SmallVector<Loop *, 4> Loops = LI.getLoopsInPreorder(); 6720b57cec5SDimitry Andric 6730b57cec5SDimitry Andric // Do a post-order traversal of the loops so that counter updates can be 6740b57cec5SDimitry Andric // iteratively hoisted outside the loop nest. 6750b57cec5SDimitry Andric for (auto *Loop : llvm::reverse(Loops)) { 6760b57cec5SDimitry Andric PGOCounterPromoter Promoter(LoopPromotionCandidates, *Loop, LI, BFI.get()); 6770b57cec5SDimitry Andric Promoter.run(&TotalCountersPromoted); 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric } 6800b57cec5SDimitry Andric 681349cc55cSDimitry Andric static bool needsRuntimeHookUnconditionally(const Triple &TT) { 682349cc55cSDimitry Andric // On Fuchsia, we only need runtime hook if any counters are present. 683349cc55cSDimitry Andric if (TT.isOSFuchsia()) 684349cc55cSDimitry Andric return false; 685349cc55cSDimitry Andric 686349cc55cSDimitry Andric return true; 687349cc55cSDimitry Andric } 688349cc55cSDimitry Andric 6890b57cec5SDimitry Andric /// Check if the module contains uses of any profiling intrinsics. 6900b57cec5SDimitry Andric static bool containsProfilingIntrinsics(Module &M) { 69104eeddc0SDimitry Andric auto containsIntrinsic = [&](int ID) { 69204eeddc0SDimitry Andric if (auto *F = M.getFunction(Intrinsic::getName(ID))) 69304eeddc0SDimitry Andric return !F->use_empty(); 6940b57cec5SDimitry Andric return false; 69504eeddc0SDimitry Andric }; 6961fd87a68SDimitry Andric return containsIntrinsic(llvm::Intrinsic::instrprof_cover) || 6971fd87a68SDimitry Andric containsIntrinsic(llvm::Intrinsic::instrprof_increment) || 69804eeddc0SDimitry Andric containsIntrinsic(llvm::Intrinsic::instrprof_increment_step) || 699fe013be4SDimitry Andric containsIntrinsic(llvm::Intrinsic::instrprof_timestamp) || 70004eeddc0SDimitry Andric containsIntrinsic(llvm::Intrinsic::instrprof_value_profile); 7010b57cec5SDimitry Andric } 7020b57cec5SDimitry Andric 703*c9157d92SDimitry Andric bool InstrLowerer::lower() { 704349cc55cSDimitry Andric bool MadeChange = false; 705bdd1243dSDimitry Andric bool NeedsRuntimeHook = needsRuntimeHookUnconditionally(TT); 706bdd1243dSDimitry Andric if (NeedsRuntimeHook) 707349cc55cSDimitry Andric MadeChange = emitRuntimeHook(); 7080b57cec5SDimitry Andric 709bdd1243dSDimitry Andric bool ContainsProfiling = containsProfilingIntrinsics(M); 7100b57cec5SDimitry Andric GlobalVariable *CoverageNamesVar = 7110b57cec5SDimitry Andric M.getNamedGlobal(getCoverageUnusedNamesVarName()); 712bdd1243dSDimitry Andric // Improve compile time by avoiding linear scans when there is no work. 713bdd1243dSDimitry Andric if (!ContainsProfiling && !CoverageNamesVar) 7140b57cec5SDimitry Andric return MadeChange; 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric // We did not know how many value sites there would be inside 7170b57cec5SDimitry Andric // the instrumented function. This is counting the number of instrumented 7180b57cec5SDimitry Andric // target value sites to enter it as field in the profile data variable. 7190b57cec5SDimitry Andric for (Function &F : M) { 720*c9157d92SDimitry Andric InstrProfCntrInstBase *FirstProfInst = nullptr; 721*c9157d92SDimitry Andric for (BasicBlock &BB : F) { 722*c9157d92SDimitry Andric for (auto I = BB.begin(), E = BB.end(); I != E; I++) { 7230b57cec5SDimitry Andric if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(I)) 7240b57cec5SDimitry Andric computeNumValueSiteCounts(Ind); 725*c9157d92SDimitry Andric else { 726*c9157d92SDimitry Andric if (FirstProfInst == nullptr && 727fe013be4SDimitry Andric (isa<InstrProfIncrementInst>(I) || isa<InstrProfCoverInst>(I))) 728*c9157d92SDimitry Andric FirstProfInst = dyn_cast<InstrProfCntrInstBase>(I); 729*c9157d92SDimitry Andric // If the MCDCBitmapParameters intrinsic seen, create the bitmaps. 730*c9157d92SDimitry Andric if (const auto &Params = dyn_cast<InstrProfMCDCBitmapParameters>(I)) 731*c9157d92SDimitry Andric static_cast<void>(getOrCreateRegionBitmaps(Params)); 732*c9157d92SDimitry Andric } 733*c9157d92SDimitry Andric } 734*c9157d92SDimitry Andric } 7350b57cec5SDimitry Andric 736*c9157d92SDimitry Andric // Use a profile intrinsic to create the region counters and data variable. 737*c9157d92SDimitry Andric // Also create the data variable based on the MCDCParams. 738*c9157d92SDimitry Andric if (FirstProfInst != nullptr) { 739fe013be4SDimitry Andric static_cast<void>(getOrCreateRegionCounters(FirstProfInst)); 7400b57cec5SDimitry Andric } 741*c9157d92SDimitry Andric } 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric for (Function &F : M) 7440b57cec5SDimitry Andric MadeChange |= lowerIntrinsics(&F); 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric if (CoverageNamesVar) { 7470b57cec5SDimitry Andric lowerCoverageData(CoverageNamesVar); 7480b57cec5SDimitry Andric MadeChange = true; 7490b57cec5SDimitry Andric } 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric if (!MadeChange) 7520b57cec5SDimitry Andric return false; 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric emitVNodes(); 7550b57cec5SDimitry Andric emitNameData(); 756bdd1243dSDimitry Andric 757bdd1243dSDimitry Andric // Emit runtime hook for the cases where the target does not unconditionally 758bdd1243dSDimitry Andric // require pulling in profile runtime, and coverage is enabled on code that is 759bdd1243dSDimitry Andric // not eliminated by the front-end, e.g. unused functions with internal 760bdd1243dSDimitry Andric // linkage. 761bdd1243dSDimitry Andric if (!NeedsRuntimeHook && ContainsProfiling) 762349cc55cSDimitry Andric emitRuntimeHook(); 763bdd1243dSDimitry Andric 7640b57cec5SDimitry Andric emitRegistration(); 7650b57cec5SDimitry Andric emitUses(); 7660b57cec5SDimitry Andric emitInitialization(); 7670b57cec5SDimitry Andric return true; 7680b57cec5SDimitry Andric } 7690b57cec5SDimitry Andric 770e8d8bef9SDimitry Andric static FunctionCallee getOrInsertValueProfilingCall( 771e8d8bef9SDimitry Andric Module &M, const TargetLibraryInfo &TLI, 772e8d8bef9SDimitry Andric ValueProfilingCallType CallType = ValueProfilingCallType::Default) { 7730b57cec5SDimitry Andric LLVMContext &Ctx = M.getContext(); 7740b57cec5SDimitry Andric auto *ReturnTy = Type::getVoidTy(M.getContext()); 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric AttributeList AL; 7770b57cec5SDimitry Andric if (auto AK = TLI.getExtAttrForI32Param(false)) 7780b57cec5SDimitry Andric AL = AL.addParamAttribute(M.getContext(), 2, AK); 7790b57cec5SDimitry Andric 780e8d8bef9SDimitry Andric assert((CallType == ValueProfilingCallType::Default || 781e8d8bef9SDimitry Andric CallType == ValueProfilingCallType::MemOp) && 782e8d8bef9SDimitry Andric "Must be Default or MemOp"); 7830b57cec5SDimitry Andric Type *ParamTypes[] = { 7840b57cec5SDimitry Andric #define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType 7850b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProfData.inc" 7860b57cec5SDimitry Andric }; 7870b57cec5SDimitry Andric auto *ValueProfilingCallTy = 788bdd1243dSDimitry Andric FunctionType::get(ReturnTy, ArrayRef(ParamTypes), false); 789e8d8bef9SDimitry Andric StringRef FuncName = CallType == ValueProfilingCallType::Default 790e8d8bef9SDimitry Andric ? getInstrProfValueProfFuncName() 791e8d8bef9SDimitry Andric : getInstrProfValueProfMemOpFuncName(); 792e8d8bef9SDimitry Andric return M.getOrInsertFunction(FuncName, ValueProfilingCallTy, AL); 7930b57cec5SDimitry Andric } 7940b57cec5SDimitry Andric 795*c9157d92SDimitry Andric void InstrLowerer::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) { 7960b57cec5SDimitry Andric GlobalVariable *Name = Ind->getName(); 7970b57cec5SDimitry Andric uint64_t ValueKind = Ind->getValueKind()->getZExtValue(); 7980b57cec5SDimitry Andric uint64_t Index = Ind->getIndex()->getZExtValue(); 7994824e7fdSDimitry Andric auto &PD = ProfileDataMap[Name]; 8004824e7fdSDimitry Andric PD.NumValueSites[ValueKind] = 8014824e7fdSDimitry Andric std::max(PD.NumValueSites[ValueKind], (uint32_t)(Index + 1)); 8020b57cec5SDimitry Andric } 8030b57cec5SDimitry Andric 804*c9157d92SDimitry Andric void InstrLowerer::lowerValueProfileInst(InstrProfValueProfileInst *Ind) { 8050eae32dcSDimitry Andric // TODO: Value profiling heavily depends on the data section which is omitted 8060eae32dcSDimitry Andric // in lightweight mode. We need to move the value profile pointer to the 8070eae32dcSDimitry Andric // Counter struct to get this working. 8080eae32dcSDimitry Andric assert( 809*c9157d92SDimitry Andric !DebugInfoCorrelate && ProfileCorrelate == InstrProfCorrelator::NONE && 8100eae32dcSDimitry Andric "Value profiling is not yet supported with lightweight instrumentation"); 8110b57cec5SDimitry Andric GlobalVariable *Name = Ind->getName(); 8120b57cec5SDimitry Andric auto It = ProfileDataMap.find(Name); 8130b57cec5SDimitry Andric assert(It != ProfileDataMap.end() && It->second.DataVar && 8140b57cec5SDimitry Andric "value profiling detected in function with no counter incerement"); 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric GlobalVariable *DataVar = It->second.DataVar; 8170b57cec5SDimitry Andric uint64_t ValueKind = Ind->getValueKind()->getZExtValue(); 8180b57cec5SDimitry Andric uint64_t Index = Ind->getIndex()->getZExtValue(); 8190b57cec5SDimitry Andric for (uint32_t Kind = IPVK_First; Kind < ValueKind; ++Kind) 8200b57cec5SDimitry Andric Index += It->second.NumValueSites[Kind]; 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric IRBuilder<> Builder(Ind); 823e8d8bef9SDimitry Andric bool IsMemOpSize = (Ind->getValueKind()->getZExtValue() == 8240b57cec5SDimitry Andric llvm::InstrProfValueKind::IPVK_MemOPSize); 8250b57cec5SDimitry Andric CallInst *Call = nullptr; 8268bcb0991SDimitry Andric auto *TLI = &GetTLI(*Ind->getFunction()); 8275ffd83dbSDimitry Andric 8285ffd83dbSDimitry Andric // To support value profiling calls within Windows exception handlers, funclet 8295ffd83dbSDimitry Andric // information contained within operand bundles needs to be copied over to 8305ffd83dbSDimitry Andric // the library call. This is required for the IR to be processed by the 8315ffd83dbSDimitry Andric // WinEHPrepare pass. 8325ffd83dbSDimitry Andric SmallVector<OperandBundleDef, 1> OpBundles; 8335ffd83dbSDimitry Andric Ind->getOperandBundlesAsDefs(OpBundles); 834e8d8bef9SDimitry Andric if (!IsMemOpSize) { 835*c9157d92SDimitry Andric Value *Args[3] = {Ind->getTargetValue(), DataVar, Builder.getInt32(Index)}; 836*c9157d92SDimitry Andric Call = Builder.CreateCall(getOrInsertValueProfilingCall(M, *TLI), Args, 8375ffd83dbSDimitry Andric OpBundles); 8380b57cec5SDimitry Andric } else { 839*c9157d92SDimitry Andric Value *Args[3] = {Ind->getTargetValue(), DataVar, Builder.getInt32(Index)}; 840e8d8bef9SDimitry Andric Call = Builder.CreateCall( 841*c9157d92SDimitry Andric getOrInsertValueProfilingCall(M, *TLI, ValueProfilingCallType::MemOp), 8425ffd83dbSDimitry Andric Args, OpBundles); 8430b57cec5SDimitry Andric } 8440b57cec5SDimitry Andric if (auto AK = TLI->getExtAttrForI32Param(false)) 8450b57cec5SDimitry Andric Call->addParamAttr(2, AK); 8460b57cec5SDimitry Andric Ind->replaceAllUsesWith(Call); 8470b57cec5SDimitry Andric Ind->eraseFromParent(); 8480b57cec5SDimitry Andric } 8490b57cec5SDimitry Andric 850*c9157d92SDimitry Andric Value *InstrLowerer::getCounterAddress(InstrProfCntrInstBase *I) { 8511fd87a68SDimitry Andric auto *Counters = getOrCreateRegionCounters(I); 8521fd87a68SDimitry Andric IRBuilder<> Builder(I); 8530b57cec5SDimitry Andric 854fe013be4SDimitry Andric if (isa<InstrProfTimestampInst>(I)) 855fe013be4SDimitry Andric Counters->setAlignment(Align(8)); 856fe013be4SDimitry Andric 8571fd87a68SDimitry Andric auto *Addr = Builder.CreateConstInBoundsGEP2_32( 8581fd87a68SDimitry Andric Counters->getValueType(), Counters, 0, I->getIndex()->getZExtValue()); 8590b57cec5SDimitry Andric 8601fd87a68SDimitry Andric if (!isRuntimeCounterRelocationEnabled()) 8611fd87a68SDimitry Andric return Addr; 8621fd87a68SDimitry Andric 863*c9157d92SDimitry Andric Type *Int64Ty = Type::getInt64Ty(M.getContext()); 8641fd87a68SDimitry Andric Function *Fn = I->getParent()->getParent(); 86581ad6265SDimitry Andric LoadInst *&BiasLI = FunctionToProfileBiasMap[Fn]; 86681ad6265SDimitry Andric if (!BiasLI) { 86781ad6265SDimitry Andric IRBuilder<> EntryBuilder(&Fn->getEntryBlock().front()); 868*c9157d92SDimitry Andric auto *Bias = M.getGlobalVariable(getInstrProfCounterBiasVarName()); 8695ffd83dbSDimitry Andric if (!Bias) { 870fe6060f1SDimitry Andric // Compiler must define this variable when runtime counter relocation 871fe6060f1SDimitry Andric // is being used. Runtime has a weak external reference that is used 872fe6060f1SDimitry Andric // to check whether that's the case or not. 8734824e7fdSDimitry Andric Bias = new GlobalVariable( 874*c9157d92SDimitry Andric M, Int64Ty, false, GlobalValue::LinkOnceODRLinkage, 8754824e7fdSDimitry Andric Constant::getNullValue(Int64Ty), getInstrProfCounterBiasVarName()); 8765ffd83dbSDimitry Andric Bias->setVisibility(GlobalVariable::HiddenVisibility); 877fe6060f1SDimitry Andric // A definition that's weak (linkonce_odr) without being in a COMDAT 878fe6060f1SDimitry Andric // section wouldn't lead to link errors, but it would lead to a dead 879fe6060f1SDimitry Andric // data word from every TU but one. Putting it in COMDAT ensures there 880fe6060f1SDimitry Andric // will be exactly one data slot in the link. 881fe6060f1SDimitry Andric if (TT.supportsCOMDAT()) 882*c9157d92SDimitry Andric Bias->setComdat(M.getOrInsertComdat(Bias->getName())); 8835ffd83dbSDimitry Andric } 88481ad6265SDimitry Andric BiasLI = EntryBuilder.CreateLoad(Int64Ty, Bias); 8855ffd83dbSDimitry Andric } 88681ad6265SDimitry Andric auto *Add = Builder.CreateAdd(Builder.CreatePtrToInt(Addr, Int64Ty), BiasLI); 8871fd87a68SDimitry Andric return Builder.CreateIntToPtr(Add, Addr->getType()); 8885ffd83dbSDimitry Andric } 8895ffd83dbSDimitry Andric 890*c9157d92SDimitry Andric Value *InstrLowerer::getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I) { 891*c9157d92SDimitry Andric auto *Bitmaps = getOrCreateRegionBitmaps(I); 892*c9157d92SDimitry Andric IRBuilder<> Builder(I); 893*c9157d92SDimitry Andric 894*c9157d92SDimitry Andric auto *Addr = Builder.CreateConstInBoundsGEP2_32( 895*c9157d92SDimitry Andric Bitmaps->getValueType(), Bitmaps, 0, I->getBitmapIndex()->getZExtValue()); 896*c9157d92SDimitry Andric 897*c9157d92SDimitry Andric if (isRuntimeCounterRelocationEnabled()) { 898*c9157d92SDimitry Andric LLVMContext &Ctx = M.getContext(); 899*c9157d92SDimitry Andric Ctx.diagnose(DiagnosticInfoPGOProfile( 900*c9157d92SDimitry Andric M.getName().data(), 901*c9157d92SDimitry Andric Twine("Runtime counter relocation is presently not supported for MC/DC " 902*c9157d92SDimitry Andric "bitmaps."), 903*c9157d92SDimitry Andric DS_Warning)); 904*c9157d92SDimitry Andric } 905*c9157d92SDimitry Andric 906*c9157d92SDimitry Andric return Addr; 907*c9157d92SDimitry Andric } 908*c9157d92SDimitry Andric 909*c9157d92SDimitry Andric void InstrLowerer::lowerCover(InstrProfCoverInst *CoverInstruction) { 9101fd87a68SDimitry Andric auto *Addr = getCounterAddress(CoverInstruction); 9111fd87a68SDimitry Andric IRBuilder<> Builder(CoverInstruction); 9121fd87a68SDimitry Andric // We store zero to represent that this block is covered. 9131fd87a68SDimitry Andric Builder.CreateStore(Builder.getInt8(0), Addr); 9141fd87a68SDimitry Andric CoverInstruction->eraseFromParent(); 9151fd87a68SDimitry Andric } 9161fd87a68SDimitry Andric 917*c9157d92SDimitry Andric void InstrLowerer::lowerTimestamp( 918fe013be4SDimitry Andric InstrProfTimestampInst *TimestampInstruction) { 919fe013be4SDimitry Andric assert(TimestampInstruction->getIndex()->isZeroValue() && 920fe013be4SDimitry Andric "timestamp probes are always the first probe for a function"); 921*c9157d92SDimitry Andric auto &Ctx = M.getContext(); 922fe013be4SDimitry Andric auto *TimestampAddr = getCounterAddress(TimestampInstruction); 923fe013be4SDimitry Andric IRBuilder<> Builder(TimestampInstruction); 924fe013be4SDimitry Andric auto *CalleeTy = 925fe013be4SDimitry Andric FunctionType::get(Type::getVoidTy(Ctx), TimestampAddr->getType(), false); 926*c9157d92SDimitry Andric auto Callee = M.getOrInsertFunction( 927fe013be4SDimitry Andric INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_SET_TIMESTAMP), CalleeTy); 928fe013be4SDimitry Andric Builder.CreateCall(Callee, {TimestampAddr}); 929fe013be4SDimitry Andric TimestampInstruction->eraseFromParent(); 930fe013be4SDimitry Andric } 931fe013be4SDimitry Andric 932*c9157d92SDimitry Andric void InstrLowerer::lowerIncrement(InstrProfIncrementInst *Inc) { 9331fd87a68SDimitry Andric auto *Addr = getCounterAddress(Inc); 9341fd87a68SDimitry Andric 9351fd87a68SDimitry Andric IRBuilder<> Builder(Inc); 9365ffd83dbSDimitry Andric if (Options.Atomic || AtomicCounterUpdateAll || 9371fd87a68SDimitry Andric (Inc->getIndex()->isZeroValue() && AtomicFirstCounter)) { 9380b57cec5SDimitry Andric Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, Inc->getStep(), 939fe6060f1SDimitry Andric MaybeAlign(), AtomicOrdering::Monotonic); 9400b57cec5SDimitry Andric } else { 9410b57cec5SDimitry Andric Value *IncStep = Inc->getStep(); 9420b57cec5SDimitry Andric Value *Load = Builder.CreateLoad(IncStep->getType(), Addr, "pgocount"); 9430b57cec5SDimitry Andric auto *Count = Builder.CreateAdd(Load, Inc->getStep()); 9440b57cec5SDimitry Andric auto *Store = Builder.CreateStore(Count, Addr); 9450b57cec5SDimitry Andric if (isCounterPromotionEnabled()) 9460b57cec5SDimitry Andric PromotionCandidates.emplace_back(cast<Instruction>(Load), Store); 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric Inc->eraseFromParent(); 9490b57cec5SDimitry Andric } 9500b57cec5SDimitry Andric 951*c9157d92SDimitry Andric void InstrLowerer::lowerCoverageData(GlobalVariable *CoverageNamesVar) { 9520b57cec5SDimitry Andric ConstantArray *Names = 9530b57cec5SDimitry Andric cast<ConstantArray>(CoverageNamesVar->getInitializer()); 9540b57cec5SDimitry Andric for (unsigned I = 0, E = Names->getNumOperands(); I < E; ++I) { 9550b57cec5SDimitry Andric Constant *NC = Names->getOperand(I); 9560b57cec5SDimitry Andric Value *V = NC->stripPointerCasts(); 9570b57cec5SDimitry Andric assert(isa<GlobalVariable>(V) && "Missing reference to function name"); 9580b57cec5SDimitry Andric GlobalVariable *Name = cast<GlobalVariable>(V); 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric Name->setLinkage(GlobalValue::PrivateLinkage); 9610b57cec5SDimitry Andric ReferencedNames.push_back(Name); 96281ad6265SDimitry Andric if (isa<ConstantExpr>(NC)) 9630b57cec5SDimitry Andric NC->dropAllReferences(); 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric CoverageNamesVar->eraseFromParent(); 9660b57cec5SDimitry Andric } 9670b57cec5SDimitry Andric 968*c9157d92SDimitry Andric void InstrLowerer::lowerMCDCTestVectorBitmapUpdate( 969*c9157d92SDimitry Andric InstrProfMCDCTVBitmapUpdate *Update) { 970*c9157d92SDimitry Andric IRBuilder<> Builder(Update); 971*c9157d92SDimitry Andric auto *Int8Ty = Type::getInt8Ty(M.getContext()); 972*c9157d92SDimitry Andric auto *Int8PtrTy = PointerType::getUnqual(M.getContext()); 973*c9157d92SDimitry Andric auto *Int32Ty = Type::getInt32Ty(M.getContext()); 974*c9157d92SDimitry Andric auto *Int64Ty = Type::getInt64Ty(M.getContext()); 975*c9157d92SDimitry Andric auto *MCDCCondBitmapAddr = Update->getMCDCCondBitmapAddr(); 976*c9157d92SDimitry Andric auto *BitmapAddr = getBitmapAddress(Update); 977*c9157d92SDimitry Andric 978*c9157d92SDimitry Andric // Load Temp Val. 979*c9157d92SDimitry Andric // %mcdc.temp = load i32, ptr %mcdc.addr, align 4 980*c9157d92SDimitry Andric auto *Temp = Builder.CreateLoad(Int32Ty, MCDCCondBitmapAddr, "mcdc.temp"); 981*c9157d92SDimitry Andric 982*c9157d92SDimitry Andric // Calculate byte offset using div8. 983*c9157d92SDimitry Andric // %1 = lshr i32 %mcdc.temp, 3 984*c9157d92SDimitry Andric auto *BitmapByteOffset = Builder.CreateLShr(Temp, 0x3); 985*c9157d92SDimitry Andric 986*c9157d92SDimitry Andric // Add byte offset to section base byte address. 987*c9157d92SDimitry Andric // %2 = zext i32 %1 to i64 988*c9157d92SDimitry Andric // %3 = add i64 ptrtoint (ptr @__profbm_test to i64), %2 989*c9157d92SDimitry Andric auto *BitmapByteAddr = 990*c9157d92SDimitry Andric Builder.CreateAdd(Builder.CreatePtrToInt(BitmapAddr, Int64Ty), 991*c9157d92SDimitry Andric Builder.CreateZExtOrBitCast(BitmapByteOffset, Int64Ty)); 992*c9157d92SDimitry Andric 993*c9157d92SDimitry Andric // Convert to a pointer. 994*c9157d92SDimitry Andric // %4 = inttoptr i32 %3 to ptr 995*c9157d92SDimitry Andric BitmapByteAddr = Builder.CreateIntToPtr(BitmapByteAddr, Int8PtrTy); 996*c9157d92SDimitry Andric 997*c9157d92SDimitry Andric // Calculate bit offset into bitmap byte by using div8 remainder (AND ~8) 998*c9157d92SDimitry Andric // %5 = and i32 %mcdc.temp, 7 999*c9157d92SDimitry Andric // %6 = trunc i32 %5 to i8 1000*c9157d92SDimitry Andric auto *BitToSet = Builder.CreateTrunc(Builder.CreateAnd(Temp, 0x7), Int8Ty); 1001*c9157d92SDimitry Andric 1002*c9157d92SDimitry Andric // Shift bit offset left to form a bitmap. 1003*c9157d92SDimitry Andric // %7 = shl i8 1, %6 1004*c9157d92SDimitry Andric auto *ShiftedVal = Builder.CreateShl(Builder.getInt8(0x1), BitToSet); 1005*c9157d92SDimitry Andric 1006*c9157d92SDimitry Andric // Load profile bitmap byte. 1007*c9157d92SDimitry Andric // %mcdc.bits = load i8, ptr %4, align 1 1008*c9157d92SDimitry Andric auto *Bitmap = Builder.CreateLoad(Int8Ty, BitmapByteAddr, "mcdc.bits"); 1009*c9157d92SDimitry Andric 1010*c9157d92SDimitry Andric // Perform logical OR of profile bitmap byte and shifted bit offset. 1011*c9157d92SDimitry Andric // %8 = or i8 %mcdc.bits, %7 1012*c9157d92SDimitry Andric auto *Result = Builder.CreateOr(Bitmap, ShiftedVal); 1013*c9157d92SDimitry Andric 1014*c9157d92SDimitry Andric // Store the updated profile bitmap byte. 1015*c9157d92SDimitry Andric // store i8 %8, ptr %3, align 1 1016*c9157d92SDimitry Andric Builder.CreateStore(Result, BitmapByteAddr); 1017*c9157d92SDimitry Andric Update->eraseFromParent(); 1018*c9157d92SDimitry Andric } 1019*c9157d92SDimitry Andric 1020*c9157d92SDimitry Andric void InstrLowerer::lowerMCDCCondBitmapUpdate( 1021*c9157d92SDimitry Andric InstrProfMCDCCondBitmapUpdate *Update) { 1022*c9157d92SDimitry Andric IRBuilder<> Builder(Update); 1023*c9157d92SDimitry Andric auto *Int32Ty = Type::getInt32Ty(M.getContext()); 1024*c9157d92SDimitry Andric auto *MCDCCondBitmapAddr = Update->getMCDCCondBitmapAddr(); 1025*c9157d92SDimitry Andric 1026*c9157d92SDimitry Andric // Load the MCDC temporary value from the stack. 1027*c9157d92SDimitry Andric // %mcdc.temp = load i32, ptr %mcdc.addr, align 4 1028*c9157d92SDimitry Andric auto *Temp = Builder.CreateLoad(Int32Ty, MCDCCondBitmapAddr, "mcdc.temp"); 1029*c9157d92SDimitry Andric 1030*c9157d92SDimitry Andric // Zero-extend the evaluated condition boolean value (0 or 1) by 32bits. 1031*c9157d92SDimitry Andric // %1 = zext i1 %tobool to i32 1032*c9157d92SDimitry Andric auto *CondV_32 = Builder.CreateZExt(Update->getCondBool(), Int32Ty); 1033*c9157d92SDimitry Andric 1034*c9157d92SDimitry Andric // Shift the boolean value left (by the condition's ID) to form a bitmap. 1035*c9157d92SDimitry Andric // %2 = shl i32 %1, <Update->getCondID()> 1036*c9157d92SDimitry Andric auto *ShiftedVal = Builder.CreateShl(CondV_32, Update->getCondID()); 1037*c9157d92SDimitry Andric 1038*c9157d92SDimitry Andric // Perform logical OR of the bitmap against the loaded MCDC temporary value. 1039*c9157d92SDimitry Andric // %3 = or i32 %mcdc.temp, %2 1040*c9157d92SDimitry Andric auto *Result = Builder.CreateOr(Temp, ShiftedVal); 1041*c9157d92SDimitry Andric 1042*c9157d92SDimitry Andric // Store the updated temporary value back to the stack. 1043*c9157d92SDimitry Andric // store i32 %3, ptr %mcdc.addr, align 4 1044*c9157d92SDimitry Andric Builder.CreateStore(Result, MCDCCondBitmapAddr); 1045*c9157d92SDimitry Andric Update->eraseFromParent(); 1046*c9157d92SDimitry Andric } 1047*c9157d92SDimitry Andric 10480b57cec5SDimitry Andric /// Get the name of a profiling variable for a particular function. 104904eeddc0SDimitry Andric static std::string getVarName(InstrProfInstBase *Inc, StringRef Prefix, 1050349cc55cSDimitry Andric bool &Renamed) { 10510b57cec5SDimitry Andric StringRef NamePrefix = getInstrProfNameVarPrefix(); 10520b57cec5SDimitry Andric StringRef Name = Inc->getName()->getName().substr(NamePrefix.size()); 10530b57cec5SDimitry Andric Function *F = Inc->getParent()->getParent(); 10540b57cec5SDimitry Andric Module *M = F->getParent(); 10550b57cec5SDimitry Andric if (!DoHashBasedCounterSplit || !isIRPGOFlagSet(M) || 1056349cc55cSDimitry Andric !canRenameComdatFunc(*F)) { 1057349cc55cSDimitry Andric Renamed = false; 10580b57cec5SDimitry Andric return (Prefix + Name).str(); 1059349cc55cSDimitry Andric } 1060349cc55cSDimitry Andric Renamed = true; 10610b57cec5SDimitry Andric uint64_t FuncHash = Inc->getHash()->getZExtValue(); 10620b57cec5SDimitry Andric SmallVector<char, 24> HashPostfix; 1063*c9157d92SDimitry Andric if (Name.ends_with((Twine(".") + Twine(FuncHash)).toStringRef(HashPostfix))) 10640b57cec5SDimitry Andric return (Prefix + Name).str(); 10650b57cec5SDimitry Andric return (Prefix + Name + "." + Twine(FuncHash)).str(); 10660b57cec5SDimitry Andric } 10670b57cec5SDimitry Andric 1068fe6060f1SDimitry Andric static uint64_t getIntModuleFlagOrZero(const Module &M, StringRef Flag) { 1069fe6060f1SDimitry Andric auto *MD = dyn_cast_or_null<ConstantAsMetadata>(M.getModuleFlag(Flag)); 1070fe6060f1SDimitry Andric if (!MD) 1071fe6060f1SDimitry Andric return 0; 1072fe6060f1SDimitry Andric 1073fe6060f1SDimitry Andric // If the flag is a ConstantAsMetadata, it should be an integer representable 1074fe6060f1SDimitry Andric // in 64-bits. 1075fe6060f1SDimitry Andric return cast<ConstantInt>(MD->getValue())->getZExtValue(); 1076fe6060f1SDimitry Andric } 1077fe6060f1SDimitry Andric 1078fe6060f1SDimitry Andric static bool enablesValueProfiling(const Module &M) { 1079fe6060f1SDimitry Andric return isIRPGOFlagSet(&M) || 1080fe6060f1SDimitry Andric getIntModuleFlagOrZero(M, "EnableValueProfiling") != 0; 1081fe6060f1SDimitry Andric } 1082fe6060f1SDimitry Andric 1083fe6060f1SDimitry Andric // Conservatively returns true if data variables may be referenced by code. 1084fe6060f1SDimitry Andric static bool profDataReferencedByCode(const Module &M) { 1085fe6060f1SDimitry Andric return enablesValueProfiling(M); 1086fe6060f1SDimitry Andric } 1087fe6060f1SDimitry Andric 10880b57cec5SDimitry Andric static inline bool shouldRecordFunctionAddr(Function *F) { 1089fe6060f1SDimitry Andric // Only record function addresses if IR PGO is enabled or if clang value 1090fe6060f1SDimitry Andric // profiling is enabled. Recording function addresses greatly increases object 1091fe6060f1SDimitry Andric // file size, because it prevents the inliner from deleting functions that 1092fe6060f1SDimitry Andric // have been inlined everywhere. 1093fe6060f1SDimitry Andric if (!profDataReferencedByCode(*F->getParent())) 1094fe6060f1SDimitry Andric return false; 1095fe6060f1SDimitry Andric 10960b57cec5SDimitry Andric // Check the linkage 10970b57cec5SDimitry Andric bool HasAvailableExternallyLinkage = F->hasAvailableExternallyLinkage(); 10980b57cec5SDimitry Andric if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() && 10990b57cec5SDimitry Andric !HasAvailableExternallyLinkage) 11000b57cec5SDimitry Andric return true; 11010b57cec5SDimitry Andric 11020b57cec5SDimitry Andric // A function marked 'alwaysinline' with available_externally linkage can't 11030b57cec5SDimitry Andric // have its address taken. Doing so would create an undefined external ref to 11040b57cec5SDimitry Andric // the function, which would fail to link. 11050b57cec5SDimitry Andric if (HasAvailableExternallyLinkage && 11060b57cec5SDimitry Andric F->hasFnAttribute(Attribute::AlwaysInline)) 11070b57cec5SDimitry Andric return false; 11080b57cec5SDimitry Andric 11090b57cec5SDimitry Andric // Prohibit function address recording if the function is both internal and 11100b57cec5SDimitry Andric // COMDAT. This avoids the profile data variable referencing internal symbols 11110b57cec5SDimitry Andric // in COMDAT. 11120b57cec5SDimitry Andric if (F->hasLocalLinkage() && F->hasComdat()) 11130b57cec5SDimitry Andric return false; 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric // Check uses of this function for other than direct calls or invokes to it. 11160b57cec5SDimitry Andric // Inline virtual functions have linkeOnceODR linkage. When a key method 11170b57cec5SDimitry Andric // exists, the vtable will only be emitted in the TU where the key method 11180b57cec5SDimitry Andric // is defined. In a TU where vtable is not available, the function won't 11190b57cec5SDimitry Andric // be 'addresstaken'. If its address is not recorded here, the profile data 11200b57cec5SDimitry Andric // with missing address may be picked by the linker leading to missing 11210b57cec5SDimitry Andric // indirect call target info. 11220b57cec5SDimitry Andric return F->hasAddressTaken() || F->hasLinkOnceLinkage(); 11230b57cec5SDimitry Andric } 11240b57cec5SDimitry Andric 1125fe013be4SDimitry Andric static inline bool shouldUsePublicSymbol(Function *Fn) { 1126fe013be4SDimitry Andric // It isn't legal to make an alias of this function at all 1127fe013be4SDimitry Andric if (Fn->isDeclarationForLinker()) 1128fe013be4SDimitry Andric return true; 1129fe013be4SDimitry Andric 1130fe013be4SDimitry Andric // Symbols with local linkage can just use the symbol directly without 1131fe013be4SDimitry Andric // introducing relocations 1132fe013be4SDimitry Andric if (Fn->hasLocalLinkage()) 1133fe013be4SDimitry Andric return true; 1134fe013be4SDimitry Andric 1135fe013be4SDimitry Andric // PGO + ThinLTO + CFI cause duplicate symbols to be introduced due to some 1136fe013be4SDimitry Andric // unfavorable interaction between the new alias and the alias renaming done 1137fe013be4SDimitry Andric // in LowerTypeTests under ThinLTO. For comdat functions that would normally 1138fe013be4SDimitry Andric // be deduplicated, but the renaming scheme ends up preventing renaming, since 1139fe013be4SDimitry Andric // it creates unique names for each alias, resulting in duplicated symbols. In 1140fe013be4SDimitry Andric // the future, we should update the CFI related passes to migrate these 1141fe013be4SDimitry Andric // aliases to the same module as the jump-table they refer to will be defined. 1142fe013be4SDimitry Andric if (Fn->hasMetadata(LLVMContext::MD_type)) 1143fe013be4SDimitry Andric return true; 1144fe013be4SDimitry Andric 1145fe013be4SDimitry Andric // For comdat functions, an alias would need the same linkage as the original 1146fe013be4SDimitry Andric // function and hidden visibility. There is no point in adding an alias with 1147fe013be4SDimitry Andric // identical linkage an visibility to avoid introducing symbolic relocations. 1148fe013be4SDimitry Andric if (Fn->hasComdat() && 1149fe013be4SDimitry Andric (Fn->getVisibility() == GlobalValue::VisibilityTypes::HiddenVisibility)) 1150fe013be4SDimitry Andric return true; 1151fe013be4SDimitry Andric 1152fe013be4SDimitry Andric // its OK to use an alias 1153fe013be4SDimitry Andric return false; 1154fe013be4SDimitry Andric } 1155fe013be4SDimitry Andric 1156fe013be4SDimitry Andric static inline Constant *getFuncAddrForProfData(Function *Fn) { 1157*c9157d92SDimitry Andric auto *Int8PtrTy = PointerType::getUnqual(Fn->getContext()); 1158fe013be4SDimitry Andric // Store a nullptr in __llvm_profd, if we shouldn't use a real address 1159fe013be4SDimitry Andric if (!shouldRecordFunctionAddr(Fn)) 1160fe013be4SDimitry Andric return ConstantPointerNull::get(Int8PtrTy); 1161fe013be4SDimitry Andric 1162fe013be4SDimitry Andric // If we can't use an alias, we must use the public symbol, even though this 1163fe013be4SDimitry Andric // may require a symbolic relocation. 1164fe013be4SDimitry Andric if (shouldUsePublicSymbol(Fn)) 1165*c9157d92SDimitry Andric return Fn; 1166fe013be4SDimitry Andric 1167fe013be4SDimitry Andric // When possible use a private alias to avoid symbolic relocations. 1168fe013be4SDimitry Andric auto *GA = GlobalAlias::create(GlobalValue::LinkageTypes::PrivateLinkage, 1169fe013be4SDimitry Andric Fn->getName() + ".local", Fn); 1170fe013be4SDimitry Andric 1171fe013be4SDimitry Andric // When the instrumented function is a COMDAT function, we cannot use a 1172fe013be4SDimitry Andric // private alias. If we did, we would create reference to a local label in 1173fe013be4SDimitry Andric // this function's section. If this version of the function isn't selected by 1174fe013be4SDimitry Andric // the linker, then the metadata would introduce a reference to a discarded 1175fe013be4SDimitry Andric // section. So, for COMDAT functions, we need to adjust the linkage of the 1176fe013be4SDimitry Andric // alias. Using hidden visibility avoids a dynamic relocation and an entry in 1177fe013be4SDimitry Andric // the dynamic symbol table. 1178fe013be4SDimitry Andric // 1179fe013be4SDimitry Andric // Note that this handles COMDAT functions with visibility other than Hidden, 1180fe013be4SDimitry Andric // since that case is covered in shouldUsePublicSymbol() 1181fe013be4SDimitry Andric if (Fn->hasComdat()) { 1182fe013be4SDimitry Andric GA->setLinkage(Fn->getLinkage()); 1183fe013be4SDimitry Andric GA->setVisibility(GlobalValue::VisibilityTypes::HiddenVisibility); 1184fe013be4SDimitry Andric } 1185fe013be4SDimitry Andric 1186fe013be4SDimitry Andric // appendToCompilerUsed(*Fn->getParent(), {GA}); 1187fe013be4SDimitry Andric 1188*c9157d92SDimitry Andric return GA; 1189fe013be4SDimitry Andric } 1190fe013be4SDimitry Andric 11910b57cec5SDimitry Andric static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) { 11920b57cec5SDimitry Andric // Don't do this for Darwin. compiler-rt uses linker magic. 11930b57cec5SDimitry Andric if (TT.isOSDarwin()) 11940b57cec5SDimitry Andric return false; 11950b57cec5SDimitry Andric // Use linker script magic to get data/cnts/name start/end. 119681ad6265SDimitry Andric if (TT.isOSAIX() || TT.isOSLinux() || TT.isOSFreeBSD() || TT.isOSNetBSD() || 119781ad6265SDimitry Andric TT.isOSSolaris() || TT.isOSFuchsia() || TT.isPS() || TT.isOSWindows()) 11980b57cec5SDimitry Andric return false; 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric return true; 12010b57cec5SDimitry Andric } 12020b57cec5SDimitry Andric 1203*c9157d92SDimitry Andric void InstrLowerer::maybeSetComdat(GlobalVariable *GV, Function *Fn, 1204*c9157d92SDimitry Andric StringRef VarName) { 1205*c9157d92SDimitry Andric bool DataReferencedByCode = profDataReferencedByCode(M); 1206*c9157d92SDimitry Andric bool NeedComdat = needsComdatForCounter(*Fn, M); 1207*c9157d92SDimitry Andric bool UseComdat = (NeedComdat || TT.isOSBinFormatELF()); 1208*c9157d92SDimitry Andric 1209*c9157d92SDimitry Andric if (!UseComdat) 1210*c9157d92SDimitry Andric return; 1211*c9157d92SDimitry Andric 1212*c9157d92SDimitry Andric StringRef GroupName = 1213*c9157d92SDimitry Andric TT.isOSBinFormatCOFF() && DataReferencedByCode ? GV->getName() : VarName; 1214*c9157d92SDimitry Andric Comdat *C = M.getOrInsertComdat(GroupName); 1215*c9157d92SDimitry Andric if (!NeedComdat) 1216*c9157d92SDimitry Andric C->setSelectionKind(Comdat::NoDeduplicate); 1217*c9157d92SDimitry Andric GV->setComdat(C); 1218*c9157d92SDimitry Andric // COFF doesn't allow the comdat group leader to have private linkage, so 1219*c9157d92SDimitry Andric // upgrade private linkage to internal linkage to produce a symbol table 1220*c9157d92SDimitry Andric // entry. 1221*c9157d92SDimitry Andric if (TT.isOSBinFormatCOFF() && GV->hasPrivateLinkage()) 1222*c9157d92SDimitry Andric GV->setLinkage(GlobalValue::InternalLinkage); 12231fd87a68SDimitry Andric } 12241fd87a68SDimitry Andric 1225*c9157d92SDimitry Andric GlobalVariable *InstrLowerer::setupProfileSection(InstrProfInstBase *Inc, 1226*c9157d92SDimitry Andric InstrProfSectKind IPSK) { 12270b57cec5SDimitry Andric GlobalVariable *NamePtr = Inc->getName(); 12280b57cec5SDimitry Andric 1229fe6060f1SDimitry Andric // Match the linkage and visibility of the name global. 12300b57cec5SDimitry Andric Function *Fn = Inc->getParent()->getParent(); 12310b57cec5SDimitry Andric GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage(); 12320b57cec5SDimitry Andric GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility(); 12330b57cec5SDimitry Andric 12340eae32dcSDimitry Andric // Use internal rather than private linkage so the counter variable shows up 12350eae32dcSDimitry Andric // in the symbol table when using debug info for correlation. 1236*c9157d92SDimitry Andric if ((DebugInfoCorrelate || 1237*c9157d92SDimitry Andric ProfileCorrelate == InstrProfCorrelator::DEBUG_INFO) && 1238*c9157d92SDimitry Andric TT.isOSBinFormatMachO() && Linkage == GlobalValue::PrivateLinkage) 12390eae32dcSDimitry Andric Linkage = GlobalValue::InternalLinkage; 12400eae32dcSDimitry Andric 1241349cc55cSDimitry Andric // Due to the limitation of binder as of 2021/09/28, the duplicate weak 1242349cc55cSDimitry Andric // symbols in the same csect won't be discarded. When there are duplicate weak 1243349cc55cSDimitry Andric // symbols, we can NOT guarantee that the relocations get resolved to the 1244349cc55cSDimitry Andric // intended weak symbol, so we can not ensure the correctness of the relative 1245349cc55cSDimitry Andric // CounterPtr, so we have to use private linkage for counter and data symbols. 1246349cc55cSDimitry Andric if (TT.isOSBinFormatXCOFF()) { 1247349cc55cSDimitry Andric Linkage = GlobalValue::PrivateLinkage; 1248349cc55cSDimitry Andric Visibility = GlobalValue::DefaultVisibility; 1249349cc55cSDimitry Andric } 12500b57cec5SDimitry Andric // Move the name variable to the right section. Place them in a COMDAT group 12510b57cec5SDimitry Andric // if the associated function is a COMDAT. This will make sure that only one 12520b57cec5SDimitry Andric // copy of counters of the COMDAT function will be emitted after linking. Keep 12530b57cec5SDimitry Andric // in mind that this pass may run before the inliner, so we need to create a 12540b57cec5SDimitry Andric // new comdat group for the counters and profiling data. If we use the comdat 12550b57cec5SDimitry Andric // of the parent function, that will result in relocations against discarded 12560b57cec5SDimitry Andric // sections. 1257fe6060f1SDimitry Andric // 1258fe6060f1SDimitry Andric // If the data variable is referenced by code, counters and data have to be 1259fe6060f1SDimitry Andric // in different comdats for COFF because the Visual C++ linker will report 1260fe6060f1SDimitry Andric // duplicate symbol errors if there are multiple external symbols with the 1261fe6060f1SDimitry Andric // same name marked IMAGE_COMDAT_SELECT_ASSOCIATIVE. 1262fe6060f1SDimitry Andric // 1263fe6060f1SDimitry Andric // For ELF, when not using COMDAT, put counters, data and values into a 1264fe6060f1SDimitry Andric // nodeduplicate COMDAT which is lowered to a zero-flag section group. This 1265fe6060f1SDimitry Andric // allows -z start-stop-gc to discard the entire group when the function is 1266fe6060f1SDimitry Andric // discarded. 1267349cc55cSDimitry Andric bool Renamed; 1268*c9157d92SDimitry Andric GlobalVariable *Ptr; 1269*c9157d92SDimitry Andric StringRef VarPrefix; 1270*c9157d92SDimitry Andric std::string VarName; 1271*c9157d92SDimitry Andric if (IPSK == IPSK_cnts) { 1272*c9157d92SDimitry Andric VarPrefix = getInstrProfCountersVarPrefix(); 1273*c9157d92SDimitry Andric VarName = getVarName(Inc, VarPrefix, Renamed); 1274*c9157d92SDimitry Andric InstrProfCntrInstBase *CntrIncrement = dyn_cast<InstrProfCntrInstBase>(Inc); 1275*c9157d92SDimitry Andric Ptr = createRegionCounters(CntrIncrement, VarName, Linkage); 1276*c9157d92SDimitry Andric } else if (IPSK == IPSK_bitmap) { 1277*c9157d92SDimitry Andric VarPrefix = getInstrProfBitmapVarPrefix(); 1278*c9157d92SDimitry Andric VarName = getVarName(Inc, VarPrefix, Renamed); 1279*c9157d92SDimitry Andric InstrProfMCDCBitmapInstBase *BitmapUpdate = 1280*c9157d92SDimitry Andric dyn_cast<InstrProfMCDCBitmapInstBase>(Inc); 1281*c9157d92SDimitry Andric Ptr = createRegionBitmaps(BitmapUpdate, VarName, Linkage); 1282*c9157d92SDimitry Andric } else { 1283*c9157d92SDimitry Andric llvm_unreachable("Profile Section must be for Counters or Bitmaps"); 1284fe6060f1SDimitry Andric } 12850b57cec5SDimitry Andric 1286*c9157d92SDimitry Andric Ptr->setVisibility(Visibility); 1287*c9157d92SDimitry Andric // Put the counters and bitmaps in their own sections so linkers can 1288*c9157d92SDimitry Andric // remove unneeded sections. 1289*c9157d92SDimitry Andric Ptr->setSection(getInstrProfSectionName(IPSK, TT.getObjectFormat())); 1290*c9157d92SDimitry Andric Ptr->setLinkage(Linkage); 1291*c9157d92SDimitry Andric maybeSetComdat(Ptr, Fn, VarName); 1292*c9157d92SDimitry Andric return Ptr; 1293*c9157d92SDimitry Andric } 1294*c9157d92SDimitry Andric 1295*c9157d92SDimitry Andric GlobalVariable * 1296*c9157d92SDimitry Andric InstrLowerer::createRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc, 1297*c9157d92SDimitry Andric StringRef Name, 1298*c9157d92SDimitry Andric GlobalValue::LinkageTypes Linkage) { 1299*c9157d92SDimitry Andric uint64_t NumBytes = Inc->getNumBitmapBytes()->getZExtValue(); 1300*c9157d92SDimitry Andric auto *BitmapTy = ArrayType::get(Type::getInt8Ty(M.getContext()), NumBytes); 1301*c9157d92SDimitry Andric auto GV = new GlobalVariable(M, BitmapTy, false, Linkage, 1302*c9157d92SDimitry Andric Constant::getNullValue(BitmapTy), Name); 1303*c9157d92SDimitry Andric GV->setAlignment(Align(1)); 1304*c9157d92SDimitry Andric return GV; 1305*c9157d92SDimitry Andric } 1306*c9157d92SDimitry Andric 1307*c9157d92SDimitry Andric GlobalVariable * 1308*c9157d92SDimitry Andric InstrLowerer::getOrCreateRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc) { 1309*c9157d92SDimitry Andric GlobalVariable *NamePtr = Inc->getName(); 1310*c9157d92SDimitry Andric auto &PD = ProfileDataMap[NamePtr]; 1311*c9157d92SDimitry Andric if (PD.RegionBitmaps) 1312*c9157d92SDimitry Andric return PD.RegionBitmaps; 1313*c9157d92SDimitry Andric 1314*c9157d92SDimitry Andric // If RegionBitmaps doesn't already exist, create it by first setting up 1315*c9157d92SDimitry Andric // the corresponding profile section. 1316*c9157d92SDimitry Andric auto *BitmapPtr = setupProfileSection(Inc, IPSK_bitmap); 1317*c9157d92SDimitry Andric PD.RegionBitmaps = BitmapPtr; 1318*c9157d92SDimitry Andric PD.NumBitmapBytes = Inc->getNumBitmapBytes()->getZExtValue(); 1319*c9157d92SDimitry Andric return PD.RegionBitmaps; 1320*c9157d92SDimitry Andric } 1321*c9157d92SDimitry Andric 1322*c9157d92SDimitry Andric GlobalVariable * 1323*c9157d92SDimitry Andric InstrLowerer::createRegionCounters(InstrProfCntrInstBase *Inc, StringRef Name, 1324*c9157d92SDimitry Andric GlobalValue::LinkageTypes Linkage) { 13250b57cec5SDimitry Andric uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); 1326*c9157d92SDimitry Andric auto &Ctx = M.getContext(); 1327*c9157d92SDimitry Andric GlobalVariable *GV; 1328*c9157d92SDimitry Andric if (isa<InstrProfCoverInst>(Inc)) { 1329*c9157d92SDimitry Andric auto *CounterTy = Type::getInt8Ty(Ctx); 1330*c9157d92SDimitry Andric auto *CounterArrTy = ArrayType::get(CounterTy, NumCounters); 1331*c9157d92SDimitry Andric // TODO: `Constant::getAllOnesValue()` does not yet accept an array type. 1332*c9157d92SDimitry Andric std::vector<Constant *> InitialValues(NumCounters, 1333*c9157d92SDimitry Andric Constant::getAllOnesValue(CounterTy)); 1334*c9157d92SDimitry Andric GV = new GlobalVariable(M, CounterArrTy, false, Linkage, 1335*c9157d92SDimitry Andric ConstantArray::get(CounterArrTy, InitialValues), 1336*c9157d92SDimitry Andric Name); 1337*c9157d92SDimitry Andric GV->setAlignment(Align(1)); 1338*c9157d92SDimitry Andric } else { 1339*c9157d92SDimitry Andric auto *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters); 1340*c9157d92SDimitry Andric GV = new GlobalVariable(M, CounterTy, false, Linkage, 1341*c9157d92SDimitry Andric Constant::getNullValue(CounterTy), Name); 1342*c9157d92SDimitry Andric GV->setAlignment(Align(8)); 1343*c9157d92SDimitry Andric } 1344*c9157d92SDimitry Andric return GV; 1345*c9157d92SDimitry Andric } 13460b57cec5SDimitry Andric 1347*c9157d92SDimitry Andric GlobalVariable * 1348*c9157d92SDimitry Andric InstrLowerer::getOrCreateRegionCounters(InstrProfCntrInstBase *Inc) { 1349*c9157d92SDimitry Andric GlobalVariable *NamePtr = Inc->getName(); 1350*c9157d92SDimitry Andric auto &PD = ProfileDataMap[NamePtr]; 1351*c9157d92SDimitry Andric if (PD.RegionCounters) 1352*c9157d92SDimitry Andric return PD.RegionCounters; 1353*c9157d92SDimitry Andric 1354*c9157d92SDimitry Andric // If RegionCounters doesn't already exist, create it by first setting up 1355*c9157d92SDimitry Andric // the corresponding profile section. 1356*c9157d92SDimitry Andric auto *CounterPtr = setupProfileSection(Inc, IPSK_cnts); 13574824e7fdSDimitry Andric PD.RegionCounters = CounterPtr; 1358*c9157d92SDimitry Andric 1359*c9157d92SDimitry Andric if (DebugInfoCorrelate || 1360*c9157d92SDimitry Andric ProfileCorrelate == InstrProfCorrelator::DEBUG_INFO) { 1361*c9157d92SDimitry Andric LLVMContext &Ctx = M.getContext(); 1362*c9157d92SDimitry Andric Function *Fn = Inc->getParent()->getParent(); 13630eae32dcSDimitry Andric if (auto *SP = Fn->getSubprogram()) { 1364*c9157d92SDimitry Andric DIBuilder DB(M, true, SP->getUnit()); 13650eae32dcSDimitry Andric Metadata *FunctionNameAnnotation[] = { 13660eae32dcSDimitry Andric MDString::get(Ctx, InstrProfCorrelator::FunctionNameAttributeName), 13670eae32dcSDimitry Andric MDString::get(Ctx, getPGOFuncNameVarInitializer(NamePtr)), 13680eae32dcSDimitry Andric }; 13690eae32dcSDimitry Andric Metadata *CFGHashAnnotation[] = { 13700eae32dcSDimitry Andric MDString::get(Ctx, InstrProfCorrelator::CFGHashAttributeName), 13710eae32dcSDimitry Andric ConstantAsMetadata::get(Inc->getHash()), 13720eae32dcSDimitry Andric }; 13730eae32dcSDimitry Andric Metadata *NumCountersAnnotation[] = { 13740eae32dcSDimitry Andric MDString::get(Ctx, InstrProfCorrelator::NumCountersAttributeName), 13750eae32dcSDimitry Andric ConstantAsMetadata::get(Inc->getNumCounters()), 13760eae32dcSDimitry Andric }; 13770eae32dcSDimitry Andric auto Annotations = DB.getOrCreateArray({ 13780eae32dcSDimitry Andric MDNode::get(Ctx, FunctionNameAnnotation), 13790eae32dcSDimitry Andric MDNode::get(Ctx, CFGHashAnnotation), 13800eae32dcSDimitry Andric MDNode::get(Ctx, NumCountersAnnotation), 13810eae32dcSDimitry Andric }); 13820eae32dcSDimitry Andric auto *DICounter = DB.createGlobalVariableExpression( 13830eae32dcSDimitry Andric SP, CounterPtr->getName(), /*LinkageName=*/StringRef(), SP->getFile(), 13840eae32dcSDimitry Andric /*LineNo=*/0, DB.createUnspecifiedType("Profile Data Type"), 13850eae32dcSDimitry Andric CounterPtr->hasLocalLinkage(), /*IsDefined=*/true, /*Expr=*/nullptr, 13860eae32dcSDimitry Andric /*Decl=*/nullptr, /*TemplateParams=*/nullptr, /*AlignInBits=*/0, 13870eae32dcSDimitry Andric Annotations); 13880eae32dcSDimitry Andric CounterPtr->addDebugInfo(DICounter); 13890eae32dcSDimitry Andric DB.finalize(); 13900eae32dcSDimitry Andric } 13910b57cec5SDimitry Andric 1392*c9157d92SDimitry Andric // Mark the counter variable as used so that it isn't optimized out. 1393*c9157d92SDimitry Andric CompilerUsedVars.push_back(PD.RegionCounters); 1394*c9157d92SDimitry Andric } 1395*c9157d92SDimitry Andric 1396*c9157d92SDimitry Andric // Create the data variable (if it doesn't already exist). 1397*c9157d92SDimitry Andric createDataVariable(Inc); 1398*c9157d92SDimitry Andric 1399*c9157d92SDimitry Andric return PD.RegionCounters; 1400*c9157d92SDimitry Andric } 1401*c9157d92SDimitry Andric 1402*c9157d92SDimitry Andric void InstrLowerer::createDataVariable(InstrProfCntrInstBase *Inc) { 1403*c9157d92SDimitry Andric // When debug information is correlated to profile data, a data variable 1404*c9157d92SDimitry Andric // is not needed. 1405*c9157d92SDimitry Andric if (DebugInfoCorrelate || ProfileCorrelate == InstrProfCorrelator::DEBUG_INFO) 1406*c9157d92SDimitry Andric return; 1407*c9157d92SDimitry Andric 1408*c9157d92SDimitry Andric GlobalVariable *NamePtr = Inc->getName(); 1409*c9157d92SDimitry Andric auto &PD = ProfileDataMap[NamePtr]; 1410*c9157d92SDimitry Andric 1411*c9157d92SDimitry Andric // Return if data variable was already created. 1412*c9157d92SDimitry Andric if (PD.DataVar) 1413*c9157d92SDimitry Andric return; 1414*c9157d92SDimitry Andric 1415*c9157d92SDimitry Andric LLVMContext &Ctx = M.getContext(); 1416*c9157d92SDimitry Andric 1417*c9157d92SDimitry Andric Function *Fn = Inc->getParent()->getParent(); 1418*c9157d92SDimitry Andric GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage(); 1419*c9157d92SDimitry Andric GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility(); 1420*c9157d92SDimitry Andric 1421*c9157d92SDimitry Andric // Due to the limitation of binder as of 2021/09/28, the duplicate weak 1422*c9157d92SDimitry Andric // symbols in the same csect won't be discarded. When there are duplicate weak 1423*c9157d92SDimitry Andric // symbols, we can NOT guarantee that the relocations get resolved to the 1424*c9157d92SDimitry Andric // intended weak symbol, so we can not ensure the correctness of the relative 1425*c9157d92SDimitry Andric // CounterPtr, so we have to use private linkage for counter and data symbols. 1426*c9157d92SDimitry Andric if (TT.isOSBinFormatXCOFF()) { 1427*c9157d92SDimitry Andric Linkage = GlobalValue::PrivateLinkage; 1428*c9157d92SDimitry Andric Visibility = GlobalValue::DefaultVisibility; 1429*c9157d92SDimitry Andric } 1430*c9157d92SDimitry Andric 1431*c9157d92SDimitry Andric bool DataReferencedByCode = profDataReferencedByCode(M); 1432*c9157d92SDimitry Andric bool NeedComdat = needsComdatForCounter(*Fn, M); 1433*c9157d92SDimitry Andric bool Renamed; 1434*c9157d92SDimitry Andric 1435*c9157d92SDimitry Andric // The Data Variable section is anchored to profile counters. 1436*c9157d92SDimitry Andric std::string CntsVarName = 1437*c9157d92SDimitry Andric getVarName(Inc, getInstrProfCountersVarPrefix(), Renamed); 1438*c9157d92SDimitry Andric std::string DataVarName = 1439*c9157d92SDimitry Andric getVarName(Inc, getInstrProfDataVarPrefix(), Renamed); 1440*c9157d92SDimitry Andric 1441*c9157d92SDimitry Andric auto *Int8PtrTy = PointerType::getUnqual(Ctx); 14420b57cec5SDimitry Andric // Allocate statically the array of pointers to value profile nodes for 14430b57cec5SDimitry Andric // the current function. 14440b57cec5SDimitry Andric Constant *ValuesPtrExpr = ConstantPointerNull::get(Int8PtrTy); 14450b57cec5SDimitry Andric uint64_t NS = 0; 14460b57cec5SDimitry Andric for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 14470b57cec5SDimitry Andric NS += PD.NumValueSites[Kind]; 1448fe6060f1SDimitry Andric if (NS > 0 && ValueProfileStaticAlloc && 1449fe6060f1SDimitry Andric !needsRuntimeRegistrationOfSectionRange(TT)) { 14500b57cec5SDimitry Andric ArrayType *ValuesTy = ArrayType::get(Type::getInt64Ty(Ctx), NS); 1451fe6060f1SDimitry Andric auto *ValuesVar = new GlobalVariable( 1452*c9157d92SDimitry Andric M, ValuesTy, false, Linkage, Constant::getNullValue(ValuesTy), 1453349cc55cSDimitry Andric getVarName(Inc, getInstrProfValuesVarPrefix(), Renamed)); 14540b57cec5SDimitry Andric ValuesVar->setVisibility(Visibility); 1455*c9157d92SDimitry Andric setGlobalVariableLargeSection(TT, *ValuesVar); 14560b57cec5SDimitry Andric ValuesVar->setSection( 14570b57cec5SDimitry Andric getInstrProfSectionName(IPSK_vals, TT.getObjectFormat())); 14588bcb0991SDimitry Andric ValuesVar->setAlignment(Align(8)); 1459*c9157d92SDimitry Andric maybeSetComdat(ValuesVar, Fn, CntsVarName); 1460*c9157d92SDimitry Andric ValuesPtrExpr = ValuesVar; 14610b57cec5SDimitry Andric } 14620b57cec5SDimitry Andric 1463*c9157d92SDimitry Andric uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); 1464*c9157d92SDimitry Andric auto *CounterPtr = PD.RegionCounters; 1465*c9157d92SDimitry Andric 1466*c9157d92SDimitry Andric uint64_t NumBitmapBytes = PD.NumBitmapBytes; 14670eae32dcSDimitry Andric 14680b57cec5SDimitry Andric // Create data variable. 1469*c9157d92SDimitry Andric auto *IntPtrTy = M.getDataLayout().getIntPtrType(M.getContext()); 14700b57cec5SDimitry Andric auto *Int16Ty = Type::getInt16Ty(Ctx); 14710b57cec5SDimitry Andric auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last + 1); 14720b57cec5SDimitry Andric Type *DataTypes[] = { 14730b57cec5SDimitry Andric #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType, 14740b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProfData.inc" 14750b57cec5SDimitry Andric }; 1476bdd1243dSDimitry Andric auto *DataTy = StructType::get(Ctx, ArrayRef(DataTypes)); 14770b57cec5SDimitry Andric 1478fe013be4SDimitry Andric Constant *FunctionAddr = getFuncAddrForProfData(Fn); 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric Constant *Int16ArrayVals[IPVK_Last + 1]; 14810b57cec5SDimitry Andric for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 14820b57cec5SDimitry Andric Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]); 14830b57cec5SDimitry Andric 1484fe6060f1SDimitry Andric // If the data variable is not referenced by code (if we don't emit 1485fe6060f1SDimitry Andric // @llvm.instrprof.value.profile, NS will be 0), and the counter keeps the 1486fe6060f1SDimitry Andric // data variable live under linker GC, the data variable can be private. This 1487fe6060f1SDimitry Andric // optimization applies to ELF. 1488fe6060f1SDimitry Andric // 1489fe6060f1SDimitry Andric // On COFF, a comdat leader cannot be local so we require DataReferencedByCode 1490fe6060f1SDimitry Andric // to be false. 1491349cc55cSDimitry Andric // 1492349cc55cSDimitry Andric // If profd is in a deduplicate comdat, NS==0 with a hash suffix guarantees 1493349cc55cSDimitry Andric // that other copies must have the same CFG and cannot have value profiling. 1494349cc55cSDimitry Andric // If no hash suffix, other profd copies may be referenced by code. 1495349cc55cSDimitry Andric if (NS == 0 && !(DataReferencedByCode && NeedComdat && !Renamed) && 1496349cc55cSDimitry Andric (TT.isOSBinFormatELF() || 1497fe6060f1SDimitry Andric (!DataReferencedByCode && TT.isOSBinFormatCOFF()))) { 1498fe6060f1SDimitry Andric Linkage = GlobalValue::PrivateLinkage; 1499fe6060f1SDimitry Andric Visibility = GlobalValue::DefaultVisibility; 1500fe6060f1SDimitry Andric } 1501e8d8bef9SDimitry Andric auto *Data = 1502*c9157d92SDimitry Andric new GlobalVariable(M, DataTy, false, Linkage, nullptr, DataVarName); 1503*c9157d92SDimitry Andric Constant *RelativeCounterPtr; 1504*c9157d92SDimitry Andric GlobalVariable *BitmapPtr = PD.RegionBitmaps; 1505*c9157d92SDimitry Andric Constant *RelativeBitmapPtr = ConstantInt::get(IntPtrTy, 0); 1506*c9157d92SDimitry Andric InstrProfSectKind DataSectionKind; 1507*c9157d92SDimitry Andric // With binary profile correlation, profile data is not loaded into memory. 1508*c9157d92SDimitry Andric // profile data must reference profile counter with an absolute relocation. 1509*c9157d92SDimitry Andric if (ProfileCorrelate == InstrProfCorrelator::BINARY) { 1510*c9157d92SDimitry Andric DataSectionKind = IPSK_covdata; 1511*c9157d92SDimitry Andric RelativeCounterPtr = ConstantExpr::getPtrToInt(CounterPtr, IntPtrTy); 1512*c9157d92SDimitry Andric if (BitmapPtr != nullptr) 1513*c9157d92SDimitry Andric RelativeBitmapPtr = ConstantExpr::getPtrToInt(BitmapPtr, IntPtrTy); 1514*c9157d92SDimitry Andric } else { 1515349cc55cSDimitry Andric // Reference the counter variable with a label difference (link-time 1516349cc55cSDimitry Andric // constant). 1517*c9157d92SDimitry Andric DataSectionKind = IPSK_data; 1518*c9157d92SDimitry Andric RelativeCounterPtr = 1519349cc55cSDimitry Andric ConstantExpr::getSub(ConstantExpr::getPtrToInt(CounterPtr, IntPtrTy), 1520349cc55cSDimitry Andric ConstantExpr::getPtrToInt(Data, IntPtrTy)); 1521*c9157d92SDimitry Andric if (BitmapPtr != nullptr) 1522*c9157d92SDimitry Andric RelativeBitmapPtr = 1523*c9157d92SDimitry Andric ConstantExpr::getSub(ConstantExpr::getPtrToInt(BitmapPtr, IntPtrTy), 1524*c9157d92SDimitry Andric ConstantExpr::getPtrToInt(Data, IntPtrTy)); 1525*c9157d92SDimitry Andric } 1526349cc55cSDimitry Andric 1527349cc55cSDimitry Andric Constant *DataVals[] = { 1528349cc55cSDimitry Andric #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init, 1529349cc55cSDimitry Andric #include "llvm/ProfileData/InstrProfData.inc" 1530349cc55cSDimitry Andric }; 1531349cc55cSDimitry Andric Data->setInitializer(ConstantStruct::get(DataTy, DataVals)); 1532349cc55cSDimitry Andric 15330b57cec5SDimitry Andric Data->setVisibility(Visibility); 1534*c9157d92SDimitry Andric Data->setSection( 1535*c9157d92SDimitry Andric getInstrProfSectionName(DataSectionKind, TT.getObjectFormat())); 15368bcb0991SDimitry Andric Data->setAlignment(Align(INSTR_PROF_DATA_ALIGNMENT)); 1537*c9157d92SDimitry Andric maybeSetComdat(Data, Fn, CntsVarName); 15380b57cec5SDimitry Andric 15390b57cec5SDimitry Andric PD.DataVar = Data; 15400b57cec5SDimitry Andric 15410b57cec5SDimitry Andric // Mark the data variable as used so that it isn't stripped out. 1542fe6060f1SDimitry Andric CompilerUsedVars.push_back(Data); 15430b57cec5SDimitry Andric // Now that the linkage set by the FE has been passed to the data and counter 15440b57cec5SDimitry Andric // variables, reset Name variable's linkage and visibility to private so that 15450b57cec5SDimitry Andric // it can be removed later by the compiler. 15460b57cec5SDimitry Andric NamePtr->setLinkage(GlobalValue::PrivateLinkage); 15470b57cec5SDimitry Andric // Collect the referenced names to be used by emitNameData. 15480b57cec5SDimitry Andric ReferencedNames.push_back(NamePtr); 15490b57cec5SDimitry Andric } 15500b57cec5SDimitry Andric 1551*c9157d92SDimitry Andric void InstrLowerer::emitVNodes() { 15520b57cec5SDimitry Andric if (!ValueProfileStaticAlloc) 15530b57cec5SDimitry Andric return; 15540b57cec5SDimitry Andric 15550b57cec5SDimitry Andric // For now only support this on platforms that do 15560b57cec5SDimitry Andric // not require runtime registration to discover 15570b57cec5SDimitry Andric // named section start/end. 15580b57cec5SDimitry Andric if (needsRuntimeRegistrationOfSectionRange(TT)) 15590b57cec5SDimitry Andric return; 15600b57cec5SDimitry Andric 15610b57cec5SDimitry Andric size_t TotalNS = 0; 15620b57cec5SDimitry Andric for (auto &PD : ProfileDataMap) { 15630b57cec5SDimitry Andric for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 15640b57cec5SDimitry Andric TotalNS += PD.second.NumValueSites[Kind]; 15650b57cec5SDimitry Andric } 15660b57cec5SDimitry Andric 15670b57cec5SDimitry Andric if (!TotalNS) 15680b57cec5SDimitry Andric return; 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andric uint64_t NumCounters = TotalNS * NumCountersPerValueSite; 15710b57cec5SDimitry Andric // Heuristic for small programs with very few total value sites. 15720b57cec5SDimitry Andric // The default value of vp-counters-per-site is chosen based on 15730b57cec5SDimitry Andric // the observation that large apps usually have a low percentage 15740b57cec5SDimitry Andric // of value sites that actually have any profile data, and thus 15750b57cec5SDimitry Andric // the average number of counters per site is low. For small 15760b57cec5SDimitry Andric // apps with very few sites, this may not be true. Bump up the 15770b57cec5SDimitry Andric // number of counters in this case. 15780b57cec5SDimitry Andric #define INSTR_PROF_MIN_VAL_COUNTS 10 15790b57cec5SDimitry Andric if (NumCounters < INSTR_PROF_MIN_VAL_COUNTS) 15800b57cec5SDimitry Andric NumCounters = std::max(INSTR_PROF_MIN_VAL_COUNTS, (int)NumCounters * 2); 15810b57cec5SDimitry Andric 1582*c9157d92SDimitry Andric auto &Ctx = M.getContext(); 15830b57cec5SDimitry Andric Type *VNodeTypes[] = { 15840b57cec5SDimitry Andric #define INSTR_PROF_VALUE_NODE(Type, LLVMType, Name, Init) LLVMType, 15850b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProfData.inc" 15860b57cec5SDimitry Andric }; 1587bdd1243dSDimitry Andric auto *VNodeTy = StructType::get(Ctx, ArrayRef(VNodeTypes)); 15880b57cec5SDimitry Andric 15890b57cec5SDimitry Andric ArrayType *VNodesTy = ArrayType::get(VNodeTy, NumCounters); 15900b57cec5SDimitry Andric auto *VNodesVar = new GlobalVariable( 1591*c9157d92SDimitry Andric M, VNodesTy, false, GlobalValue::PrivateLinkage, 15920b57cec5SDimitry Andric Constant::getNullValue(VNodesTy), getInstrProfVNodesVarName()); 1593*c9157d92SDimitry Andric setGlobalVariableLargeSection(TT, *VNodesVar); 15940b57cec5SDimitry Andric VNodesVar->setSection( 15950b57cec5SDimitry Andric getInstrProfSectionName(IPSK_vnodes, TT.getObjectFormat())); 1596*c9157d92SDimitry Andric VNodesVar->setAlignment(M.getDataLayout().getABITypeAlign(VNodesTy)); 1597fe6060f1SDimitry Andric // VNodesVar is used by runtime but not referenced via relocation by other 1598fe6060f1SDimitry Andric // sections. Conservatively make it linker retained. 15990b57cec5SDimitry Andric UsedVars.push_back(VNodesVar); 16000b57cec5SDimitry Andric } 16010b57cec5SDimitry Andric 1602*c9157d92SDimitry Andric void InstrLowerer::emitNameData() { 16030b57cec5SDimitry Andric std::string UncompressedData; 16040b57cec5SDimitry Andric 16050b57cec5SDimitry Andric if (ReferencedNames.empty()) 16060b57cec5SDimitry Andric return; 16070b57cec5SDimitry Andric 16080b57cec5SDimitry Andric std::string CompressedNameStr; 16090b57cec5SDimitry Andric if (Error E = collectPGOFuncNameStrings(ReferencedNames, CompressedNameStr, 16105ffd83dbSDimitry Andric DoInstrProfNameCompression)) { 1611349cc55cSDimitry Andric report_fatal_error(Twine(toString(std::move(E))), false); 16120b57cec5SDimitry Andric } 16130b57cec5SDimitry Andric 1614*c9157d92SDimitry Andric auto &Ctx = M.getContext(); 16154824e7fdSDimitry Andric auto *NamesVal = 16164824e7fdSDimitry Andric ConstantDataArray::getString(Ctx, StringRef(CompressedNameStr), false); 1617*c9157d92SDimitry Andric NamesVar = new GlobalVariable(M, NamesVal->getType(), true, 16180b57cec5SDimitry Andric GlobalValue::PrivateLinkage, NamesVal, 16190b57cec5SDimitry Andric getInstrProfNamesVarName()); 16200b57cec5SDimitry Andric NamesSize = CompressedNameStr.size(); 1621*c9157d92SDimitry Andric setGlobalVariableLargeSection(TT, *NamesVar); 16220b57cec5SDimitry Andric NamesVar->setSection( 1623*c9157d92SDimitry Andric ProfileCorrelate == InstrProfCorrelator::BINARY 1624*c9157d92SDimitry Andric ? getInstrProfSectionName(IPSK_covname, TT.getObjectFormat()) 1625*c9157d92SDimitry Andric : getInstrProfSectionName(IPSK_name, TT.getObjectFormat())); 16260b57cec5SDimitry Andric // On COFF, it's important to reduce the alignment down to 1 to prevent the 16270b57cec5SDimitry Andric // linker from inserting padding before the start of the names section or 16280b57cec5SDimitry Andric // between names entries. 16295ffd83dbSDimitry Andric NamesVar->setAlignment(Align(1)); 1630fe6060f1SDimitry Andric // NamesVar is used by runtime but not referenced via relocation by other 1631fe6060f1SDimitry Andric // sections. Conservatively make it linker retained. 16320b57cec5SDimitry Andric UsedVars.push_back(NamesVar); 16330b57cec5SDimitry Andric 16340b57cec5SDimitry Andric for (auto *NamePtr : ReferencedNames) 16350b57cec5SDimitry Andric NamePtr->eraseFromParent(); 16360b57cec5SDimitry Andric } 16370b57cec5SDimitry Andric 1638*c9157d92SDimitry Andric void InstrLowerer::emitRegistration() { 16390b57cec5SDimitry Andric if (!needsRuntimeRegistrationOfSectionRange(TT)) 16400b57cec5SDimitry Andric return; 16410b57cec5SDimitry Andric 16420b57cec5SDimitry Andric // Construct the function. 1643*c9157d92SDimitry Andric auto *VoidTy = Type::getVoidTy(M.getContext()); 1644*c9157d92SDimitry Andric auto *VoidPtrTy = PointerType::getUnqual(M.getContext()); 1645*c9157d92SDimitry Andric auto *Int64Ty = Type::getInt64Ty(M.getContext()); 16460b57cec5SDimitry Andric auto *RegisterFTy = FunctionType::get(VoidTy, false); 16470b57cec5SDimitry Andric auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage, 16480b57cec5SDimitry Andric getInstrProfRegFuncsName(), M); 16490b57cec5SDimitry Andric RegisterF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 16500b57cec5SDimitry Andric if (Options.NoRedZone) 16510b57cec5SDimitry Andric RegisterF->addFnAttr(Attribute::NoRedZone); 16520b57cec5SDimitry Andric 16530b57cec5SDimitry Andric auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false); 16540b57cec5SDimitry Andric auto *RuntimeRegisterF = 16550b57cec5SDimitry Andric Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage, 16560b57cec5SDimitry Andric getInstrProfRegFuncName(), M); 16570b57cec5SDimitry Andric 1658*c9157d92SDimitry Andric IRBuilder<> IRB(BasicBlock::Create(M.getContext(), "", RegisterF)); 1659fe6060f1SDimitry Andric for (Value *Data : CompilerUsedVars) 1660fe6060f1SDimitry Andric if (!isa<Function>(Data)) 1661*c9157d92SDimitry Andric IRB.CreateCall(RuntimeRegisterF, Data); 16620b57cec5SDimitry Andric for (Value *Data : UsedVars) 16630b57cec5SDimitry Andric if (Data != NamesVar && !isa<Function>(Data)) 1664*c9157d92SDimitry Andric IRB.CreateCall(RuntimeRegisterF, Data); 16650b57cec5SDimitry Andric 16660b57cec5SDimitry Andric if (NamesVar) { 16670b57cec5SDimitry Andric Type *ParamTypes[] = {VoidPtrTy, Int64Ty}; 16680b57cec5SDimitry Andric auto *NamesRegisterTy = 1669bdd1243dSDimitry Andric FunctionType::get(VoidTy, ArrayRef(ParamTypes), false); 16700b57cec5SDimitry Andric auto *NamesRegisterF = 16710b57cec5SDimitry Andric Function::Create(NamesRegisterTy, GlobalVariable::ExternalLinkage, 16720b57cec5SDimitry Andric getInstrProfNamesRegFuncName(), M); 1673*c9157d92SDimitry Andric IRB.CreateCall(NamesRegisterF, {NamesVar, IRB.getInt64(NamesSize)}); 16740b57cec5SDimitry Andric } 16750b57cec5SDimitry Andric 16760b57cec5SDimitry Andric IRB.CreateRetVoid(); 16770b57cec5SDimitry Andric } 16780b57cec5SDimitry Andric 1679*c9157d92SDimitry Andric bool InstrLowerer::emitRuntimeHook() { 1680349cc55cSDimitry Andric // We expect the linker to be invoked with -u<hook_var> flag for Linux 1681349cc55cSDimitry Andric // in which case there is no need to emit the external variable. 1682bdd1243dSDimitry Andric if (TT.isOSLinux() || TT.isOSAIX()) 16830b57cec5SDimitry Andric return false; 16840b57cec5SDimitry Andric 16850b57cec5SDimitry Andric // If the module's provided its own runtime, we don't need to do anything. 1686*c9157d92SDimitry Andric if (M.getGlobalVariable(getInstrProfRuntimeHookVarName())) 16870b57cec5SDimitry Andric return false; 16880b57cec5SDimitry Andric 16890b57cec5SDimitry Andric // Declare an external variable that will pull in the runtime initialization. 1690*c9157d92SDimitry Andric auto *Int32Ty = Type::getInt32Ty(M.getContext()); 16910b57cec5SDimitry Andric auto *Var = 1692*c9157d92SDimitry Andric new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage, 16930b57cec5SDimitry Andric nullptr, getInstrProfRuntimeHookVarName()); 1694753f127fSDimitry Andric Var->setVisibility(GlobalValue::HiddenVisibility); 16950b57cec5SDimitry Andric 169681ad6265SDimitry Andric if (TT.isOSBinFormatELF() && !TT.isPS()) { 1697349cc55cSDimitry Andric // Mark the user variable as used so that it isn't stripped out. 1698349cc55cSDimitry Andric CompilerUsedVars.push_back(Var); 1699349cc55cSDimitry Andric } else { 17000b57cec5SDimitry Andric // Make a function that uses it. 17010b57cec5SDimitry Andric auto *User = Function::Create(FunctionType::get(Int32Ty, false), 17020b57cec5SDimitry Andric GlobalValue::LinkOnceODRLinkage, 17030b57cec5SDimitry Andric getInstrProfRuntimeHookVarUseFuncName(), M); 17040b57cec5SDimitry Andric User->addFnAttr(Attribute::NoInline); 17050b57cec5SDimitry Andric if (Options.NoRedZone) 17060b57cec5SDimitry Andric User->addFnAttr(Attribute::NoRedZone); 17070b57cec5SDimitry Andric User->setVisibility(GlobalValue::HiddenVisibility); 17080b57cec5SDimitry Andric if (TT.supportsCOMDAT()) 1709*c9157d92SDimitry Andric User->setComdat(M.getOrInsertComdat(User->getName())); 17100b57cec5SDimitry Andric 1711*c9157d92SDimitry Andric IRBuilder<> IRB(BasicBlock::Create(M.getContext(), "", User)); 17120b57cec5SDimitry Andric auto *Load = IRB.CreateLoad(Int32Ty, Var); 17130b57cec5SDimitry Andric IRB.CreateRet(Load); 17140b57cec5SDimitry Andric 1715349cc55cSDimitry Andric // Mark the function as used so that it isn't stripped out. 1716fe6060f1SDimitry Andric CompilerUsedVars.push_back(User); 1717349cc55cSDimitry Andric } 17180b57cec5SDimitry Andric return true; 17190b57cec5SDimitry Andric } 17200b57cec5SDimitry Andric 1721*c9157d92SDimitry Andric void InstrLowerer::emitUses() { 1722fe6060f1SDimitry Andric // The metadata sections are parallel arrays. Optimizers (e.g. 1723fe6060f1SDimitry Andric // GlobalOpt/ConstantMerge) may not discard associated sections as a unit, so 1724fe6060f1SDimitry Andric // we conservatively retain all unconditionally in the compiler. 1725fe6060f1SDimitry Andric // 1726349cc55cSDimitry Andric // On ELF and Mach-O, the linker can guarantee the associated sections will be 1727349cc55cSDimitry Andric // retained or discarded as a unit, so llvm.compiler.used is sufficient. 1728349cc55cSDimitry Andric // Similarly on COFF, if prof data is not referenced by code we use one comdat 1729349cc55cSDimitry Andric // and ensure this GC property as well. Otherwise, we have to conservatively 1730349cc55cSDimitry Andric // make all of the sections retained by the linker. 1731349cc55cSDimitry Andric if (TT.isOSBinFormatELF() || TT.isOSBinFormatMachO() || 1732*c9157d92SDimitry Andric (TT.isOSBinFormatCOFF() && !profDataReferencedByCode(M))) 1733*c9157d92SDimitry Andric appendToCompilerUsed(M, CompilerUsedVars); 1734fe6060f1SDimitry Andric else 1735*c9157d92SDimitry Andric appendToUsed(M, CompilerUsedVars); 1736fe6060f1SDimitry Andric 1737fe6060f1SDimitry Andric // We do not add proper references from used metadata sections to NamesVar and 1738fe6060f1SDimitry Andric // VNodesVar, so we have to be conservative and place them in llvm.used 1739fe6060f1SDimitry Andric // regardless of the target, 1740*c9157d92SDimitry Andric appendToUsed(M, UsedVars); 17410b57cec5SDimitry Andric } 17420b57cec5SDimitry Andric 1743*c9157d92SDimitry Andric void InstrLowerer::emitInitialization() { 17440b57cec5SDimitry Andric // Create ProfileFileName variable. Don't don't this for the 17450b57cec5SDimitry Andric // context-sensitive instrumentation lowering: This lowering is after 17460b57cec5SDimitry Andric // LTO/ThinLTO linking. Pass PGOInstrumentationGenCreateVar should 17470b57cec5SDimitry Andric // have already create the variable before LTO/ThinLTO linking. 17480b57cec5SDimitry Andric if (!IsCS) 1749*c9157d92SDimitry Andric createProfileFileNameVar(M, Options.InstrProfileOutput); 1750*c9157d92SDimitry Andric Function *RegisterF = M.getFunction(getInstrProfRegFuncsName()); 17510b57cec5SDimitry Andric if (!RegisterF) 17520b57cec5SDimitry Andric return; 17530b57cec5SDimitry Andric 17540b57cec5SDimitry Andric // Create the initialization function. 1755*c9157d92SDimitry Andric auto *VoidTy = Type::getVoidTy(M.getContext()); 17560b57cec5SDimitry Andric auto *F = Function::Create(FunctionType::get(VoidTy, false), 17570b57cec5SDimitry Andric GlobalValue::InternalLinkage, 17580b57cec5SDimitry Andric getInstrProfInitFuncName(), M); 17590b57cec5SDimitry Andric F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 17600b57cec5SDimitry Andric F->addFnAttr(Attribute::NoInline); 17610b57cec5SDimitry Andric if (Options.NoRedZone) 17620b57cec5SDimitry Andric F->addFnAttr(Attribute::NoRedZone); 17630b57cec5SDimitry Andric 17640b57cec5SDimitry Andric // Add the basic block and the necessary calls. 1765*c9157d92SDimitry Andric IRBuilder<> IRB(BasicBlock::Create(M.getContext(), "", F)); 17660b57cec5SDimitry Andric IRB.CreateCall(RegisterF, {}); 17670b57cec5SDimitry Andric IRB.CreateRetVoid(); 17680b57cec5SDimitry Andric 1769*c9157d92SDimitry Andric appendToGlobalCtors(M, F, 0); 17700b57cec5SDimitry Andric } 1771