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