161ba2e39SJustin Bogner //===-- InstrProfiling.cpp - Frontend instrumentation based profiling -----===// 261ba2e39SJustin Bogner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 661ba2e39SJustin Bogner // 761ba2e39SJustin Bogner //===----------------------------------------------------------------------===// 861ba2e39SJustin Bogner // 96fac1741SBetul Buyukkurt // This pass lowers instrprof_* intrinsics emitted by a frontend for profiling. 106fac1741SBetul Buyukkurt // It also builds the data structures and initialization code needed for 116fac1741SBetul Buyukkurt // updating execution counts and emitting the profile at runtime. 1261ba2e39SJustin Bogner // 1361ba2e39SJustin Bogner //===----------------------------------------------------------------------===// 1461ba2e39SJustin Bogner 154fe1fe14SDavid Blaikie #include "llvm/Transforms/Instrumentation/InstrProfiling.h" 1634c23279SEugene Zelenko #include "llvm/ADT/ArrayRef.h" 1734c23279SEugene Zelenko #include "llvm/ADT/SmallVector.h" 1834c23279SEugene Zelenko #include "llvm/ADT/StringRef.h" 1961ba2e39SJustin Bogner #include "llvm/ADT/Triple.h" 2034c23279SEugene Zelenko #include "llvm/ADT/Twine.h" 216cdf3d80SRong Xu #include "llvm/Analysis/BlockFrequencyInfo.h" 226cdf3d80SRong Xu #include "llvm/Analysis/BranchProbabilityInfo.h" 23b67530e9SXinliang David Li #include "llvm/Analysis/LoopInfo.h" 241c2bd1e9SMarcin Koscielnicki #include "llvm/Analysis/TargetLibraryInfo.h" 2534c23279SEugene Zelenko #include "llvm/IR/Attributes.h" 2634c23279SEugene Zelenko #include "llvm/IR/BasicBlock.h" 2734c23279SEugene Zelenko #include "llvm/IR/Constant.h" 2834c23279SEugene Zelenko #include "llvm/IR/Constants.h" 2934c23279SEugene Zelenko #include "llvm/IR/DerivedTypes.h" 30b67530e9SXinliang David Li #include "llvm/IR/Dominators.h" 3134c23279SEugene Zelenko #include "llvm/IR/Function.h" 3234c23279SEugene Zelenko #include "llvm/IR/GlobalValue.h" 3334c23279SEugene Zelenko #include "llvm/IR/GlobalVariable.h" 346bda14b3SChandler Carruth #include "llvm/IR/IRBuilder.h" 3534c23279SEugene Zelenko #include "llvm/IR/Instruction.h" 3634c23279SEugene Zelenko #include "llvm/IR/Instructions.h" 3761ba2e39SJustin Bogner #include "llvm/IR/IntrinsicInst.h" 3861ba2e39SJustin Bogner #include "llvm/IR/Module.h" 3934c23279SEugene Zelenko #include "llvm/IR/Type.h" 4005da2fe5SReid Kleckner #include "llvm/InitializePasses.h" 4134c23279SEugene Zelenko #include "llvm/Pass.h" 426fac1741SBetul Buyukkurt #include "llvm/ProfileData/InstrProf.h" 4334c23279SEugene Zelenko #include "llvm/Support/Casting.h" 4434c23279SEugene Zelenko #include "llvm/Support/CommandLine.h" 4534c23279SEugene Zelenko #include "llvm/Support/Error.h" 4634c23279SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 47b67530e9SXinliang David Li #include "llvm/Transforms/Utils/BasicBlockUtils.h" 4861ba2e39SJustin Bogner #include "llvm/Transforms/Utils/ModuleUtils.h" 49b67530e9SXinliang David Li #include "llvm/Transforms/Utils/SSAUpdater.h" 5034c23279SEugene Zelenko #include <algorithm> 5134c23279SEugene Zelenko #include <cassert> 5234c23279SEugene Zelenko #include <cstddef> 5334c23279SEugene Zelenko #include <cstdint> 5434c23279SEugene Zelenko #include <string> 5561ba2e39SJustin Bogner 5661ba2e39SJustin Bogner using namespace llvm; 5761ba2e39SJustin Bogner 5861ba2e39SJustin Bogner #define DEBUG_TYPE "instrprof" 5961ba2e39SJustin Bogner 6061ba2e39SJustin Bogner namespace { 6161ba2e39SJustin Bogner 6220f5df1dSRong Xu cl::opt<bool> DoHashBasedCounterSplit( 6320f5df1dSRong Xu "hash-based-counter-split", 6420f5df1dSRong Xu cl::desc("Rename counter variable of a comdat function based on cfg hash"), 6520f5df1dSRong Xu cl::init(true)); 6620f5df1dSRong Xu 67d3db13afSPetr Hosek cl::opt<bool> RuntimeCounterRelocation( 68d3db13afSPetr Hosek "runtime-counter-relocation", 69d3db13afSPetr Hosek cl::desc("Enable relocating counters at runtime."), 70d3db13afSPetr Hosek cl::init(false)); 71d3db13afSPetr Hosek 72b628dd35SXinliang David Li cl::opt<bool> ValueProfileStaticAlloc( 73b628dd35SXinliang David Li "vp-static-alloc", 74b628dd35SXinliang David Li cl::desc("Do static counter allocation for value profiler"), 75b628dd35SXinliang David Li cl::init(true)); 7634c23279SEugene Zelenko 77b628dd35SXinliang David Li cl::opt<double> NumCountersPerValueSite( 78b628dd35SXinliang David Li "vp-counters-per-site", 79b628dd35SXinliang David Li cl::desc("The average number of profile counters allocated " 80b628dd35SXinliang David Li "per value profiling site."), 81b628dd35SXinliang David Li // This is set to a very small value because in real programs, only 82b628dd35SXinliang David Li // a very small percentage of value sites have non-zero targets, e.g, 1/30. 83b628dd35SXinliang David Li // For those sites with non-zero profile, the average number of targets 84b628dd35SXinliang David Li // is usually smaller than 2. 85b628dd35SXinliang David Li cl::init(1.0)); 86b628dd35SXinliang David Li 87ee6c233aSVedant Kumar cl::opt<bool> AtomicCounterUpdateAll( 88ee6c233aSVedant Kumar "instrprof-atomic-counter-update-all", cl::ZeroOrMore, 89ee6c233aSVedant Kumar cl::desc("Make all profile counter updates atomic (for testing only)"), 90ee6c233aSVedant Kumar cl::init(false)); 91ee6c233aSVedant Kumar 92b67530e9SXinliang David Li cl::opt<bool> AtomicCounterUpdatePromoted( 93b67530e9SXinliang David Li "atomic-counter-update-promoted", cl::ZeroOrMore, 94b67530e9SXinliang David Li cl::desc("Do counter update using atomic fetch add " 95b67530e9SXinliang David Li " for promoted counters only"), 96b67530e9SXinliang David Li cl::init(false)); 97b67530e9SXinliang David Li 98b4bceb94SRong Xu cl::opt<bool> AtomicFirstCounter( 99b4bceb94SRong Xu "atomic-first-counter", cl::ZeroOrMore, 100b4bceb94SRong Xu cl::desc("Use atomic fetch add for first counter in a function (usually " 101b4bceb94SRong Xu "the entry counter)"), 102b4bceb94SRong Xu cl::init(false)); 103b4bceb94SRong Xu 104b67530e9SXinliang David Li // If the option is not specified, the default behavior about whether 105b67530e9SXinliang David Li // counter promotion is done depends on how instrumentaiton lowering 106b67530e9SXinliang David Li // pipeline is setup, i.e., the default value of true of this option 107b67530e9SXinliang David Li // does not mean the promotion will be done by default. Explicitly 108b67530e9SXinliang David Li // setting this option can override the default behavior. 109b67530e9SXinliang David Li cl::opt<bool> DoCounterPromotion("do-counter-promotion", cl::ZeroOrMore, 110b67530e9SXinliang David Li cl::desc("Do counter register promotion"), 111b67530e9SXinliang David Li cl::init(false)); 112b67530e9SXinliang David Li cl::opt<unsigned> MaxNumOfPromotionsPerLoop( 113f564c695SXinliang David Li cl::ZeroOrMore, "max-counter-promotions-per-loop", cl::init(20), 114b67530e9SXinliang David Li cl::desc("Max number counter promotions per loop to avoid" 115b67530e9SXinliang David Li " increasing register pressure too much")); 116b67530e9SXinliang David Li 117b67530e9SXinliang David Li // A debug option 118b67530e9SXinliang David Li cl::opt<int> 119b67530e9SXinliang David Li MaxNumOfPromotions(cl::ZeroOrMore, "max-counter-promotions", cl::init(-1), 120b67530e9SXinliang David Li cl::desc("Max number of allowed counter promotions")); 121b67530e9SXinliang David Li 122f564c695SXinliang David Li cl::opt<unsigned> SpeculativeCounterPromotionMaxExiting( 123f564c695SXinliang David Li cl::ZeroOrMore, "speculative-counter-promotion-max-exiting", cl::init(3), 124f564c695SXinliang David Li cl::desc("The max number of exiting blocks of a loop to allow " 125f564c695SXinliang David Li " speculative counter promotion")); 126f564c695SXinliang David Li 127f564c695SXinliang David Li cl::opt<bool> SpeculativeCounterPromotionToLoop( 128f564c695SXinliang David Li cl::ZeroOrMore, "speculative-counter-promotion-to-loop", cl::init(false), 129f564c695SXinliang David Li cl::desc("When the option is false, if the target block is in a loop, " 130f564c695SXinliang David Li "the promotion will be disallowed unless the promoted counter " 131f564c695SXinliang David Li " update can be further/iteratively promoted into an acyclic " 132f564c695SXinliang David Li " region.")); 133f564c695SXinliang David Li 134f564c695SXinliang David Li cl::opt<bool> IterativeCounterPromotion( 135f564c695SXinliang David Li cl::ZeroOrMore, "iterative-counter-promotion", cl::init(true), 136f564c695SXinliang David Li cl::desc("Allow counter promotion across the whole loop nest.")); 137b67530e9SXinliang David Li 13831bd15c5SRong Xu cl::opt<bool> SkipRetExitBlock( 13931bd15c5SRong Xu cl::ZeroOrMore, "skip-ret-exit-block", cl::init(true), 14031bd15c5SRong Xu cl::desc("Suppress counter promotion if exit blocks contain ret.")); 14131bd15c5SRong Xu 142e6b89294SXinliang David Li class InstrProfilingLegacyPass : public ModulePass { 143e6b89294SXinliang David Li InstrProfiling InstrProf; 144e6b89294SXinliang David Li 14561ba2e39SJustin Bogner public: 14661ba2e39SJustin Bogner static char ID; 14734c23279SEugene Zelenko 14834c23279SEugene Zelenko InstrProfilingLegacyPass() : ModulePass(ID) {} 1496cdf3d80SRong Xu InstrProfilingLegacyPass(const InstrProfOptions &Options, bool IsCS = false) 15073a9b7deSArthur Eubanks : ModulePass(ID), InstrProf(Options, IsCS) { 15173a9b7deSArthur Eubanks initializeInstrProfilingLegacyPassPass(*PassRegistry::getPassRegistry()); 15273a9b7deSArthur Eubanks } 15334c23279SEugene Zelenko 154117296c0SMehdi Amini StringRef getPassName() const override { 15561ba2e39SJustin Bogner return "Frontend instrumentation-based coverage lowering"; 15661ba2e39SJustin Bogner } 15761ba2e39SJustin Bogner 1581c2bd1e9SMarcin Koscielnicki bool runOnModule(Module &M) override { 1599c27b59cSTeresa Johnson auto GetTLI = [this](Function &F) -> TargetLibraryInfo & { 1609c27b59cSTeresa Johnson return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); 1619c27b59cSTeresa Johnson }; 1629c27b59cSTeresa Johnson return InstrProf.run(M, GetTLI); 1631c2bd1e9SMarcin Koscielnicki } 16461ba2e39SJustin Bogner 16561ba2e39SJustin Bogner void getAnalysisUsage(AnalysisUsage &AU) const override { 16661ba2e39SJustin Bogner AU.setPreservesCFG(); 1671c2bd1e9SMarcin Koscielnicki AU.addRequired<TargetLibraryInfoWrapperPass>(); 16861ba2e39SJustin Bogner } 16961ba2e39SJustin Bogner }; 17061ba2e39SJustin Bogner 171f564c695SXinliang David Li /// 172b67530e9SXinliang David Li /// A helper class to promote one counter RMW operation in the loop 173b67530e9SXinliang David Li /// into register update. 174b67530e9SXinliang David Li /// 175b67530e9SXinliang David Li /// RWM update for the counter will be sinked out of the loop after 176b67530e9SXinliang David Li /// the transformation. 177b67530e9SXinliang David Li /// 178b67530e9SXinliang David Li class PGOCounterPromoterHelper : public LoadAndStorePromoter { 179b67530e9SXinliang David Li public: 180f564c695SXinliang David Li PGOCounterPromoterHelper( 181f564c695SXinliang David Li Instruction *L, Instruction *S, SSAUpdater &SSA, Value *Init, 182f564c695SXinliang David Li BasicBlock *PH, ArrayRef<BasicBlock *> ExitBlocks, 183f564c695SXinliang David Li ArrayRef<Instruction *> InsertPts, 184f564c695SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCands, 185f564c695SXinliang David Li LoopInfo &LI) 186b67530e9SXinliang David Li : LoadAndStorePromoter({L, S}, SSA), Store(S), ExitBlocks(ExitBlocks), 187f564c695SXinliang David Li InsertPts(InsertPts), LoopToCandidates(LoopToCands), LI(LI) { 188b67530e9SXinliang David Li assert(isa<LoadInst>(L)); 189b67530e9SXinliang David Li assert(isa<StoreInst>(S)); 190b67530e9SXinliang David Li SSA.AddAvailableValue(PH, Init); 191b67530e9SXinliang David Li } 192f564c695SXinliang David Li 1936cba96edSAlina Sbirlea void doExtraRewritesBeforeFinalDeletion() override { 194b67530e9SXinliang David Li for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { 195b67530e9SXinliang David Li BasicBlock *ExitBlock = ExitBlocks[i]; 196b67530e9SXinliang David Li Instruction *InsertPos = InsertPts[i]; 197b67530e9SXinliang David Li // Get LiveIn value into the ExitBlock. If there are multiple 198b67530e9SXinliang David Li // predecessors, the value is defined by a PHI node in this 199b67530e9SXinliang David Li // block. 200b67530e9SXinliang David Li Value *LiveInValue = SSA.GetValueInMiddleOfBlock(ExitBlock); 201b67530e9SXinliang David Li Value *Addr = cast<StoreInst>(Store)->getPointerOperand(); 20214359ef1SJames Y Knight Type *Ty = LiveInValue->getType(); 203b67530e9SXinliang David Li IRBuilder<> Builder(InsertPos); 204b67530e9SXinliang David Li if (AtomicCounterUpdatePromoted) 205f564c695SXinliang David Li // automic update currently can only be promoted across the current 206f564c695SXinliang David Li // loop, not the whole loop nest. 207b67530e9SXinliang David Li Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, LiveInValue, 20824539f1eSJames Y Knight MaybeAlign(), 209b67530e9SXinliang David Li AtomicOrdering::SequentiallyConsistent); 210b67530e9SXinliang David Li else { 21114359ef1SJames Y Knight LoadInst *OldVal = Builder.CreateLoad(Ty, Addr, "pgocount.promoted"); 212b67530e9SXinliang David Li auto *NewVal = Builder.CreateAdd(OldVal, LiveInValue); 213f564c695SXinliang David Li auto *NewStore = Builder.CreateStore(NewVal, Addr); 214f564c695SXinliang David Li 215f564c695SXinliang David Li // Now update the parent loop's candidate list: 216f564c695SXinliang David Li if (IterativeCounterPromotion) { 217f564c695SXinliang David Li auto *TargetLoop = LI.getLoopFor(ExitBlock); 218f564c695SXinliang David Li if (TargetLoop) 219f564c695SXinliang David Li LoopToCandidates[TargetLoop].emplace_back(OldVal, NewStore); 220f564c695SXinliang David Li } 221b67530e9SXinliang David Li } 222b67530e9SXinliang David Li } 223b67530e9SXinliang David Li } 224b67530e9SXinliang David Li 225b67530e9SXinliang David Li private: 226b67530e9SXinliang David Li Instruction *Store; 227b67530e9SXinliang David Li ArrayRef<BasicBlock *> ExitBlocks; 228b67530e9SXinliang David Li ArrayRef<Instruction *> InsertPts; 229f564c695SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCandidates; 230f564c695SXinliang David Li LoopInfo &LI; 231b67530e9SXinliang David Li }; 232b67530e9SXinliang David Li 233b67530e9SXinliang David Li /// A helper class to do register promotion for all profile counter 234b67530e9SXinliang David Li /// updates in a loop. 235b67530e9SXinliang David Li /// 236b67530e9SXinliang David Li class PGOCounterPromoter { 237b67530e9SXinliang David Li public: 238f564c695SXinliang David Li PGOCounterPromoter( 239f564c695SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCands, 2406cdf3d80SRong Xu Loop &CurLoop, LoopInfo &LI, BlockFrequencyInfo *BFI) 241f564c695SXinliang David Li : LoopToCandidates(LoopToCands), ExitBlocks(), InsertPts(), L(CurLoop), 2426cdf3d80SRong Xu LI(LI), BFI(BFI) { 243b67530e9SXinliang David Li 244a33accdeSAndy Kaylor // Skip collection of ExitBlocks and InsertPts for loops that will not be 245a33accdeSAndy Kaylor // able to have counters promoted. 246b67530e9SXinliang David Li SmallVector<BasicBlock *, 8> LoopExitBlocks; 247b67530e9SXinliang David Li SmallPtrSet<BasicBlock *, 8> BlockSet; 248a33accdeSAndy Kaylor 249f564c695SXinliang David Li L.getExitBlocks(LoopExitBlocks); 250a33accdeSAndy Kaylor if (!isPromotionPossible(&L, LoopExitBlocks)) 251a33accdeSAndy Kaylor return; 252b67530e9SXinliang David Li 253b67530e9SXinliang David Li for (BasicBlock *ExitBlock : LoopExitBlocks) { 254b67530e9SXinliang David Li if (BlockSet.insert(ExitBlock).second) { 255b67530e9SXinliang David Li ExitBlocks.push_back(ExitBlock); 256b67530e9SXinliang David Li InsertPts.push_back(&*ExitBlock->getFirstInsertionPt()); 257b67530e9SXinliang David Li } 258b67530e9SXinliang David Li } 259b67530e9SXinliang David Li } 260b67530e9SXinliang David Li 261b67530e9SXinliang David Li bool run(int64_t *NumPromoted) { 262c23d2c68SXinliang David Li // Skip 'infinite' loops: 263c23d2c68SXinliang David Li if (ExitBlocks.size() == 0) 264c23d2c68SXinliang David Li return false; 26531bd15c5SRong Xu 26631bd15c5SRong Xu // Skip if any of the ExitBlocks contains a ret instruction. 26731bd15c5SRong Xu // This is to prevent dumping of incomplete profile -- if the 26831bd15c5SRong Xu // the loop is a long running loop and dump is called in the middle 26931bd15c5SRong Xu // of the loop, the result profile is incomplete. 27031bd15c5SRong Xu // FIXME: add other heuristics to detect long running loops. 27131bd15c5SRong Xu if (SkipRetExitBlock) { 27231bd15c5SRong Xu for (auto BB : ExitBlocks) 27395ea8658SKazu Hirata if (isa<ReturnInst>(BB->getTerminator())) 27431bd15c5SRong Xu return false; 27531bd15c5SRong Xu } 27631bd15c5SRong Xu 277f564c695SXinliang David Li unsigned MaxProm = getMaxNumOfPromotionsInLoop(&L); 278f564c695SXinliang David Li if (MaxProm == 0) 279b67530e9SXinliang David Li return false; 280b67530e9SXinliang David Li 281b67530e9SXinliang David Li unsigned Promoted = 0; 282f564c695SXinliang David Li for (auto &Cand : LoopToCandidates[&L]) { 283b67530e9SXinliang David Li 284b67530e9SXinliang David Li SmallVector<PHINode *, 4> NewPHIs; 285b67530e9SXinliang David Li SSAUpdater SSA(&NewPHIs); 286b67530e9SXinliang David Li Value *InitVal = ConstantInt::get(Cand.first->getType(), 0); 287f564c695SXinliang David Li 2886cdf3d80SRong Xu // If BFI is set, we will use it to guide the promotions. 2896cdf3d80SRong Xu if (BFI) { 2906cdf3d80SRong Xu auto *BB = Cand.first->getParent(); 2916cdf3d80SRong Xu auto InstrCount = BFI->getBlockProfileCount(BB); 2926cdf3d80SRong Xu if (!InstrCount) 2936cdf3d80SRong Xu continue; 2946cdf3d80SRong Xu auto PreheaderCount = BFI->getBlockProfileCount(L.getLoopPreheader()); 2956cdf3d80SRong Xu // If the average loop trip count is not greater than 1.5, we skip 2966cdf3d80SRong Xu // promotion. 2976cdf3d80SRong Xu if (PreheaderCount && 2986cdf3d80SRong Xu (PreheaderCount.getValue() * 3) >= (InstrCount.getValue() * 2)) 2996cdf3d80SRong Xu continue; 3006cdf3d80SRong Xu } 3016cdf3d80SRong Xu 302b67530e9SXinliang David Li PGOCounterPromoterHelper Promoter(Cand.first, Cand.second, SSA, InitVal, 303f564c695SXinliang David Li L.getLoopPreheader(), ExitBlocks, 304f564c695SXinliang David Li InsertPts, LoopToCandidates, LI); 305b67530e9SXinliang David Li Promoter.run(SmallVector<Instruction *, 2>({Cand.first, Cand.second})); 306b67530e9SXinliang David Li Promoted++; 307f564c695SXinliang David Li if (Promoted >= MaxProm) 308b67530e9SXinliang David Li break; 309f564c695SXinliang David Li 310b67530e9SXinliang David Li (*NumPromoted)++; 311b67530e9SXinliang David Li if (MaxNumOfPromotions != -1 && *NumPromoted >= MaxNumOfPromotions) 312b67530e9SXinliang David Li break; 313b67530e9SXinliang David Li } 314b67530e9SXinliang David Li 315d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << Promoted << " counters promoted for loop (depth=" 316f564c695SXinliang David Li << L.getLoopDepth() << ")\n"); 317b67530e9SXinliang David Li return Promoted != 0; 318b67530e9SXinliang David Li } 319b67530e9SXinliang David Li 320b67530e9SXinliang David Li private: 321f564c695SXinliang David Li bool allowSpeculativeCounterPromotion(Loop *LP) { 322f564c695SXinliang David Li SmallVector<BasicBlock *, 8> ExitingBlocks; 323f564c695SXinliang David Li L.getExitingBlocks(ExitingBlocks); 324f564c695SXinliang David Li // Not considierered speculative. 325f564c695SXinliang David Li if (ExitingBlocks.size() == 1) 326f564c695SXinliang David Li return true; 327f564c695SXinliang David Li if (ExitingBlocks.size() > SpeculativeCounterPromotionMaxExiting) 328f564c695SXinliang David Li return false; 329f564c695SXinliang David Li return true; 330f564c695SXinliang David Li } 331f564c695SXinliang David Li 332a33accdeSAndy Kaylor // Check whether the loop satisfies the basic conditions needed to perform 333a33accdeSAndy Kaylor // Counter Promotions. 334a33accdeSAndy Kaylor bool isPromotionPossible(Loop *LP, 335a33accdeSAndy Kaylor const SmallVectorImpl<BasicBlock *> &LoopExitBlocks) { 336f564c695SXinliang David Li // We can't insert into a catchswitch. 337f564c695SXinliang David Li if (llvm::any_of(LoopExitBlocks, [](BasicBlock *Exit) { 338f564c695SXinliang David Li return isa<CatchSwitchInst>(Exit->getTerminator()); 339f564c695SXinliang David Li })) 340a33accdeSAndy Kaylor return false; 341f564c695SXinliang David Li 342f564c695SXinliang David Li if (!LP->hasDedicatedExits()) 343a33accdeSAndy Kaylor return false; 344f564c695SXinliang David Li 345f564c695SXinliang David Li BasicBlock *PH = LP->getLoopPreheader(); 346f564c695SXinliang David Li if (!PH) 347a33accdeSAndy Kaylor return false; 348a33accdeSAndy Kaylor 349a33accdeSAndy Kaylor return true; 350a33accdeSAndy Kaylor } 351a33accdeSAndy Kaylor 352a33accdeSAndy Kaylor // Returns the max number of Counter Promotions for LP. 353a33accdeSAndy Kaylor unsigned getMaxNumOfPromotionsInLoop(Loop *LP) { 354a33accdeSAndy Kaylor SmallVector<BasicBlock *, 8> LoopExitBlocks; 355a33accdeSAndy Kaylor LP->getExitBlocks(LoopExitBlocks); 356a33accdeSAndy Kaylor if (!isPromotionPossible(LP, LoopExitBlocks)) 357f564c695SXinliang David Li return 0; 358f564c695SXinliang David Li 359f564c695SXinliang David Li SmallVector<BasicBlock *, 8> ExitingBlocks; 360f564c695SXinliang David Li LP->getExitingBlocks(ExitingBlocks); 3616cdf3d80SRong Xu 3626cdf3d80SRong Xu // If BFI is set, we do more aggressive promotions based on BFI. 3636cdf3d80SRong Xu if (BFI) 3646cdf3d80SRong Xu return (unsigned)-1; 3656cdf3d80SRong Xu 366f564c695SXinliang David Li // Not considierered speculative. 367f564c695SXinliang David Li if (ExitingBlocks.size() == 1) 368f564c695SXinliang David Li return MaxNumOfPromotionsPerLoop; 369f564c695SXinliang David Li 370f564c695SXinliang David Li if (ExitingBlocks.size() > SpeculativeCounterPromotionMaxExiting) 371f564c695SXinliang David Li return 0; 372f564c695SXinliang David Li 373f564c695SXinliang David Li // Whether the target block is in a loop does not matter: 374f564c695SXinliang David Li if (SpeculativeCounterPromotionToLoop) 375f564c695SXinliang David Li return MaxNumOfPromotionsPerLoop; 376f564c695SXinliang David Li 377f564c695SXinliang David Li // Now check the target block: 378f564c695SXinliang David Li unsigned MaxProm = MaxNumOfPromotionsPerLoop; 379f564c695SXinliang David Li for (auto *TargetBlock : LoopExitBlocks) { 380f564c695SXinliang David Li auto *TargetLoop = LI.getLoopFor(TargetBlock); 381f564c695SXinliang David Li if (!TargetLoop) 382f564c695SXinliang David Li continue; 383f564c695SXinliang David Li unsigned MaxPromForTarget = getMaxNumOfPromotionsInLoop(TargetLoop); 384f564c695SXinliang David Li unsigned PendingCandsInTarget = LoopToCandidates[TargetLoop].size(); 385f564c695SXinliang David Li MaxProm = 386f564c695SXinliang David Li std::min(MaxProm, std::max(MaxPromForTarget, PendingCandsInTarget) - 387f564c695SXinliang David Li PendingCandsInTarget); 388f564c695SXinliang David Li } 389f564c695SXinliang David Li return MaxProm; 390f564c695SXinliang David Li } 391f564c695SXinliang David Li 392f564c695SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCandidates; 393b67530e9SXinliang David Li SmallVector<BasicBlock *, 8> ExitBlocks; 394b67530e9SXinliang David Li SmallVector<Instruction *, 8> InsertPts; 395f564c695SXinliang David Li Loop &L; 396f564c695SXinliang David Li LoopInfo &LI; 3976cdf3d80SRong Xu BlockFrequencyInfo *BFI; 398b67530e9SXinliang David Li }; 399b67530e9SXinliang David Li 400f78f509cSHiroshi Yamauchi enum class ValueProfilingCallType { 401f78f509cSHiroshi Yamauchi // Individual values are tracked. Currently used for indiret call target 402f78f509cSHiroshi Yamauchi // profiling. 403f78f509cSHiroshi Yamauchi Default, 404f78f509cSHiroshi Yamauchi 4051ebee7adSHiroshi Yamauchi // MemOp: the memop size value profiling. 406f78f509cSHiroshi Yamauchi MemOp 407f78f509cSHiroshi Yamauchi }; 408f78f509cSHiroshi Yamauchi 40934c23279SEugene Zelenko } // end anonymous namespace 41061ba2e39SJustin Bogner 411fd03ac6aSSean Silva PreservedAnalyses InstrProfiling::run(Module &M, ModuleAnalysisManager &AM) { 4129c27b59cSTeresa Johnson FunctionAnalysisManager &FAM = 4139c27b59cSTeresa Johnson AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 4149c27b59cSTeresa Johnson auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { 4159c27b59cSTeresa Johnson return FAM.getResult<TargetLibraryAnalysis>(F); 4169c27b59cSTeresa Johnson }; 4179c27b59cSTeresa Johnson if (!run(M, GetTLI)) 418e6b89294SXinliang David Li return PreservedAnalyses::all(); 419e6b89294SXinliang David Li 420e6b89294SXinliang David Li return PreservedAnalyses::none(); 421e6b89294SXinliang David Li } 422e6b89294SXinliang David Li 423e6b89294SXinliang David Li char InstrProfilingLegacyPass::ID = 0; 4241c2bd1e9SMarcin Koscielnicki INITIALIZE_PASS_BEGIN( 4251c2bd1e9SMarcin Koscielnicki InstrProfilingLegacyPass, "instrprof", 4261c2bd1e9SMarcin Koscielnicki "Frontend instrumentation-based coverage lowering.", false, false) 4271c2bd1e9SMarcin Koscielnicki INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 4281c2bd1e9SMarcin Koscielnicki INITIALIZE_PASS_END( 4291c2bd1e9SMarcin Koscielnicki InstrProfilingLegacyPass, "instrprof", 4301c2bd1e9SMarcin Koscielnicki "Frontend instrumentation-based coverage lowering.", false, false) 43161ba2e39SJustin Bogner 43269a00f06SXinliang David Li ModulePass * 4336cdf3d80SRong Xu llvm::createInstrProfilingLegacyPass(const InstrProfOptions &Options, 4346cdf3d80SRong Xu bool IsCS) { 4356cdf3d80SRong Xu return new InstrProfilingLegacyPass(Options, IsCS); 43661ba2e39SJustin Bogner } 43761ba2e39SJustin Bogner 4384ca1733aSXinliang David Li static InstrProfIncrementInst *castToIncrementInst(Instruction *Instr) { 4394ca1733aSXinliang David Li InstrProfIncrementInst *Inc = dyn_cast<InstrProfIncrementInstStep>(Instr); 4404ca1733aSXinliang David Li if (Inc) 4414ca1733aSXinliang David Li return Inc; 4424ca1733aSXinliang David Li return dyn_cast<InstrProfIncrementInst>(Instr); 4434ca1733aSXinliang David Li } 4444ca1733aSXinliang David Li 445b67530e9SXinliang David Li bool InstrProfiling::lowerIntrinsics(Function *F) { 446b67530e9SXinliang David Li bool MadeChange = false; 447b67530e9SXinliang David Li PromotionCandidates.clear(); 448b67530e9SXinliang David Li for (BasicBlock &BB : *F) { 449*24c8eaecSKazu Hirata for (Instruction &Instr : llvm::make_early_inc_range(BB)) { 450*24c8eaecSKazu Hirata InstrProfIncrementInst *Inc = castToIncrementInst(&Instr); 451b67530e9SXinliang David Li if (Inc) { 452b67530e9SXinliang David Li lowerIncrement(Inc); 453b67530e9SXinliang David Li MadeChange = true; 454*24c8eaecSKazu Hirata } else if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(&Instr)) { 455b67530e9SXinliang David Li lowerValueProfileInst(Ind); 456b67530e9SXinliang David Li MadeChange = true; 457b67530e9SXinliang David Li } 458b67530e9SXinliang David Li } 459b67530e9SXinliang David Li } 460b67530e9SXinliang David Li 461b67530e9SXinliang David Li if (!MadeChange) 462b67530e9SXinliang David Li return false; 463b67530e9SXinliang David Li 464b67530e9SXinliang David Li promoteCounterLoadStores(F); 465b67530e9SXinliang David Li return true; 466b67530e9SXinliang David Li } 467b67530e9SXinliang David Li 468d3db13afSPetr Hosek bool InstrProfiling::isRuntimeCounterRelocationEnabled() const { 46954902e00SPetr Hosek // Mach-O don't support weak external references. 47054902e00SPetr Hosek if (TT.isOSBinFormatMachO()) 47154902e00SPetr Hosek return false; 47254902e00SPetr Hosek 473d3db13afSPetr Hosek if (RuntimeCounterRelocation.getNumOccurrences() > 0) 474d3db13afSPetr Hosek return RuntimeCounterRelocation; 475d3db13afSPetr Hosek 47654902e00SPetr Hosek // Fuchsia uses runtime counter relocation by default. 477d3db13afSPetr Hosek return TT.isOSFuchsia(); 478d3db13afSPetr Hosek } 479d3db13afSPetr Hosek 480b67530e9SXinliang David Li bool InstrProfiling::isCounterPromotionEnabled() const { 481b67530e9SXinliang David Li if (DoCounterPromotion.getNumOccurrences() > 0) 482b67530e9SXinliang David Li return DoCounterPromotion; 483b67530e9SXinliang David Li 484b67530e9SXinliang David Li return Options.DoCounterPromotion; 485b67530e9SXinliang David Li } 486b67530e9SXinliang David Li 487b67530e9SXinliang David Li void InstrProfiling::promoteCounterLoadStores(Function *F) { 488b67530e9SXinliang David Li if (!isCounterPromotionEnabled()) 489b67530e9SXinliang David Li return; 490b67530e9SXinliang David Li 491b67530e9SXinliang David Li DominatorTree DT(*F); 492b67530e9SXinliang David Li LoopInfo LI(DT); 493b67530e9SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> LoopPromotionCandidates; 494b67530e9SXinliang David Li 4956cdf3d80SRong Xu std::unique_ptr<BlockFrequencyInfo> BFI; 4966cdf3d80SRong Xu if (Options.UseBFIInPromotion) { 4976cdf3d80SRong Xu std::unique_ptr<BranchProbabilityInfo> BPI; 4989c27b59cSTeresa Johnson BPI.reset(new BranchProbabilityInfo(*F, LI, &GetTLI(*F))); 4996cdf3d80SRong Xu BFI.reset(new BlockFrequencyInfo(*F, *BPI, LI)); 5006cdf3d80SRong Xu } 5016cdf3d80SRong Xu 502b67530e9SXinliang David Li for (const auto &LoadStore : PromotionCandidates) { 503b67530e9SXinliang David Li auto *CounterLoad = LoadStore.first; 504b67530e9SXinliang David Li auto *CounterStore = LoadStore.second; 505b67530e9SXinliang David Li BasicBlock *BB = CounterLoad->getParent(); 506b67530e9SXinliang David Li Loop *ParentLoop = LI.getLoopFor(BB); 507b67530e9SXinliang David Li if (!ParentLoop) 508b67530e9SXinliang David Li continue; 509b67530e9SXinliang David Li LoopPromotionCandidates[ParentLoop].emplace_back(CounterLoad, CounterStore); 510b67530e9SXinliang David Li } 511b67530e9SXinliang David Li 512b67530e9SXinliang David Li SmallVector<Loop *, 4> Loops = LI.getLoopsInPreorder(); 513b67530e9SXinliang David Li 514f564c695SXinliang David Li // Do a post-order traversal of the loops so that counter updates can be 515f564c695SXinliang David Li // iteratively hoisted outside the loop nest. 516f564c695SXinliang David Li for (auto *Loop : llvm::reverse(Loops)) { 5176cdf3d80SRong Xu PGOCounterPromoter Promoter(LoopPromotionCandidates, *Loop, LI, BFI.get()); 518b67530e9SXinliang David Li Promoter.run(&TotalCountersPromoted); 519b67530e9SXinliang David Li } 520b67530e9SXinliang David Li } 521b67530e9SXinliang David Li 522389dc94dSPetr Hosek static bool needsRuntimeHookUnconditionally(const Triple &TT) { 523389dc94dSPetr Hosek // On Fuchsia, we only need runtime hook if any counters are present. 524389dc94dSPetr Hosek if (TT.isOSFuchsia()) 525389dc94dSPetr Hosek return false; 526389dc94dSPetr Hosek 527389dc94dSPetr Hosek return true; 528389dc94dSPetr Hosek } 529389dc94dSPetr Hosek 5301ee511c1SVedant Kumar /// Check if the module contains uses of any profiling intrinsics. 5311ee511c1SVedant Kumar static bool containsProfilingIntrinsics(Module &M) { 5321ee511c1SVedant Kumar if (auto *F = M.getFunction( 5331ee511c1SVedant Kumar Intrinsic::getName(llvm::Intrinsic::instrprof_increment))) 534cff94627SVedant Kumar if (!F->use_empty()) 535cff94627SVedant Kumar return true; 5361ee511c1SVedant Kumar if (auto *F = M.getFunction( 5371ee511c1SVedant Kumar Intrinsic::getName(llvm::Intrinsic::instrprof_increment_step))) 538cff94627SVedant Kumar if (!F->use_empty()) 539cff94627SVedant Kumar return true; 5401ee511c1SVedant Kumar if (auto *F = M.getFunction( 5411ee511c1SVedant Kumar Intrinsic::getName(llvm::Intrinsic::instrprof_value_profile))) 542cff94627SVedant Kumar if (!F->use_empty()) 543cff94627SVedant Kumar return true; 5441ee511c1SVedant Kumar return false; 5451ee511c1SVedant Kumar } 5461ee511c1SVedant Kumar 5479c27b59cSTeresa Johnson bool InstrProfiling::run( 5489c27b59cSTeresa Johnson Module &M, std::function<const TargetLibraryInfo &(Function &F)> GetTLI) { 54961ba2e39SJustin Bogner this->M = &M; 5509c27b59cSTeresa Johnson this->GetTLI = std::move(GetTLI); 551a82d6c0aSXinliang David Li NamesVar = nullptr; 552a82d6c0aSXinliang David Li NamesSize = 0; 5536fac1741SBetul Buyukkurt ProfileDataMap.clear(); 554a84f4fc0SFangrui Song CompilerUsedVars.clear(); 55561ba2e39SJustin Bogner UsedVars.clear(); 5561a6a2b64SVedant Kumar TT = Triple(M.getTargetTriple()); 55761ba2e39SJustin Bogner 5581c841671SPetr Hosek bool MadeChange = false; 559389dc94dSPetr Hosek 560f50aef74SHans Wennborg // Emit the runtime hook even if no counters are present. 561389dc94dSPetr Hosek if (needsRuntimeHookUnconditionally(TT)) 562389dc94dSPetr Hosek MadeChange = emitRuntimeHook(); 5639a041a75SVedant Kumar 5649a041a75SVedant Kumar // Improve compile time by avoiding linear scans when there is no work. 5659a041a75SVedant Kumar GlobalVariable *CoverageNamesVar = 5669a041a75SVedant Kumar M.getNamedGlobal(getCoverageUnusedNamesVarName()); 5679a041a75SVedant Kumar if (!containsProfilingIntrinsics(M) && !CoverageNamesVar) 5689a041a75SVedant Kumar return MadeChange; 5699a041a75SVedant Kumar 5706fac1741SBetul Buyukkurt // We did not know how many value sites there would be inside 5716fac1741SBetul Buyukkurt // the instrumented function. This is counting the number of instrumented 5726fac1741SBetul Buyukkurt // target value sites to enter it as field in the profile data variable. 573294572f1SRong Xu for (Function &F : M) { 574294572f1SRong Xu InstrProfIncrementInst *FirstProfIncInst = nullptr; 57561ba2e39SJustin Bogner for (BasicBlock &BB : F) 576294572f1SRong Xu for (auto I = BB.begin(), E = BB.end(); I != E; I++) 577294572f1SRong Xu if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(I)) 5786fac1741SBetul Buyukkurt computeNumValueSiteCounts(Ind); 579294572f1SRong Xu else if (FirstProfIncInst == nullptr) 580294572f1SRong Xu FirstProfIncInst = dyn_cast<InstrProfIncrementInst>(I); 581294572f1SRong Xu 582294572f1SRong Xu // Value profiling intrinsic lowering requires per-function profile data 583294572f1SRong Xu // variable to be created first. 584294572f1SRong Xu if (FirstProfIncInst != nullptr) 585294572f1SRong Xu static_cast<void>(getOrCreateRegionCounters(FirstProfIncInst)); 586294572f1SRong Xu } 5876fac1741SBetul Buyukkurt 5886fac1741SBetul Buyukkurt for (Function &F : M) 589b67530e9SXinliang David Li MadeChange |= lowerIntrinsics(&F); 5906fac1741SBetul Buyukkurt 5911ee511c1SVedant Kumar if (CoverageNamesVar) { 59281056077SXinliang David Li lowerCoverageData(CoverageNamesVar); 593d24e1857SJustin Bogner MadeChange = true; 594d24e1857SJustin Bogner } 5956fac1741SBetul Buyukkurt 59661ba2e39SJustin Bogner if (!MadeChange) 59761ba2e39SJustin Bogner return false; 59861ba2e39SJustin Bogner 599b628dd35SXinliang David Li emitVNodes(); 600a82d6c0aSXinliang David Li emitNameData(); 601389dc94dSPetr Hosek emitRuntimeHook(); 60261ba2e39SJustin Bogner emitRegistration(); 60361ba2e39SJustin Bogner emitUses(); 60461ba2e39SJustin Bogner emitInitialization(); 60561ba2e39SJustin Bogner return true; 60661ba2e39SJustin Bogner } 60761ba2e39SJustin Bogner 608f78f509cSHiroshi Yamauchi static FunctionCallee getOrInsertValueProfilingCall( 609f78f509cSHiroshi Yamauchi Module &M, const TargetLibraryInfo &TLI, 610f78f509cSHiroshi Yamauchi ValueProfilingCallType CallType = ValueProfilingCallType::Default) { 611c7673239SXinliang David Li LLVMContext &Ctx = M.getContext(); 612c7673239SXinliang David Li auto *ReturnTy = Type::getVoidTy(M.getContext()); 61360faea19SRong Xu 61413680223SJames Y Knight AttributeList AL; 61513680223SJames Y Knight if (auto AK = TLI.getExtAttrForI32Param(false)) 61613680223SJames Y Knight AL = AL.addParamAttribute(M.getContext(), 2, AK); 61713680223SJames Y Knight 6181ebee7adSHiroshi Yamauchi assert((CallType == ValueProfilingCallType::Default || 6191ebee7adSHiroshi Yamauchi CallType == ValueProfilingCallType::MemOp) && 6201ebee7adSHiroshi Yamauchi "Must be Default or MemOp"); 621c7673239SXinliang David Li Type *ParamTypes[] = { 622c7673239SXinliang David Li #define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType 623c7673239SXinliang David Li #include "llvm/ProfileData/InstrProfData.inc" 624c7673239SXinliang David Li }; 6256fac1741SBetul Buyukkurt auto *ValueProfilingCallTy = 626c7673239SXinliang David Li FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false); 627f78f509cSHiroshi Yamauchi StringRef FuncName = CallType == ValueProfilingCallType::Default 628f78f509cSHiroshi Yamauchi ? getInstrProfValueProfFuncName() 629f78f509cSHiroshi Yamauchi : getInstrProfValueProfMemOpFuncName(); 630f78f509cSHiroshi Yamauchi return M.getOrInsertFunction(FuncName, ValueProfilingCallTy, AL); 6316fac1741SBetul Buyukkurt } 6326fac1741SBetul Buyukkurt 6336fac1741SBetul Buyukkurt void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) { 6346fac1741SBetul Buyukkurt GlobalVariable *Name = Ind->getName(); 6356fac1741SBetul Buyukkurt uint64_t ValueKind = Ind->getValueKind()->getZExtValue(); 6366fac1741SBetul Buyukkurt uint64_t Index = Ind->getIndex()->getZExtValue(); 6376fac1741SBetul Buyukkurt auto It = ProfileDataMap.find(Name); 6386fac1741SBetul Buyukkurt if (It == ProfileDataMap.end()) { 6396fac1741SBetul Buyukkurt PerFunctionProfileData PD; 6406fac1741SBetul Buyukkurt PD.NumValueSites[ValueKind] = Index + 1; 6416fac1741SBetul Buyukkurt ProfileDataMap[Name] = PD; 6426fac1741SBetul Buyukkurt } else if (It->second.NumValueSites[ValueKind] <= Index) 6436fac1741SBetul Buyukkurt It->second.NumValueSites[ValueKind] = Index + 1; 6446fac1741SBetul Buyukkurt } 6456fac1741SBetul Buyukkurt 6466fac1741SBetul Buyukkurt void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) { 6476fac1741SBetul Buyukkurt GlobalVariable *Name = Ind->getName(); 6486fac1741SBetul Buyukkurt auto It = ProfileDataMap.find(Name); 6496fac1741SBetul Buyukkurt assert(It != ProfileDataMap.end() && It->second.DataVar && 6506fac1741SBetul Buyukkurt "value profiling detected in function with no counter incerement"); 6516fac1741SBetul Buyukkurt 6526fac1741SBetul Buyukkurt GlobalVariable *DataVar = It->second.DataVar; 6536fac1741SBetul Buyukkurt uint64_t ValueKind = Ind->getValueKind()->getZExtValue(); 6546fac1741SBetul Buyukkurt uint64_t Index = Ind->getIndex()->getZExtValue(); 6556fac1741SBetul Buyukkurt for (uint32_t Kind = IPVK_First; Kind < ValueKind; ++Kind) 6566fac1741SBetul Buyukkurt Index += It->second.NumValueSites[Kind]; 6576fac1741SBetul Buyukkurt 6586fac1741SBetul Buyukkurt IRBuilder<> Builder(Ind); 659f78f509cSHiroshi Yamauchi bool IsMemOpSize = (Ind->getValueKind()->getZExtValue() == 66060faea19SRong Xu llvm::InstrProfValueKind::IPVK_MemOPSize); 66160faea19SRong Xu CallInst *Call = nullptr; 6629c27b59cSTeresa Johnson auto *TLI = &GetTLI(*Ind->getFunction()); 663b35b7da4SAndy Kaylor 664b35b7da4SAndy Kaylor // To support value profiling calls within Windows exception handlers, funclet 665b35b7da4SAndy Kaylor // information contained within operand bundles needs to be copied over to 666b35b7da4SAndy Kaylor // the library call. This is required for the IR to be processed by the 667b35b7da4SAndy Kaylor // WinEHPrepare pass. 668b35b7da4SAndy Kaylor SmallVector<OperandBundleDef, 1> OpBundles; 669b35b7da4SAndy Kaylor Ind->getOperandBundlesAsDefs(OpBundles); 670f78f509cSHiroshi Yamauchi if (!IsMemOpSize) { 6716fac1741SBetul Buyukkurt Value *Args[3] = {Ind->getTargetValue(), 6726fac1741SBetul Buyukkurt Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()), 6736fac1741SBetul Buyukkurt Builder.getInt32(Index)}; 674b35b7da4SAndy Kaylor Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI), Args, 675b35b7da4SAndy Kaylor OpBundles); 6761ebee7adSHiroshi Yamauchi } else { 677f78f509cSHiroshi Yamauchi Value *Args[3] = {Ind->getTargetValue(), 678f78f509cSHiroshi Yamauchi Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()), 679f78f509cSHiroshi Yamauchi Builder.getInt32(Index)}; 680f78f509cSHiroshi Yamauchi Call = Builder.CreateCall( 681f78f509cSHiroshi Yamauchi getOrInsertValueProfilingCall(*M, *TLI, ValueProfilingCallType::MemOp), 682f78f509cSHiroshi Yamauchi Args, OpBundles); 68360faea19SRong Xu } 6841c2bd1e9SMarcin Koscielnicki if (auto AK = TLI->getExtAttrForI32Param(false)) 685a0b45f4bSReid Kleckner Call->addParamAttr(2, AK); 6861c2bd1e9SMarcin Koscielnicki Ind->replaceAllUsesWith(Call); 6876fac1741SBetul Buyukkurt Ind->eraseFromParent(); 6886fac1741SBetul Buyukkurt } 6896fac1741SBetul Buyukkurt 69061ba2e39SJustin Bogner void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) { 69161ba2e39SJustin Bogner GlobalVariable *Counters = getOrCreateRegionCounters(Inc); 69261ba2e39SJustin Bogner 693e82c286fSDuncan P. N. Exon Smith IRBuilder<> Builder(Inc); 69461ba2e39SJustin Bogner uint64_t Index = Inc->getIndex()->getZExtValue(); 6957716075aSJames Y Knight Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters->getValueType(), 6967716075aSJames Y Knight Counters, 0, Index); 697ee6c233aSVedant Kumar 698d3db13afSPetr Hosek if (isRuntimeCounterRelocationEnabled()) { 699d3db13afSPetr Hosek Type *Int64Ty = Type::getInt64Ty(M->getContext()); 700d3db13afSPetr Hosek Type *Int64PtrTy = Type::getInt64PtrTy(M->getContext()); 701d3db13afSPetr Hosek Function *Fn = Inc->getParent()->getParent(); 702d3db13afSPetr Hosek Instruction &I = Fn->getEntryBlock().front(); 703d3db13afSPetr Hosek LoadInst *LI = dyn_cast<LoadInst>(&I); 704d3db13afSPetr Hosek if (!LI) { 705d3db13afSPetr Hosek IRBuilder<> Builder(&I); 706d3db13afSPetr Hosek GlobalVariable *Bias = M->getGlobalVariable(getInstrProfCounterBiasVarName()); 707c0c1c3cfSPetr Hosek if (!Bias) { 708c0c1c3cfSPetr Hosek // Compiler must define this variable when runtime counter relocation 709c0c1c3cfSPetr Hosek // is being used. Runtime has a weak external reference that is used 710c0c1c3cfSPetr Hosek // to check whether that's the case or not. 711c0c1c3cfSPetr Hosek Bias = new GlobalVariable(*M, Int64Ty, false, GlobalValue::LinkOnceODRLinkage, 712c0c1c3cfSPetr Hosek Constant::getNullValue(Int64Ty), 713c0c1c3cfSPetr Hosek getInstrProfCounterBiasVarName()); 714c0c1c3cfSPetr Hosek Bias->setVisibility(GlobalVariable::HiddenVisibility); 715c0c1c3cfSPetr Hosek // A definition that's weak (linkonce_odr) without being in a COMDAT 716c0c1c3cfSPetr Hosek // section wouldn't lead to link errors, but it would lead to a dead 717c0c1c3cfSPetr Hosek // data word from every TU but one. Putting it in COMDAT ensures there 718c0c1c3cfSPetr Hosek // will be exactly one data slot in the link. 719c0c1c3cfSPetr Hosek if (TT.supportsCOMDAT()) 720c0c1c3cfSPetr Hosek Bias->setComdat(M->getOrInsertComdat(Bias->getName())); 721c0c1c3cfSPetr Hosek } 722d3db13afSPetr Hosek LI = Builder.CreateLoad(Int64Ty, Bias); 723d3db13afSPetr Hosek } 724d3db13afSPetr Hosek auto *Add = Builder.CreateAdd(Builder.CreatePtrToInt(Addr, Int64Ty), LI); 725d3db13afSPetr Hosek Addr = Builder.CreateIntToPtr(Add, Int64PtrTy); 726d3db13afSPetr Hosek } 727d3db13afSPetr Hosek 728b4bceb94SRong Xu if (Options.Atomic || AtomicCounterUpdateAll || 729b4bceb94SRong Xu (Index == 0 && AtomicFirstCounter)) { 730ee6c233aSVedant Kumar Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, Inc->getStep(), 73124539f1eSJames Y Knight MaybeAlign(), AtomicOrdering::Monotonic); 732ee6c233aSVedant Kumar } else { 73314359ef1SJames Y Knight Value *IncStep = Inc->getStep(); 73414359ef1SJames Y Knight Value *Load = Builder.CreateLoad(IncStep->getType(), Addr, "pgocount"); 735b67530e9SXinliang David Li auto *Count = Builder.CreateAdd(Load, Inc->getStep()); 736b67530e9SXinliang David Li auto *Store = Builder.CreateStore(Count, Addr); 737b67530e9SXinliang David Li if (isCounterPromotionEnabled()) 738b67530e9SXinliang David Li PromotionCandidates.emplace_back(cast<Instruction>(Load), Store); 739ee6c233aSVedant Kumar } 74061ba2e39SJustin Bogner Inc->eraseFromParent(); 74161ba2e39SJustin Bogner } 74261ba2e39SJustin Bogner 74381056077SXinliang David Li void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageNamesVar) { 74481056077SXinliang David Li ConstantArray *Names = 74581056077SXinliang David Li cast<ConstantArray>(CoverageNamesVar->getInitializer()); 74681056077SXinliang David Li for (unsigned I = 0, E = Names->getNumOperands(); I < E; ++I) { 74781056077SXinliang David Li Constant *NC = Names->getOperand(I); 74881056077SXinliang David Li Value *V = NC->stripPointerCasts(); 749d24e1857SJustin Bogner assert(isa<GlobalVariable>(V) && "Missing reference to function name"); 750d24e1857SJustin Bogner GlobalVariable *Name = cast<GlobalVariable>(V); 751d24e1857SJustin Bogner 752a82d6c0aSXinliang David Li Name->setLinkage(GlobalValue::PrivateLinkage); 753a82d6c0aSXinliang David Li ReferencedNames.push_back(Name); 75455891fc7SVedant Kumar NC->dropAllReferences(); 755d24e1857SJustin Bogner } 75655891fc7SVedant Kumar CoverageNamesVar->eraseFromParent(); 757d24e1857SJustin Bogner } 758d24e1857SJustin Bogner 75961ba2e39SJustin Bogner /// Get the name of a profiling variable for a particular function. 7609ab9a959SFangrui Song static std::string getVarName(InstrProfIncrementInst *Inc, StringRef Prefix, 7619ab9a959SFangrui Song bool &Renamed) { 762d1bab960SXinliang David Li StringRef NamePrefix = getInstrProfNameVarPrefix(); 763d1bab960SXinliang David Li StringRef Name = Inc->getName()->getName().substr(NamePrefix.size()); 76420f5df1dSRong Xu Function *F = Inc->getParent()->getParent(); 76520f5df1dSRong Xu Module *M = F->getParent(); 76620f5df1dSRong Xu if (!DoHashBasedCounterSplit || !isIRPGOFlagSet(M) || 7679ab9a959SFangrui Song !canRenameComdatFunc(*F)) { 7689ab9a959SFangrui Song Renamed = false; 76983bc4220SXinliang David Li return (Prefix + Name).str(); 7709ab9a959SFangrui Song } 7719ab9a959SFangrui Song Renamed = true; 77220f5df1dSRong Xu uint64_t FuncHash = Inc->getHash()->getZExtValue(); 77320f5df1dSRong Xu SmallVector<char, 24> HashPostfix; 77420f5df1dSRong Xu if (Name.endswith((Twine(".") + Twine(FuncHash)).toStringRef(HashPostfix))) 77520f5df1dSRong Xu return (Prefix + Name).str(); 77620f5df1dSRong Xu return (Prefix + Name + "." + Twine(FuncHash)).str(); 77761ba2e39SJustin Bogner } 77861ba2e39SJustin Bogner 7799e51d1f3SFangrui Song static uint64_t getIntModuleFlagOrZero(const Module &M, StringRef Flag) { 7809e51d1f3SFangrui Song auto *MD = dyn_cast_or_null<ConstantAsMetadata>(M.getModuleFlag(Flag)); 7818f20ac95SReid Kleckner if (!MD) 7828f20ac95SReid Kleckner return 0; 7838f20ac95SReid Kleckner 7848f20ac95SReid Kleckner // If the flag is a ConstantAsMetadata, it should be an integer representable 7858f20ac95SReid Kleckner // in 64-bits. 7868f20ac95SReid Kleckner return cast<ConstantInt>(MD->getValue())->getZExtValue(); 7878f20ac95SReid Kleckner } 7888f20ac95SReid Kleckner 7899e51d1f3SFangrui Song static bool enablesValueProfiling(const Module &M) { 7909e51d1f3SFangrui Song return isIRPGOFlagSet(&M) || 7919e51d1f3SFangrui Song getIntModuleFlagOrZero(M, "EnableValueProfiling") != 0; 7929e51d1f3SFangrui Song } 7939e51d1f3SFangrui Song 7949e51d1f3SFangrui Song // Conservatively returns true if data variables may be referenced by code. 7959e51d1f3SFangrui Song static bool profDataReferencedByCode(const Module &M) { 7969e51d1f3SFangrui Song return enablesValueProfiling(M); 7979e51d1f3SFangrui Song } 7989e51d1f3SFangrui Song 7996fac1741SBetul Buyukkurt static inline bool shouldRecordFunctionAddr(Function *F) { 8008f20ac95SReid Kleckner // Only record function addresses if IR PGO is enabled or if clang value 8018f20ac95SReid Kleckner // profiling is enabled. Recording function addresses greatly increases object 8028f20ac95SReid Kleckner // file size, because it prevents the inliner from deleting functions that 8038f20ac95SReid Kleckner // have been inlined everywhere. 8049e51d1f3SFangrui Song if (!profDataReferencedByCode(*F->getParent())) 8058f20ac95SReid Kleckner return false; 8068f20ac95SReid Kleckner 8076fac1741SBetul Buyukkurt // Check the linkage 8089c056c9eSVedant Kumar bool HasAvailableExternallyLinkage = F->hasAvailableExternallyLinkage(); 8096fac1741SBetul Buyukkurt if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() && 8109c056c9eSVedant Kumar !HasAvailableExternallyLinkage) 8116fac1741SBetul Buyukkurt return true; 8129c056c9eSVedant Kumar 8139c056c9eSVedant Kumar // A function marked 'alwaysinline' with available_externally linkage can't 8149c056c9eSVedant Kumar // have its address taken. Doing so would create an undefined external ref to 8159c056c9eSVedant Kumar // the function, which would fail to link. 8169c056c9eSVedant Kumar if (HasAvailableExternallyLinkage && 8179c056c9eSVedant Kumar F->hasFnAttribute(Attribute::AlwaysInline)) 8189c056c9eSVedant Kumar return false; 8199c056c9eSVedant Kumar 820af5aebaaSRong Xu // Prohibit function address recording if the function is both internal and 821af5aebaaSRong Xu // COMDAT. This avoids the profile data variable referencing internal symbols 822af5aebaaSRong Xu // in COMDAT. 823af5aebaaSRong Xu if (F->hasLocalLinkage() && F->hasComdat()) 824af5aebaaSRong Xu return false; 8259c056c9eSVedant Kumar 8266fac1741SBetul Buyukkurt // Check uses of this function for other than direct calls or invokes to it. 8277008ce3fSXinliang David Li // Inline virtual functions have linkeOnceODR linkage. When a key method 8287008ce3fSXinliang David Li // exists, the vtable will only be emitted in the TU where the key method 8297008ce3fSXinliang David Li // is defined. In a TU where vtable is not available, the function won't 8306c44e9e3SXinliang David Li // be 'addresstaken'. If its address is not recorded here, the profile data 8316c44e9e3SXinliang David Li // with missing address may be picked by the linker leading to missing 8326c44e9e3SXinliang David Li // indirect call target info. 8336c44e9e3SXinliang David Li return F->hasAddressTaken() || F->hasLinkOnceLinkage(); 8346fac1741SBetul Buyukkurt } 8356fac1741SBetul Buyukkurt 836f21c0223SReid Kleckner static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) { 837b628dd35SXinliang David Li // Don't do this for Darwin. compiler-rt uses linker magic. 838f21c0223SReid Kleckner if (TT.isOSDarwin()) 839b628dd35SXinliang David Li return false; 840b628dd35SXinliang David Li // Use linker script magic to get data/cnts/name start/end. 841f21c0223SReid Kleckner if (TT.isOSLinux() || TT.isOSFreeBSD() || TT.isOSNetBSD() || 8426fde832bSRainer Orth TT.isOSSolaris() || TT.isOSFuchsia() || TT.isPS4CPU() || 8436fde832bSRainer Orth TT.isOSWindows()) 844b628dd35SXinliang David Li return false; 845b628dd35SXinliang David Li 846b628dd35SXinliang David Li return true; 847b628dd35SXinliang David Li } 848b628dd35SXinliang David Li 84961ba2e39SJustin Bogner GlobalVariable * 85061ba2e39SJustin Bogner InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { 851192c7480SXinliang David Li GlobalVariable *NamePtr = Inc->getName(); 8526fac1741SBetul Buyukkurt auto It = ProfileDataMap.find(NamePtr); 8536fac1741SBetul Buyukkurt PerFunctionProfileData PD; 8546fac1741SBetul Buyukkurt if (It != ProfileDataMap.end()) { 8556fac1741SBetul Buyukkurt if (It->second.RegionCounters) 8566fac1741SBetul Buyukkurt return It->second.RegionCounters; 8576fac1741SBetul Buyukkurt PD = It->second; 8586fac1741SBetul Buyukkurt } 85961ba2e39SJustin Bogner 86087c43f3aSFangrui Song // Match the linkage and visibility of the name global. 861df4837baSDiego Novillo Function *Fn = Inc->getParent()->getParent(); 862987d331fSReid Kleckner GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage(); 863987d331fSReid Kleckner GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility(); 864987d331fSReid Kleckner 865987d331fSReid Kleckner // Move the name variable to the right section. Place them in a COMDAT group 866987d331fSReid Kleckner // if the associated function is a COMDAT. This will make sure that only one 8674fb3502bSReid Kleckner // copy of counters of the COMDAT function will be emitted after linking. Keep 8684fb3502bSReid Kleckner // in mind that this pass may run before the inliner, so we need to create a 8694fb3502bSReid Kleckner // new comdat group for the counters and profiling data. If we use the comdat 8704fb3502bSReid Kleckner // of the parent function, that will result in relocations against discarded 8714fb3502bSReid Kleckner // sections. 87287c43f3aSFangrui Song // 8739e51d1f3SFangrui Song // If the data variable is referenced by code, counters and data have to be 8749e51d1f3SFangrui Song // in different comdats for COFF because the Visual C++ linker will report 8759e51d1f3SFangrui Song // duplicate symbol errors if there are multiple external symbols with the 8769e51d1f3SFangrui Song // same name marked IMAGE_COMDAT_SELECT_ASSOCIATIVE. 87787c43f3aSFangrui Song // 87887c43f3aSFangrui Song // For ELF, when not using COMDAT, put counters, data and values into a 87939248779SFangrui Song // nodeduplicate COMDAT which is lowered to a zero-flag section group. This 88087c43f3aSFangrui Song // allows -z start-stop-gc to discard the entire group when the function is 88187c43f3aSFangrui Song // discarded. 88277b435aaSFangrui Song bool DataReferencedByCode = profDataReferencedByCode(*M); 88387c43f3aSFangrui Song bool NeedComdat = needsComdatForCounter(*Fn, *M); 8849ab9a959SFangrui Song bool Renamed; 8859ab9a959SFangrui Song std::string CntsVarName = 8869ab9a959SFangrui Song getVarName(Inc, getInstrProfCountersVarPrefix(), Renamed); 8879ab9a959SFangrui Song std::string DataVarName = 8889ab9a959SFangrui Song getVarName(Inc, getInstrProfDataVarPrefix(), Renamed); 8899e51d1f3SFangrui Song auto MaybeSetComdat = [&](GlobalVariable *GV) { 89077b435aaSFangrui Song bool UseComdat = (NeedComdat || TT.isOSBinFormatELF()); 89177b435aaSFangrui Song if (UseComdat) { 89277b435aaSFangrui Song StringRef GroupName = TT.isOSBinFormatCOFF() && DataReferencedByCode 89377b435aaSFangrui Song ? GV->getName() 89477b435aaSFangrui Song : CntsVarName; 89577b435aaSFangrui Song Comdat *C = M->getOrInsertComdat(GroupName); 896c24b7a16SPetr Hosek if (!NeedComdat) 89739248779SFangrui Song C->setSelectionKind(Comdat::NoDeduplicate); 898c24b7a16SPetr Hosek GV->setComdat(C); 899c24b7a16SPetr Hosek } 90023e872a3SReid Kleckner }; 90161ba2e39SJustin Bogner 90261ba2e39SJustin Bogner uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); 90361ba2e39SJustin Bogner LLVMContext &Ctx = M->getContext(); 90461ba2e39SJustin Bogner ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters); 90561ba2e39SJustin Bogner 90661ba2e39SJustin Bogner // Create the counters variable. 907192c7480SXinliang David Li auto *CounterPtr = 908987d331fSReid Kleckner new GlobalVariable(*M, CounterTy, false, Linkage, 9099e51d1f3SFangrui Song Constant::getNullValue(CounterTy), CntsVarName); 910987d331fSReid Kleckner CounterPtr->setVisibility(Visibility); 9111a6a2b64SVedant Kumar CounterPtr->setSection( 9121a6a2b64SVedant Kumar getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat())); 9130e62011dSGuillaume Chatelet CounterPtr->setAlignment(Align(8)); 91423e872a3SReid Kleckner MaybeSetComdat(CounterPtr); 91532837a0cSReid Kleckner CounterPtr->setLinkage(Linkage); 91661ba2e39SJustin Bogner 9176fac1741SBetul Buyukkurt auto *Int8PtrTy = Type::getInt8PtrTy(Ctx); 918b628dd35SXinliang David Li // Allocate statically the array of pointers to value profile nodes for 919b628dd35SXinliang David Li // the current function. 920b628dd35SXinliang David Li Constant *ValuesPtrExpr = ConstantPointerNull::get(Int8PtrTy); 921b628dd35SXinliang David Li uint64_t NS = 0; 922b628dd35SXinliang David Li for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 923b628dd35SXinliang David Li NS += PD.NumValueSites[Kind]; 9243307240fSFangrui Song if (NS > 0 && ValueProfileStaticAlloc && 9253307240fSFangrui Song !needsRuntimeRegistrationOfSectionRange(TT)) { 926b628dd35SXinliang David Li ArrayType *ValuesTy = ArrayType::get(Type::getInt64Ty(Ctx), NS); 9273307240fSFangrui Song auto *ValuesVar = new GlobalVariable( 9283307240fSFangrui Song *M, ValuesTy, false, Linkage, Constant::getNullValue(ValuesTy), 9299ab9a959SFangrui Song getVarName(Inc, getInstrProfValuesVarPrefix(), Renamed)); 930987d331fSReid Kleckner ValuesVar->setVisibility(Visibility); 9311a6a2b64SVedant Kumar ValuesVar->setSection( 9321a6a2b64SVedant Kumar getInstrProfSectionName(IPSK_vals, TT.getObjectFormat())); 9330e62011dSGuillaume Chatelet ValuesVar->setAlignment(Align(8)); 93423e872a3SReid Kleckner MaybeSetComdat(ValuesVar); 935b628dd35SXinliang David Li ValuesPtrExpr = 93634c23279SEugene Zelenko ConstantExpr::getBitCast(ValuesVar, Type::getInt8PtrTy(Ctx)); 937b628dd35SXinliang David Li } 938b628dd35SXinliang David Li 939b628dd35SXinliang David Li // Create data variable. 940a1532ed2SFangrui Song auto *IntPtrTy = M->getDataLayout().getIntPtrType(M->getContext()); 9416fac1741SBetul Buyukkurt auto *Int16Ty = Type::getInt16Ty(Ctx); 9426fac1741SBetul Buyukkurt auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last + 1); 943192c7480SXinliang David Li Type *DataTypes[] = { 944192c7480SXinliang David Li #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType, 945192c7480SXinliang David Li #include "llvm/ProfileData/InstrProfData.inc" 946192c7480SXinliang David Li }; 94761ba2e39SJustin Bogner auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes)); 948192c7480SXinliang David Li 94969a00f06SXinliang David Li Constant *FunctionAddr = shouldRecordFunctionAddr(Fn) 95069a00f06SXinliang David Li ? ConstantExpr::getBitCast(Fn, Int8PtrTy) 95169a00f06SXinliang David Li : ConstantPointerNull::get(Int8PtrTy); 9526fac1741SBetul Buyukkurt 9536fac1741SBetul Buyukkurt Constant *Int16ArrayVals[IPVK_Last + 1]; 9546fac1741SBetul Buyukkurt for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 9556fac1741SBetul Buyukkurt Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]); 9566fac1741SBetul Buyukkurt 9573307240fSFangrui Song // If the data variable is not referenced by code (if we don't emit 9583307240fSFangrui Song // @llvm.instrprof.value.profile, NS will be 0), and the counter keeps the 9593307240fSFangrui Song // data variable live under linker GC, the data variable can be private. This 96077b435aaSFangrui Song // optimization applies to ELF. 96177b435aaSFangrui Song // 96277b435aaSFangrui Song // On COFF, a comdat leader cannot be local so we require DataReferencedByCode 96377b435aaSFangrui Song // to be false. 9649ab9a959SFangrui Song // 9659ab9a959SFangrui Song // If profd is in a deduplicate comdat, NS==0 with a hash suffix guarantees 9669ab9a959SFangrui Song // that other copies must have the same CFG and cannot have value profiling. 9679ab9a959SFangrui Song // If no hash suffix, other profd copies may be referenced by code. 9689ab9a959SFangrui Song if (NS == 0 && !(DataReferencedByCode && NeedComdat && !Renamed) && 9699ab9a959SFangrui Song (TT.isOSBinFormatELF() || 97077b435aaSFangrui Song (!DataReferencedByCode && TT.isOSBinFormatCOFF()))) { 9719e51d1f3SFangrui Song Linkage = GlobalValue::PrivateLinkage; 9729e51d1f3SFangrui Song Visibility = GlobalValue::DefaultVisibility; 9739e51d1f3SFangrui Song } 974e56626e4SFangrui Song auto *Data = 975a1532ed2SFangrui Song new GlobalVariable(*M, DataTy, false, Linkage, nullptr, DataVarName); 976a1532ed2SFangrui Song // Reference the counter variable with a label difference (link-time 977a1532ed2SFangrui Song // constant). 978a1532ed2SFangrui Song auto *RelativeCounterPtr = 979a1532ed2SFangrui Song ConstantExpr::getSub(ConstantExpr::getPtrToInt(CounterPtr, IntPtrTy), 980a1532ed2SFangrui Song ConstantExpr::getPtrToInt(Data, IntPtrTy)); 981a1532ed2SFangrui Song 982a1532ed2SFangrui Song Constant *DataVals[] = { 983a1532ed2SFangrui Song #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init, 984a1532ed2SFangrui Song #include "llvm/ProfileData/InstrProfData.inc" 985a1532ed2SFangrui Song }; 986a1532ed2SFangrui Song Data->setInitializer(ConstantStruct::get(DataTy, DataVals)); 987a1532ed2SFangrui Song 988987d331fSReid Kleckner Data->setVisibility(Visibility); 9891a6a2b64SVedant Kumar Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat())); 9900e62011dSGuillaume Chatelet Data->setAlignment(Align(INSTR_PROF_DATA_ALIGNMENT)); 99123e872a3SReid Kleckner MaybeSetComdat(Data); 99232837a0cSReid Kleckner Data->setLinkage(Linkage); 99361ba2e39SJustin Bogner 9946fac1741SBetul Buyukkurt PD.RegionCounters = CounterPtr; 9956fac1741SBetul Buyukkurt PD.DataVar = Data; 9966fac1741SBetul Buyukkurt ProfileDataMap[NamePtr] = PD; 9976fac1741SBetul Buyukkurt 99861ba2e39SJustin Bogner // Mark the data variable as used so that it isn't stripped out. 999a84f4fc0SFangrui Song CompilerUsedVars.push_back(Data); 1000a82d6c0aSXinliang David Li // Now that the linkage set by the FE has been passed to the data and counter 1001a82d6c0aSXinliang David Li // variables, reset Name variable's linkage and visibility to private so that 1002a82d6c0aSXinliang David Li // it can be removed later by the compiler. 1003a82d6c0aSXinliang David Li NamePtr->setLinkage(GlobalValue::PrivateLinkage); 1004a82d6c0aSXinliang David Li // Collect the referenced names to be used by emitNameData. 1005a82d6c0aSXinliang David Li ReferencedNames.push_back(NamePtr); 100661ba2e39SJustin Bogner 1007192c7480SXinliang David Li return CounterPtr; 100861ba2e39SJustin Bogner } 100961ba2e39SJustin Bogner 1010b628dd35SXinliang David Li void InstrProfiling::emitVNodes() { 1011b628dd35SXinliang David Li if (!ValueProfileStaticAlloc) 1012b628dd35SXinliang David Li return; 10138da773bfSXinliang David Li 1014b628dd35SXinliang David Li // For now only support this on platforms that do 1015b628dd35SXinliang David Li // not require runtime registration to discover 1016b628dd35SXinliang David Li // named section start/end. 1017f21c0223SReid Kleckner if (needsRuntimeRegistrationOfSectionRange(TT)) 1018b628dd35SXinliang David Li return; 10198da773bfSXinliang David Li 1020b628dd35SXinliang David Li size_t TotalNS = 0; 1021b628dd35SXinliang David Li for (auto &PD : ProfileDataMap) { 1022b628dd35SXinliang David Li for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 1023b628dd35SXinliang David Li TotalNS += PD.second.NumValueSites[Kind]; 1024b628dd35SXinliang David Li } 1025b628dd35SXinliang David Li 1026b628dd35SXinliang David Li if (!TotalNS) 1027b628dd35SXinliang David Li return; 1028b628dd35SXinliang David Li 1029b628dd35SXinliang David Li uint64_t NumCounters = TotalNS * NumCountersPerValueSite; 1030b628dd35SXinliang David Li // Heuristic for small programs with very few total value sites. 1031b628dd35SXinliang David Li // The default value of vp-counters-per-site is chosen based on 1032b628dd35SXinliang David Li // the observation that large apps usually have a low percentage 1033b628dd35SXinliang David Li // of value sites that actually have any profile data, and thus 1034b628dd35SXinliang David Li // the average number of counters per site is low. For small 1035b628dd35SXinliang David Li // apps with very few sites, this may not be true. Bump up the 1036b628dd35SXinliang David Li // number of counters in this case. 1037e4520760SXinliang David Li #define INSTR_PROF_MIN_VAL_COUNTS 10 1038e4520760SXinliang David Li if (NumCounters < INSTR_PROF_MIN_VAL_COUNTS) 1039e4520760SXinliang David Li NumCounters = std::max(INSTR_PROF_MIN_VAL_COUNTS, (int)NumCounters * 2); 1040b628dd35SXinliang David Li 1041b628dd35SXinliang David Li auto &Ctx = M->getContext(); 1042b628dd35SXinliang David Li Type *VNodeTypes[] = { 1043b628dd35SXinliang David Li #define INSTR_PROF_VALUE_NODE(Type, LLVMType, Name, Init) LLVMType, 1044b628dd35SXinliang David Li #include "llvm/ProfileData/InstrProfData.inc" 1045b628dd35SXinliang David Li }; 1046b628dd35SXinliang David Li auto *VNodeTy = StructType::get(Ctx, makeArrayRef(VNodeTypes)); 1047b628dd35SXinliang David Li 1048b628dd35SXinliang David Li ArrayType *VNodesTy = ArrayType::get(VNodeTy, NumCounters); 1049b628dd35SXinliang David Li auto *VNodesVar = new GlobalVariable( 105034c23279SEugene Zelenko *M, VNodesTy, false, GlobalValue::PrivateLinkage, 1051b628dd35SXinliang David Li Constant::getNullValue(VNodesTy), getInstrProfVNodesVarName()); 10521a6a2b64SVedant Kumar VNodesVar->setSection( 10531a6a2b64SVedant Kumar getInstrProfSectionName(IPSK_vnodes, TT.getObjectFormat())); 1054a84f4fc0SFangrui Song // VNodesVar is used by runtime but not referenced via relocation by other 1055a84f4fc0SFangrui Song // sections. Conservatively make it linker retained. 1056b628dd35SXinliang David Li UsedVars.push_back(VNodesVar); 10578da773bfSXinliang David Li } 10588da773bfSXinliang David Li 1059a82d6c0aSXinliang David Li void InstrProfiling::emitNameData() { 1060a82d6c0aSXinliang David Li std::string UncompressedData; 1061a82d6c0aSXinliang David Li 1062a82d6c0aSXinliang David Li if (ReferencedNames.empty()) 1063a82d6c0aSXinliang David Li return; 1064a82d6c0aSXinliang David Li 1065a82d6c0aSXinliang David Li std::string CompressedNameStr; 10669152fd17SVedant Kumar if (Error E = collectPGOFuncNameStrings(ReferencedNames, CompressedNameStr, 1067dd1ea9deSVedant Kumar DoInstrProfNameCompression)) { 106834c23279SEugene Zelenko report_fatal_error(toString(std::move(E)), false); 106943cba733SVedant Kumar } 1070a82d6c0aSXinliang David Li 1071a82d6c0aSXinliang David Li auto &Ctx = M->getContext(); 107234c23279SEugene Zelenko auto *NamesVal = ConstantDataArray::getString( 1073a82d6c0aSXinliang David Li Ctx, StringRef(CompressedNameStr), false); 107434c23279SEugene Zelenko NamesVar = new GlobalVariable(*M, NamesVal->getType(), true, 107534c23279SEugene Zelenko GlobalValue::PrivateLinkage, NamesVal, 107634c23279SEugene Zelenko getInstrProfNamesVarName()); 1077a82d6c0aSXinliang David Li NamesSize = CompressedNameStr.size(); 10781a6a2b64SVedant Kumar NamesVar->setSection( 10791a6a2b64SVedant Kumar getInstrProfSectionName(IPSK_name, TT.getObjectFormat())); 1080987d331fSReid Kleckner // On COFF, it's important to reduce the alignment down to 1 to prevent the 1081987d331fSReid Kleckner // linker from inserting padding before the start of the names section or 1082987d331fSReid Kleckner // between names entries. 1083805c157eSGuillaume Chatelet NamesVar->setAlignment(Align(1)); 1084a84f4fc0SFangrui Song // NamesVar is used by runtime but not referenced via relocation by other 1085a84f4fc0SFangrui Song // sections. Conservatively make it linker retained. 1086a82d6c0aSXinliang David Li UsedVars.push_back(NamesVar); 108755891fc7SVedant Kumar 108855891fc7SVedant Kumar for (auto *NamePtr : ReferencedNames) 108955891fc7SVedant Kumar NamePtr->eraseFromParent(); 1090a82d6c0aSXinliang David Li } 1091a82d6c0aSXinliang David Li 109261ba2e39SJustin Bogner void InstrProfiling::emitRegistration() { 1093f21c0223SReid Kleckner if (!needsRuntimeRegistrationOfSectionRange(TT)) 1094aa0592ccSXinliang David Li return; 10953dd8817dSXinliang David Li 109661ba2e39SJustin Bogner // Construct the function. 109761ba2e39SJustin Bogner auto *VoidTy = Type::getVoidTy(M->getContext()); 109861ba2e39SJustin Bogner auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext()); 1099a82d6c0aSXinliang David Li auto *Int64Ty = Type::getInt64Ty(M->getContext()); 110061ba2e39SJustin Bogner auto *RegisterFTy = FunctionType::get(VoidTy, false); 110161ba2e39SJustin Bogner auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage, 11028ee08b0fSXinliang David Li getInstrProfRegFuncsName(), M); 110396efdd61SPeter Collingbourne RegisterF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 110469a00f06SXinliang David Li if (Options.NoRedZone) 110569a00f06SXinliang David Li RegisterF->addFnAttr(Attribute::NoRedZone); 110661ba2e39SJustin Bogner 1107b3029d26SDiego Novillo auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false); 110861ba2e39SJustin Bogner auto *RuntimeRegisterF = 110961ba2e39SJustin Bogner Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage, 11108ee08b0fSXinliang David Li getInstrProfRegFuncName(), M); 111161ba2e39SJustin Bogner 111261ba2e39SJustin Bogner IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", RegisterF)); 1113a84f4fc0SFangrui Song for (Value *Data : CompilerUsedVars) 1114a84f4fc0SFangrui Song if (!isa<Function>(Data)) 1115a84f4fc0SFangrui Song IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy)); 111661ba2e39SJustin Bogner for (Value *Data : UsedVars) 1117ba82788fSReid Kleckner if (Data != NamesVar && !isa<Function>(Data)) 111861ba2e39SJustin Bogner IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy)); 1119a82d6c0aSXinliang David Li 1120a82d6c0aSXinliang David Li if (NamesVar) { 1121a82d6c0aSXinliang David Li Type *ParamTypes[] = {VoidPtrTy, Int64Ty}; 1122a82d6c0aSXinliang David Li auto *NamesRegisterTy = 1123a82d6c0aSXinliang David Li FunctionType::get(VoidTy, makeArrayRef(ParamTypes), false); 1124a82d6c0aSXinliang David Li auto *NamesRegisterF = 1125a82d6c0aSXinliang David Li Function::Create(NamesRegisterTy, GlobalVariable::ExternalLinkage, 1126a82d6c0aSXinliang David Li getInstrProfNamesRegFuncName(), M); 1127a82d6c0aSXinliang David Li IRB.CreateCall(NamesRegisterF, {IRB.CreateBitCast(NamesVar, VoidPtrTy), 1128a82d6c0aSXinliang David Li IRB.getInt64(NamesSize)}); 1129a82d6c0aSXinliang David Li } 1130a82d6c0aSXinliang David Li 113161ba2e39SJustin Bogner IRB.CreateRetVoid(); 113261ba2e39SJustin Bogner } 113361ba2e39SJustin Bogner 11349a041a75SVedant Kumar bool InstrProfiling::emitRuntimeHook() { 1135389dc94dSPetr Hosek // We expect the linker to be invoked with -u<hook_var> flag for Linux 1136389dc94dSPetr Hosek // in which case there is no need to emit the external variable. 1137389dc94dSPetr Hosek if (TT.isOSLinux()) 1138f50aef74SHans Wennborg return false; 1139f50aef74SHans Wennborg 114061ba2e39SJustin Bogner // If the module's provided its own runtime, we don't need to do anything. 114169a00f06SXinliang David Li if (M->getGlobalVariable(getInstrProfRuntimeHookVarName())) 11429a041a75SVedant Kumar return false; 114361ba2e39SJustin Bogner 114461ba2e39SJustin Bogner // Declare an external variable that will pull in the runtime initialization. 114561ba2e39SJustin Bogner auto *Int32Ty = Type::getInt32Ty(M->getContext()); 114661ba2e39SJustin Bogner auto *Var = 114761ba2e39SJustin Bogner new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage, 11488ee08b0fSXinliang David Li nullptr, getInstrProfRuntimeHookVarName()); 114961ba2e39SJustin Bogner 1150389dc94dSPetr Hosek if (TT.isOSBinFormatELF()) { 1151389dc94dSPetr Hosek // Mark the user variable as used so that it isn't stripped out. 1152389dc94dSPetr Hosek CompilerUsedVars.push_back(Var); 1153389dc94dSPetr Hosek } else { 1154f50aef74SHans Wennborg // Make a function that uses it. 1155f50aef74SHans Wennborg auto *User = Function::Create(FunctionType::get(Int32Ty, false), 1156f50aef74SHans Wennborg GlobalValue::LinkOnceODRLinkage, 1157f50aef74SHans Wennborg getInstrProfRuntimeHookVarUseFuncName(), M); 1158f50aef74SHans Wennborg User->addFnAttr(Attribute::NoInline); 1159f50aef74SHans Wennborg if (Options.NoRedZone) 1160f50aef74SHans Wennborg User->addFnAttr(Attribute::NoRedZone); 1161f50aef74SHans Wennborg User->setVisibility(GlobalValue::HiddenVisibility); 1162f50aef74SHans Wennborg if (TT.supportsCOMDAT()) 1163f50aef74SHans Wennborg User->setComdat(M->getOrInsertComdat(User->getName())); 1164f50aef74SHans Wennborg 1165f50aef74SHans Wennborg IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", User)); 1166f50aef74SHans Wennborg auto *Load = IRB.CreateLoad(Int32Ty, Var); 1167f50aef74SHans Wennborg IRB.CreateRet(Load); 1168f50aef74SHans Wennborg 1169389dc94dSPetr Hosek // Mark the function as used so that it isn't stripped out. 1170f50aef74SHans Wennborg CompilerUsedVars.push_back(User); 1171389dc94dSPetr Hosek } 11729a041a75SVedant Kumar return true; 117361ba2e39SJustin Bogner } 117461ba2e39SJustin Bogner 117561ba2e39SJustin Bogner void InstrProfiling::emitUses() { 1176bf176c49SFangrui Song // The metadata sections are parallel arrays. Optimizers (e.g. 1177bf176c49SFangrui Song // GlobalOpt/ConstantMerge) may not discard associated sections as a unit, so 1178bf176c49SFangrui Song // we conservatively retain all unconditionally in the compiler. 1179bf176c49SFangrui Song // 118068745a55SFangrui Song // On ELF and Mach-O, the linker can guarantee the associated sections will be 118168745a55SFangrui Song // retained or discarded as a unit, so llvm.compiler.used is sufficient. 118268745a55SFangrui Song // Similarly on COFF, if prof data is not referenced by code we use one comdat 118368745a55SFangrui Song // and ensure this GC property as well. Otherwise, we have to conservatively 118468745a55SFangrui Song // make all of the sections retained by the linker. 118568745a55SFangrui Song if (TT.isOSBinFormatELF() || TT.isOSBinFormatMachO() || 118677b435aaSFangrui Song (TT.isOSBinFormatCOFF() && !profDataReferencedByCode(*M))) 1187a84f4fc0SFangrui Song appendToCompilerUsed(*M, CompilerUsedVars); 1188bf176c49SFangrui Song else 1189a84f4fc0SFangrui Song appendToUsed(*M, CompilerUsedVars); 1190a84f4fc0SFangrui Song 1191a84f4fc0SFangrui Song // We do not add proper references from used metadata sections to NamesVar and 1192a84f4fc0SFangrui Song // VNodesVar, so we have to be conservative and place them in llvm.used 1193a84f4fc0SFangrui Song // regardless of the target, 1194ea6d49d3SEvgeniy Stepanov appendToUsed(*M, UsedVars); 119561ba2e39SJustin Bogner } 119661ba2e39SJustin Bogner 119761ba2e39SJustin Bogner void InstrProfiling::emitInitialization() { 11986cdf3d80SRong Xu // Create ProfileFileName variable. Don't don't this for the 11996cdf3d80SRong Xu // context-sensitive instrumentation lowering: This lowering is after 12006cdf3d80SRong Xu // LTO/ThinLTO linking. Pass PGOInstrumentationGenCreateVar should 12016cdf3d80SRong Xu // have already create the variable before LTO/ThinLTO linking. 12026cdf3d80SRong Xu if (!IsCS) 1203ce10d5eaSRong Xu createProfileFileNameVar(*M, Options.InstrProfileOutput); 12047976eb58SJames Y Knight Function *RegisterF = M->getFunction(getInstrProfRegFuncsName()); 12056f8c504fSXinliang David Li if (!RegisterF) 120669a00f06SXinliang David Li return; 120761ba2e39SJustin Bogner 120861ba2e39SJustin Bogner // Create the initialization function. 120961ba2e39SJustin Bogner auto *VoidTy = Type::getVoidTy(M->getContext()); 12108ee08b0fSXinliang David Li auto *F = Function::Create(FunctionType::get(VoidTy, false), 12118ee08b0fSXinliang David Li GlobalValue::InternalLinkage, 12128ee08b0fSXinliang David Li getInstrProfInitFuncName(), M); 121396efdd61SPeter Collingbourne F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 121461ba2e39SJustin Bogner F->addFnAttr(Attribute::NoInline); 121569a00f06SXinliang David Li if (Options.NoRedZone) 121669a00f06SXinliang David Li F->addFnAttr(Attribute::NoRedZone); 121761ba2e39SJustin Bogner 121861ba2e39SJustin Bogner // Add the basic block and the necessary calls. 121961ba2e39SJustin Bogner IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F)); 1220ff6409d0SDavid Blaikie IRB.CreateCall(RegisterF, {}); 122161ba2e39SJustin Bogner IRB.CreateRetVoid(); 122261ba2e39SJustin Bogner 122361ba2e39SJustin Bogner appendToGlobalCtors(*M, F, 0); 122461ba2e39SJustin Bogner } 1225