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"
2958d9c1aeSEllis Hoag #include "llvm/IR/DIBuilder.h"
3034c23279SEugene Zelenko #include "llvm/IR/DerivedTypes.h"
3158d9c1aeSEllis Hoag #include "llvm/IR/DiagnosticInfo.h"
32b67530e9SXinliang David Li #include "llvm/IR/Dominators.h"
3334c23279SEugene Zelenko #include "llvm/IR/Function.h"
3434c23279SEugene Zelenko #include "llvm/IR/GlobalValue.h"
3534c23279SEugene Zelenko #include "llvm/IR/GlobalVariable.h"
366bda14b3SChandler Carruth #include "llvm/IR/IRBuilder.h"
3734c23279SEugene Zelenko #include "llvm/IR/Instruction.h"
3834c23279SEugene Zelenko #include "llvm/IR/Instructions.h"
3961ba2e39SJustin Bogner #include "llvm/IR/IntrinsicInst.h"
4061ba2e39SJustin Bogner #include "llvm/IR/Module.h"
4134c23279SEugene Zelenko #include "llvm/IR/Type.h"
4205da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
4334c23279SEugene Zelenko #include "llvm/Pass.h"
446fac1741SBetul Buyukkurt #include "llvm/ProfileData/InstrProf.h"
4565d7fd02SEllis Hoag #include "llvm/ProfileData/InstrProfCorrelator.h"
4634c23279SEugene Zelenko #include "llvm/Support/Casting.h"
4734c23279SEugene Zelenko #include "llvm/Support/CommandLine.h"
4834c23279SEugene Zelenko #include "llvm/Support/Error.h"
4934c23279SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
5061ba2e39SJustin Bogner #include "llvm/Transforms/Utils/ModuleUtils.h"
51b67530e9SXinliang David Li #include "llvm/Transforms/Utils/SSAUpdater.h"
5234c23279SEugene Zelenko #include <algorithm>
5334c23279SEugene Zelenko #include <cassert>
5434c23279SEugene Zelenko #include <cstdint>
5534c23279SEugene Zelenko #include <string>
5661ba2e39SJustin Bogner
5761ba2e39SJustin Bogner using namespace llvm;
5861ba2e39SJustin Bogner
5961ba2e39SJustin Bogner #define DEBUG_TYPE "instrprof"
6061ba2e39SJustin Bogner
6158d9c1aeSEllis Hoag namespace llvm {
6258d9c1aeSEllis Hoag cl::opt<bool>
63557efc9aSFangrui Song DebugInfoCorrelate("debug-info-correlate",
6458d9c1aeSEllis Hoag cl::desc("Use debug info to correlate profiles."),
6558d9c1aeSEllis Hoag cl::init(false));
6658d9c1aeSEllis Hoag } // namespace llvm
6758d9c1aeSEllis Hoag
6861ba2e39SJustin Bogner namespace {
6961ba2e39SJustin Bogner
7020f5df1dSRong Xu cl::opt<bool> DoHashBasedCounterSplit(
7120f5df1dSRong Xu "hash-based-counter-split",
7220f5df1dSRong Xu cl::desc("Rename counter variable of a comdat function based on cfg hash"),
7320f5df1dSRong Xu cl::init(true));
7420f5df1dSRong Xu
75b72b5601SRoland McGrath cl::opt<bool>
76b72b5601SRoland McGrath RuntimeCounterRelocation("runtime-counter-relocation",
77d3db13afSPetr Hosek cl::desc("Enable relocating counters at runtime."),
78d3db13afSPetr Hosek cl::init(false));
79d3db13afSPetr Hosek
80b628dd35SXinliang David Li cl::opt<bool> ValueProfileStaticAlloc(
81b628dd35SXinliang David Li "vp-static-alloc",
82b628dd35SXinliang David Li cl::desc("Do static counter allocation for value profiler"),
83b628dd35SXinliang David Li cl::init(true));
8434c23279SEugene Zelenko
85b628dd35SXinliang David Li cl::opt<double> NumCountersPerValueSite(
86b628dd35SXinliang David Li "vp-counters-per-site",
87b628dd35SXinliang David Li cl::desc("The average number of profile counters allocated "
88b628dd35SXinliang David Li "per value profiling site."),
89b628dd35SXinliang David Li // This is set to a very small value because in real programs, only
90b628dd35SXinliang David Li // a very small percentage of value sites have non-zero targets, e.g, 1/30.
91b628dd35SXinliang David Li // For those sites with non-zero profile, the average number of targets
92b628dd35SXinliang David Li // is usually smaller than 2.
93b628dd35SXinliang David Li cl::init(1.0));
94b628dd35SXinliang David Li
95ee6c233aSVedant Kumar cl::opt<bool> AtomicCounterUpdateAll(
96557efc9aSFangrui Song "instrprof-atomic-counter-update-all",
97ee6c233aSVedant Kumar cl::desc("Make all profile counter updates atomic (for testing only)"),
98ee6c233aSVedant Kumar cl::init(false));
99ee6c233aSVedant Kumar
100b67530e9SXinliang David Li cl::opt<bool> AtomicCounterUpdatePromoted(
101557efc9aSFangrui Song "atomic-counter-update-promoted",
102b67530e9SXinliang David Li cl::desc("Do counter update using atomic fetch add "
103b67530e9SXinliang David Li " for promoted counters only"),
104b67530e9SXinliang David Li cl::init(false));
105b67530e9SXinliang David Li
106b4bceb94SRong Xu cl::opt<bool> AtomicFirstCounter(
107557efc9aSFangrui Song "atomic-first-counter",
108b4bceb94SRong Xu cl::desc("Use atomic fetch add for first counter in a function (usually "
109b4bceb94SRong Xu "the entry counter)"),
110b4bceb94SRong Xu cl::init(false));
111b4bceb94SRong Xu
112b67530e9SXinliang David Li // If the option is not specified, the default behavior about whether
113b67530e9SXinliang David Li // counter promotion is done depends on how instrumentaiton lowering
114b67530e9SXinliang David Li // pipeline is setup, i.e., the default value of true of this option
115b67530e9SXinliang David Li // does not mean the promotion will be done by default. Explicitly
116b67530e9SXinliang David Li // setting this option can override the default behavior.
117557efc9aSFangrui Song cl::opt<bool> DoCounterPromotion("do-counter-promotion",
118b67530e9SXinliang David Li cl::desc("Do counter register promotion"),
119b67530e9SXinliang David Li cl::init(false));
120b67530e9SXinliang David Li cl::opt<unsigned> MaxNumOfPromotionsPerLoop(
12195a13425SFangrui Song "max-counter-promotions-per-loop", cl::init(20),
122b67530e9SXinliang David Li cl::desc("Max number counter promotions per loop to avoid"
123b67530e9SXinliang David Li " increasing register pressure too much"));
124b67530e9SXinliang David Li
125b67530e9SXinliang David Li // A debug option
126b67530e9SXinliang David Li cl::opt<int>
127d86a206fSFangrui Song MaxNumOfPromotions("max-counter-promotions", cl::init(-1),
128b67530e9SXinliang David Li cl::desc("Max number of allowed counter promotions"));
129b67530e9SXinliang David Li
130f564c695SXinliang David Li cl::opt<unsigned> SpeculativeCounterPromotionMaxExiting(
131d86a206fSFangrui Song "speculative-counter-promotion-max-exiting", cl::init(3),
132f564c695SXinliang David Li cl::desc("The max number of exiting blocks of a loop to allow "
133f564c695SXinliang David Li " speculative counter promotion"));
134f564c695SXinliang David Li
135f564c695SXinliang David Li cl::opt<bool> SpeculativeCounterPromotionToLoop(
136d86a206fSFangrui Song "speculative-counter-promotion-to-loop",
137f564c695SXinliang David Li cl::desc("When the option is false, if the target block is in a loop, "
138f564c695SXinliang David Li "the promotion will be disallowed unless the promoted counter "
139f564c695SXinliang David Li " update can be further/iteratively promoted into an acyclic "
140f564c695SXinliang David Li " region."));
141f564c695SXinliang David Li
142f564c695SXinliang David Li cl::opt<bool> IterativeCounterPromotion(
143d86a206fSFangrui Song "iterative-counter-promotion", cl::init(true),
144f564c695SXinliang David Li cl::desc("Allow counter promotion across the whole loop nest."));
145b67530e9SXinliang David Li
14631bd15c5SRong Xu cl::opt<bool> SkipRetExitBlock(
147d86a206fSFangrui Song "skip-ret-exit-block", cl::init(true),
14831bd15c5SRong Xu cl::desc("Suppress counter promotion if exit blocks contain ret."));
14931bd15c5SRong Xu
150f564c695SXinliang David Li ///
151b67530e9SXinliang David Li /// A helper class to promote one counter RMW operation in the loop
152b67530e9SXinliang David Li /// into register update.
153b67530e9SXinliang David Li ///
154b67530e9SXinliang David Li /// RWM update for the counter will be sinked out of the loop after
155b67530e9SXinliang David Li /// the transformation.
156b67530e9SXinliang David Li ///
157b67530e9SXinliang David Li class PGOCounterPromoterHelper : public LoadAndStorePromoter {
158b67530e9SXinliang David Li public:
PGOCounterPromoterHelper(Instruction * L,Instruction * S,SSAUpdater & SSA,Value * Init,BasicBlock * PH,ArrayRef<BasicBlock * > ExitBlocks,ArrayRef<Instruction * > InsertPts,DenseMap<Loop *,SmallVector<LoadStorePair,8>> & LoopToCands,LoopInfo & LI)159f564c695SXinliang David Li PGOCounterPromoterHelper(
160f564c695SXinliang David Li Instruction *L, Instruction *S, SSAUpdater &SSA, Value *Init,
161f564c695SXinliang David Li BasicBlock *PH, ArrayRef<BasicBlock *> ExitBlocks,
162f564c695SXinliang David Li ArrayRef<Instruction *> InsertPts,
163f564c695SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCands,
164f564c695SXinliang David Li LoopInfo &LI)
165b67530e9SXinliang David Li : LoadAndStorePromoter({L, S}, SSA), Store(S), ExitBlocks(ExitBlocks),
166f564c695SXinliang David Li InsertPts(InsertPts), LoopToCandidates(LoopToCands), LI(LI) {
167b67530e9SXinliang David Li assert(isa<LoadInst>(L));
168b67530e9SXinliang David Li assert(isa<StoreInst>(S));
169b67530e9SXinliang David Li SSA.AddAvailableValue(PH, Init);
170b67530e9SXinliang David Li }
171f564c695SXinliang David Li
doExtraRewritesBeforeFinalDeletion()1726cba96edSAlina Sbirlea void doExtraRewritesBeforeFinalDeletion() override {
173b67530e9SXinliang David Li for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
174b67530e9SXinliang David Li BasicBlock *ExitBlock = ExitBlocks[i];
175b67530e9SXinliang David Li Instruction *InsertPos = InsertPts[i];
176b67530e9SXinliang David Li // Get LiveIn value into the ExitBlock. If there are multiple
177b67530e9SXinliang David Li // predecessors, the value is defined by a PHI node in this
178b67530e9SXinliang David Li // block.
179b67530e9SXinliang David Li Value *LiveInValue = SSA.GetValueInMiddleOfBlock(ExitBlock);
180b67530e9SXinliang David Li Value *Addr = cast<StoreInst>(Store)->getPointerOperand();
18114359ef1SJames Y Knight Type *Ty = LiveInValue->getType();
182b67530e9SXinliang David Li IRBuilder<> Builder(InsertPos);
1839a90ea1fSEllis Hoag if (auto *AddrInst = dyn_cast_or_null<IntToPtrInst>(Addr)) {
1849a90ea1fSEllis Hoag // If isRuntimeCounterRelocationEnabled() is true then the address of
1859a90ea1fSEllis Hoag // the store instruction is computed with two instructions in
1869a90ea1fSEllis Hoag // InstrProfiling::getCounterAddress(). We need to copy those
1879a90ea1fSEllis Hoag // instructions to this block to compute Addr correctly.
1889a90ea1fSEllis Hoag // %BiasAdd = add i64 ptrtoint <__profc_>, <__llvm_profile_counter_bias>
1899a90ea1fSEllis Hoag // %Addr = inttoptr i64 %BiasAdd to i64*
1909a90ea1fSEllis Hoag auto *OrigBiasInst = dyn_cast<BinaryOperator>(AddrInst->getOperand(0));
1919a90ea1fSEllis Hoag assert(OrigBiasInst->getOpcode() == Instruction::BinaryOps::Add);
1929a90ea1fSEllis Hoag Value *BiasInst = Builder.Insert(OrigBiasInst->clone());
1939a90ea1fSEllis Hoag Addr = Builder.CreateIntToPtr(BiasInst, Ty->getPointerTo());
1949a90ea1fSEllis Hoag }
195b67530e9SXinliang David Li if (AtomicCounterUpdatePromoted)
196f564c695SXinliang David Li // automic update currently can only be promoted across the current
197f564c695SXinliang David Li // loop, not the whole loop nest.
198b67530e9SXinliang David Li Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, LiveInValue,
19924539f1eSJames Y Knight MaybeAlign(),
200b67530e9SXinliang David Li AtomicOrdering::SequentiallyConsistent);
201b67530e9SXinliang David Li else {
20214359ef1SJames Y Knight LoadInst *OldVal = Builder.CreateLoad(Ty, Addr, "pgocount.promoted");
203b67530e9SXinliang David Li auto *NewVal = Builder.CreateAdd(OldVal, LiveInValue);
204f564c695SXinliang David Li auto *NewStore = Builder.CreateStore(NewVal, Addr);
205f564c695SXinliang David Li
206f564c695SXinliang David Li // Now update the parent loop's candidate list:
207f564c695SXinliang David Li if (IterativeCounterPromotion) {
208f564c695SXinliang David Li auto *TargetLoop = LI.getLoopFor(ExitBlock);
209f564c695SXinliang David Li if (TargetLoop)
210f564c695SXinliang David Li LoopToCandidates[TargetLoop].emplace_back(OldVal, NewStore);
211f564c695SXinliang David Li }
212b67530e9SXinliang David Li }
213b67530e9SXinliang David Li }
214b67530e9SXinliang David Li }
215b67530e9SXinliang David Li
216b67530e9SXinliang David Li private:
217b67530e9SXinliang David Li Instruction *Store;
218b67530e9SXinliang David Li ArrayRef<BasicBlock *> ExitBlocks;
219b67530e9SXinliang David Li ArrayRef<Instruction *> InsertPts;
220f564c695SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCandidates;
221f564c695SXinliang David Li LoopInfo &LI;
222b67530e9SXinliang David Li };
223b67530e9SXinliang David Li
224b67530e9SXinliang David Li /// A helper class to do register promotion for all profile counter
225b67530e9SXinliang David Li /// updates in a loop.
226b67530e9SXinliang David Li ///
227b67530e9SXinliang David Li class PGOCounterPromoter {
228b67530e9SXinliang David Li public:
PGOCounterPromoter(DenseMap<Loop *,SmallVector<LoadStorePair,8>> & LoopToCands,Loop & CurLoop,LoopInfo & LI,BlockFrequencyInfo * BFI)229f564c695SXinliang David Li PGOCounterPromoter(
230f564c695SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCands,
2316cdf3d80SRong Xu Loop &CurLoop, LoopInfo &LI, BlockFrequencyInfo *BFI)
232b932bdf5SKazu Hirata : LoopToCandidates(LoopToCands), L(CurLoop), LI(LI), BFI(BFI) {
233b67530e9SXinliang David Li
234a33accdeSAndy Kaylor // Skip collection of ExitBlocks and InsertPts for loops that will not be
235a33accdeSAndy Kaylor // able to have counters promoted.
236b67530e9SXinliang David Li SmallVector<BasicBlock *, 8> LoopExitBlocks;
237b67530e9SXinliang David Li SmallPtrSet<BasicBlock *, 8> BlockSet;
238a33accdeSAndy Kaylor
239f564c695SXinliang David Li L.getExitBlocks(LoopExitBlocks);
240a33accdeSAndy Kaylor if (!isPromotionPossible(&L, LoopExitBlocks))
241a33accdeSAndy Kaylor return;
242b67530e9SXinliang David Li
243b67530e9SXinliang David Li for (BasicBlock *ExitBlock : LoopExitBlocks) {
244b67530e9SXinliang David Li if (BlockSet.insert(ExitBlock).second) {
245b67530e9SXinliang David Li ExitBlocks.push_back(ExitBlock);
246b67530e9SXinliang David Li InsertPts.push_back(&*ExitBlock->getFirstInsertionPt());
247b67530e9SXinliang David Li }
248b67530e9SXinliang David Li }
249b67530e9SXinliang David Li }
250b67530e9SXinliang David Li
run(int64_t * NumPromoted)251b67530e9SXinliang David Li bool run(int64_t *NumPromoted) {
252c23d2c68SXinliang David Li // Skip 'infinite' loops:
253c23d2c68SXinliang David Li if (ExitBlocks.size() == 0)
254c23d2c68SXinliang David Li return false;
25531bd15c5SRong Xu
25631bd15c5SRong Xu // Skip if any of the ExitBlocks contains a ret instruction.
25731bd15c5SRong Xu // This is to prevent dumping of incomplete profile -- if the
25831bd15c5SRong Xu // the loop is a long running loop and dump is called in the middle
25931bd15c5SRong Xu // of the loop, the result profile is incomplete.
26031bd15c5SRong Xu // FIXME: add other heuristics to detect long running loops.
26131bd15c5SRong Xu if (SkipRetExitBlock) {
26231bd15c5SRong Xu for (auto BB : ExitBlocks)
26395ea8658SKazu Hirata if (isa<ReturnInst>(BB->getTerminator()))
26431bd15c5SRong Xu return false;
26531bd15c5SRong Xu }
26631bd15c5SRong Xu
267f564c695SXinliang David Li unsigned MaxProm = getMaxNumOfPromotionsInLoop(&L);
268f564c695SXinliang David Li if (MaxProm == 0)
269b67530e9SXinliang David Li return false;
270b67530e9SXinliang David Li
271b67530e9SXinliang David Li unsigned Promoted = 0;
272f564c695SXinliang David Li for (auto &Cand : LoopToCandidates[&L]) {
273b67530e9SXinliang David Li
274b67530e9SXinliang David Li SmallVector<PHINode *, 4> NewPHIs;
275b67530e9SXinliang David Li SSAUpdater SSA(&NewPHIs);
276b67530e9SXinliang David Li Value *InitVal = ConstantInt::get(Cand.first->getType(), 0);
277f564c695SXinliang David Li
2786cdf3d80SRong Xu // If BFI is set, we will use it to guide the promotions.
2796cdf3d80SRong Xu if (BFI) {
2806cdf3d80SRong Xu auto *BB = Cand.first->getParent();
2816cdf3d80SRong Xu auto InstrCount = BFI->getBlockProfileCount(BB);
2826cdf3d80SRong Xu if (!InstrCount)
2836cdf3d80SRong Xu continue;
2846cdf3d80SRong Xu auto PreheaderCount = BFI->getBlockProfileCount(L.getLoopPreheader());
2856cdf3d80SRong Xu // If the average loop trip count is not greater than 1.5, we skip
2866cdf3d80SRong Xu // promotion.
2877a47ee51SKazu Hirata if (PreheaderCount && (*PreheaderCount * 3) >= (*InstrCount * 2))
2886cdf3d80SRong Xu continue;
2896cdf3d80SRong Xu }
2906cdf3d80SRong Xu
291b67530e9SXinliang David Li PGOCounterPromoterHelper Promoter(Cand.first, Cand.second, SSA, InitVal,
292f564c695SXinliang David Li L.getLoopPreheader(), ExitBlocks,
293f564c695SXinliang David Li InsertPts, LoopToCandidates, LI);
294b67530e9SXinliang David Li Promoter.run(SmallVector<Instruction *, 2>({Cand.first, Cand.second}));
295b67530e9SXinliang David Li Promoted++;
296f564c695SXinliang David Li if (Promoted >= MaxProm)
297b67530e9SXinliang David Li break;
298f564c695SXinliang David Li
299b67530e9SXinliang David Li (*NumPromoted)++;
300b67530e9SXinliang David Li if (MaxNumOfPromotions != -1 && *NumPromoted >= MaxNumOfPromotions)
301b67530e9SXinliang David Li break;
302b67530e9SXinliang David Li }
303b67530e9SXinliang David Li
304d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << Promoted << " counters promoted for loop (depth="
305f564c695SXinliang David Li << L.getLoopDepth() << ")\n");
306b67530e9SXinliang David Li return Promoted != 0;
307b67530e9SXinliang David Li }
308b67530e9SXinliang David Li
309b67530e9SXinliang David Li private:
allowSpeculativeCounterPromotion(Loop * LP)310f564c695SXinliang David Li bool allowSpeculativeCounterPromotion(Loop *LP) {
311f564c695SXinliang David Li SmallVector<BasicBlock *, 8> ExitingBlocks;
312f564c695SXinliang David Li L.getExitingBlocks(ExitingBlocks);
313f564c695SXinliang David Li // Not considierered speculative.
314f564c695SXinliang David Li if (ExitingBlocks.size() == 1)
315f564c695SXinliang David Li return true;
316f564c695SXinliang David Li if (ExitingBlocks.size() > SpeculativeCounterPromotionMaxExiting)
317f564c695SXinliang David Li return false;
318f564c695SXinliang David Li return true;
319f564c695SXinliang David Li }
320f564c695SXinliang David Li
321a33accdeSAndy Kaylor // Check whether the loop satisfies the basic conditions needed to perform
322a33accdeSAndy Kaylor // Counter Promotions.
323b72b5601SRoland McGrath bool
isPromotionPossible(Loop * LP,const SmallVectorImpl<BasicBlock * > & LoopExitBlocks)324b72b5601SRoland McGrath isPromotionPossible(Loop *LP,
325a33accdeSAndy Kaylor const SmallVectorImpl<BasicBlock *> &LoopExitBlocks) {
326f564c695SXinliang David Li // We can't insert into a catchswitch.
327f564c695SXinliang David Li if (llvm::any_of(LoopExitBlocks, [](BasicBlock *Exit) {
328f564c695SXinliang David Li return isa<CatchSwitchInst>(Exit->getTerminator());
329f564c695SXinliang David Li }))
330a33accdeSAndy Kaylor return false;
331f564c695SXinliang David Li
332f564c695SXinliang David Li if (!LP->hasDedicatedExits())
333a33accdeSAndy Kaylor return false;
334f564c695SXinliang David Li
335f564c695SXinliang David Li BasicBlock *PH = LP->getLoopPreheader();
336f564c695SXinliang David Li if (!PH)
337a33accdeSAndy Kaylor return false;
338a33accdeSAndy Kaylor
339a33accdeSAndy Kaylor return true;
340a33accdeSAndy Kaylor }
341a33accdeSAndy Kaylor
342a33accdeSAndy Kaylor // Returns the max number of Counter Promotions for LP.
getMaxNumOfPromotionsInLoop(Loop * LP)343a33accdeSAndy Kaylor unsigned getMaxNumOfPromotionsInLoop(Loop *LP) {
344a33accdeSAndy Kaylor SmallVector<BasicBlock *, 8> LoopExitBlocks;
345a33accdeSAndy Kaylor LP->getExitBlocks(LoopExitBlocks);
346a33accdeSAndy Kaylor if (!isPromotionPossible(LP, LoopExitBlocks))
347f564c695SXinliang David Li return 0;
348f564c695SXinliang David Li
349f564c695SXinliang David Li SmallVector<BasicBlock *, 8> ExitingBlocks;
350f564c695SXinliang David Li LP->getExitingBlocks(ExitingBlocks);
3516cdf3d80SRong Xu
3526cdf3d80SRong Xu // If BFI is set, we do more aggressive promotions based on BFI.
3536cdf3d80SRong Xu if (BFI)
3546cdf3d80SRong Xu return (unsigned)-1;
3556cdf3d80SRong Xu
356f564c695SXinliang David Li // Not considierered speculative.
357f564c695SXinliang David Li if (ExitingBlocks.size() == 1)
358f564c695SXinliang David Li return MaxNumOfPromotionsPerLoop;
359f564c695SXinliang David Li
360f564c695SXinliang David Li if (ExitingBlocks.size() > SpeculativeCounterPromotionMaxExiting)
361f564c695SXinliang David Li return 0;
362f564c695SXinliang David Li
363f564c695SXinliang David Li // Whether the target block is in a loop does not matter:
364f564c695SXinliang David Li if (SpeculativeCounterPromotionToLoop)
365f564c695SXinliang David Li return MaxNumOfPromotionsPerLoop;
366f564c695SXinliang David Li
367f564c695SXinliang David Li // Now check the target block:
368f564c695SXinliang David Li unsigned MaxProm = MaxNumOfPromotionsPerLoop;
369f564c695SXinliang David Li for (auto *TargetBlock : LoopExitBlocks) {
370f564c695SXinliang David Li auto *TargetLoop = LI.getLoopFor(TargetBlock);
371f564c695SXinliang David Li if (!TargetLoop)
372f564c695SXinliang David Li continue;
373f564c695SXinliang David Li unsigned MaxPromForTarget = getMaxNumOfPromotionsInLoop(TargetLoop);
374f564c695SXinliang David Li unsigned PendingCandsInTarget = LoopToCandidates[TargetLoop].size();
375f564c695SXinliang David Li MaxProm =
376f564c695SXinliang David Li std::min(MaxProm, std::max(MaxPromForTarget, PendingCandsInTarget) -
377f564c695SXinliang David Li PendingCandsInTarget);
378f564c695SXinliang David Li }
379f564c695SXinliang David Li return MaxProm;
380f564c695SXinliang David Li }
381f564c695SXinliang David Li
382f564c695SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCandidates;
383b67530e9SXinliang David Li SmallVector<BasicBlock *, 8> ExitBlocks;
384b67530e9SXinliang David Li SmallVector<Instruction *, 8> InsertPts;
385f564c695SXinliang David Li Loop &L;
386f564c695SXinliang David Li LoopInfo &LI;
3876cdf3d80SRong Xu BlockFrequencyInfo *BFI;
388b67530e9SXinliang David Li };
389b67530e9SXinliang David Li
390f78f509cSHiroshi Yamauchi enum class ValueProfilingCallType {
391f78f509cSHiroshi Yamauchi // Individual values are tracked. Currently used for indiret call target
392f78f509cSHiroshi Yamauchi // profiling.
393f78f509cSHiroshi Yamauchi Default,
394f78f509cSHiroshi Yamauchi
3951ebee7adSHiroshi Yamauchi // MemOp: the memop size value profiling.
396f78f509cSHiroshi Yamauchi MemOp
397f78f509cSHiroshi Yamauchi };
398f78f509cSHiroshi Yamauchi
39934c23279SEugene Zelenko } // end anonymous namespace
40061ba2e39SJustin Bogner
run(Module & M,ModuleAnalysisManager & AM)401fd03ac6aSSean Silva PreservedAnalyses InstrProfiling::run(Module &M, ModuleAnalysisManager &AM) {
4029c27b59cSTeresa Johnson FunctionAnalysisManager &FAM =
4039c27b59cSTeresa Johnson AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
4049c27b59cSTeresa Johnson auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
4059c27b59cSTeresa Johnson return FAM.getResult<TargetLibraryAnalysis>(F);
4069c27b59cSTeresa Johnson };
4079c27b59cSTeresa Johnson if (!run(M, GetTLI))
408e6b89294SXinliang David Li return PreservedAnalyses::all();
409e6b89294SXinliang David Li
410e6b89294SXinliang David Li return PreservedAnalyses::none();
411e6b89294SXinliang David Li }
412e6b89294SXinliang David Li
lowerIntrinsics(Function * F)413b67530e9SXinliang David Li bool InstrProfiling::lowerIntrinsics(Function *F) {
414b67530e9SXinliang David Li bool MadeChange = false;
415b67530e9SXinliang David Li PromotionCandidates.clear();
416b67530e9SXinliang David Li for (BasicBlock &BB : *F) {
41724c8eaecSKazu Hirata for (Instruction &Instr : llvm::make_early_inc_range(BB)) {
4185b9358d7SEllis Hoag if (auto *IPIS = dyn_cast<InstrProfIncrementInstStep>(&Instr)) {
4195b9358d7SEllis Hoag lowerIncrement(IPIS);
420b67530e9SXinliang David Li MadeChange = true;
4215b9358d7SEllis Hoag } else if (auto *IPI = dyn_cast<InstrProfIncrementInst>(&Instr)) {
4225b9358d7SEllis Hoag lowerIncrement(IPI);
4235b9358d7SEllis Hoag MadeChange = true;
42411d30742SEllis Hoag } else if (auto *IPC = dyn_cast<InstrProfCoverInst>(&Instr)) {
42511d30742SEllis Hoag lowerCover(IPC);
42611d30742SEllis Hoag MadeChange = true;
4275b9358d7SEllis Hoag } else if (auto *IPVP = dyn_cast<InstrProfValueProfileInst>(&Instr)) {
4285b9358d7SEllis Hoag lowerValueProfileInst(IPVP);
429b67530e9SXinliang David Li MadeChange = true;
430b67530e9SXinliang David Li }
431b67530e9SXinliang David Li }
432b67530e9SXinliang David Li }
433b67530e9SXinliang David Li
434b67530e9SXinliang David Li if (!MadeChange)
435b67530e9SXinliang David Li return false;
436b67530e9SXinliang David Li
437b67530e9SXinliang David Li promoteCounterLoadStores(F);
438b67530e9SXinliang David Li return true;
439b67530e9SXinliang David Li }
440b67530e9SXinliang David Li
isRuntimeCounterRelocationEnabled() const441d3db13afSPetr Hosek bool InstrProfiling::isRuntimeCounterRelocationEnabled() const {
44254902e00SPetr Hosek // Mach-O don't support weak external references.
44354902e00SPetr Hosek if (TT.isOSBinFormatMachO())
44454902e00SPetr Hosek return false;
44554902e00SPetr Hosek
446d3db13afSPetr Hosek if (RuntimeCounterRelocation.getNumOccurrences() > 0)
447d3db13afSPetr Hosek return RuntimeCounterRelocation;
448d3db13afSPetr Hosek
44954902e00SPetr Hosek // Fuchsia uses runtime counter relocation by default.
450d3db13afSPetr Hosek return TT.isOSFuchsia();
451d3db13afSPetr Hosek }
452d3db13afSPetr Hosek
isCounterPromotionEnabled() const453b67530e9SXinliang David Li bool InstrProfiling::isCounterPromotionEnabled() const {
454b67530e9SXinliang David Li if (DoCounterPromotion.getNumOccurrences() > 0)
455b67530e9SXinliang David Li return DoCounterPromotion;
456b67530e9SXinliang David Li
457b67530e9SXinliang David Li return Options.DoCounterPromotion;
458b67530e9SXinliang David Li }
459b67530e9SXinliang David Li
promoteCounterLoadStores(Function * F)460b67530e9SXinliang David Li void InstrProfiling::promoteCounterLoadStores(Function *F) {
461b67530e9SXinliang David Li if (!isCounterPromotionEnabled())
462b67530e9SXinliang David Li return;
463b67530e9SXinliang David Li
464b67530e9SXinliang David Li DominatorTree DT(*F);
465b67530e9SXinliang David Li LoopInfo LI(DT);
466b67530e9SXinliang David Li DenseMap<Loop *, SmallVector<LoadStorePair, 8>> LoopPromotionCandidates;
467b67530e9SXinliang David Li
4686cdf3d80SRong Xu std::unique_ptr<BlockFrequencyInfo> BFI;
4696cdf3d80SRong Xu if (Options.UseBFIInPromotion) {
4706cdf3d80SRong Xu std::unique_ptr<BranchProbabilityInfo> BPI;
4719c27b59cSTeresa Johnson BPI.reset(new BranchProbabilityInfo(*F, LI, &GetTLI(*F)));
4726cdf3d80SRong Xu BFI.reset(new BlockFrequencyInfo(*F, *BPI, LI));
4736cdf3d80SRong Xu }
4746cdf3d80SRong Xu
475b67530e9SXinliang David Li for (const auto &LoadStore : PromotionCandidates) {
476b67530e9SXinliang David Li auto *CounterLoad = LoadStore.first;
477b67530e9SXinliang David Li auto *CounterStore = LoadStore.second;
478b67530e9SXinliang David Li BasicBlock *BB = CounterLoad->getParent();
479b67530e9SXinliang David Li Loop *ParentLoop = LI.getLoopFor(BB);
480b67530e9SXinliang David Li if (!ParentLoop)
481b67530e9SXinliang David Li continue;
482b67530e9SXinliang David Li LoopPromotionCandidates[ParentLoop].emplace_back(CounterLoad, CounterStore);
483b67530e9SXinliang David Li }
484b67530e9SXinliang David Li
485b67530e9SXinliang David Li SmallVector<Loop *, 4> Loops = LI.getLoopsInPreorder();
486b67530e9SXinliang David Li
487f564c695SXinliang David Li // Do a post-order traversal of the loops so that counter updates can be
488f564c695SXinliang David Li // iteratively hoisted outside the loop nest.
489f564c695SXinliang David Li for (auto *Loop : llvm::reverse(Loops)) {
4906cdf3d80SRong Xu PGOCounterPromoter Promoter(LoopPromotionCandidates, *Loop, LI, BFI.get());
491b67530e9SXinliang David Li Promoter.run(&TotalCountersPromoted);
492b67530e9SXinliang David Li }
493b67530e9SXinliang David Li }
494b67530e9SXinliang David Li
needsRuntimeHookUnconditionally(const Triple & TT)495389dc94dSPetr Hosek static bool needsRuntimeHookUnconditionally(const Triple &TT) {
496389dc94dSPetr Hosek // On Fuchsia, we only need runtime hook if any counters are present.
497389dc94dSPetr Hosek if (TT.isOSFuchsia())
498389dc94dSPetr Hosek return false;
499389dc94dSPetr Hosek
500389dc94dSPetr Hosek return true;
501389dc94dSPetr Hosek }
502389dc94dSPetr Hosek
5031ee511c1SVedant Kumar /// Check if the module contains uses of any profiling intrinsics.
containsProfilingIntrinsics(Module & M)5041ee511c1SVedant Kumar static bool containsProfilingIntrinsics(Module &M) {
5055b9358d7SEllis Hoag auto containsIntrinsic = [&](int ID) {
5065b9358d7SEllis Hoag if (auto *F = M.getFunction(Intrinsic::getName(ID)))
5075b9358d7SEllis Hoag return !F->use_empty();
5081ee511c1SVedant Kumar return false;
5095b9358d7SEllis Hoag };
51011d30742SEllis Hoag return containsIntrinsic(llvm::Intrinsic::instrprof_cover) ||
51111d30742SEllis Hoag containsIntrinsic(llvm::Intrinsic::instrprof_increment) ||
5125b9358d7SEllis Hoag containsIntrinsic(llvm::Intrinsic::instrprof_increment_step) ||
5135b9358d7SEllis Hoag containsIntrinsic(llvm::Intrinsic::instrprof_value_profile);
5141ee511c1SVedant Kumar }
5151ee511c1SVedant Kumar
run(Module & M,std::function<const TargetLibraryInfo & (Function & F)> GetTLI)5169c27b59cSTeresa Johnson bool InstrProfiling::run(
5179c27b59cSTeresa Johnson Module &M, std::function<const TargetLibraryInfo &(Function &F)> GetTLI) {
51861ba2e39SJustin Bogner this->M = &M;
5199c27b59cSTeresa Johnson this->GetTLI = std::move(GetTLI);
520a82d6c0aSXinliang David Li NamesVar = nullptr;
521a82d6c0aSXinliang David Li NamesSize = 0;
5226fac1741SBetul Buyukkurt ProfileDataMap.clear();
523a84f4fc0SFangrui Song CompilerUsedVars.clear();
52461ba2e39SJustin Bogner UsedVars.clear();
5251a6a2b64SVedant Kumar TT = Triple(M.getTargetTriple());
52661ba2e39SJustin Bogner
5271c841671SPetr Hosek bool MadeChange = false;
528bcf8f218SGulfem Savrun Yeniceri
529bcf8f218SGulfem Savrun Yeniceri // Emit the runtime hook even if no counters are present.
530bcf8f218SGulfem Savrun Yeniceri if (needsRuntimeHookUnconditionally(TT))
531389dc94dSPetr Hosek MadeChange = emitRuntimeHook();
5329a041a75SVedant Kumar
533bcf8f218SGulfem Savrun Yeniceri // Improve compile time by avoiding linear scans when there is no work.
5349a041a75SVedant Kumar GlobalVariable *CoverageNamesVar =
5359a041a75SVedant Kumar M.getNamedGlobal(getCoverageUnusedNamesVarName());
536bcf8f218SGulfem Savrun Yeniceri if (!containsProfilingIntrinsics(M) && !CoverageNamesVar)
5379a041a75SVedant Kumar return MadeChange;
5389a041a75SVedant Kumar
5396fac1741SBetul Buyukkurt // We did not know how many value sites there would be inside
5406fac1741SBetul Buyukkurt // the instrumented function. This is counting the number of instrumented
5416fac1741SBetul Buyukkurt // target value sites to enter it as field in the profile data variable.
542294572f1SRong Xu for (Function &F : M) {
543294572f1SRong Xu InstrProfIncrementInst *FirstProfIncInst = nullptr;
54461ba2e39SJustin Bogner for (BasicBlock &BB : F)
545294572f1SRong Xu for (auto I = BB.begin(), E = BB.end(); I != E; I++)
546294572f1SRong Xu if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(I))
5476fac1741SBetul Buyukkurt computeNumValueSiteCounts(Ind);
548294572f1SRong Xu else if (FirstProfIncInst == nullptr)
549294572f1SRong Xu FirstProfIncInst = dyn_cast<InstrProfIncrementInst>(I);
550294572f1SRong Xu
551294572f1SRong Xu // Value profiling intrinsic lowering requires per-function profile data
552294572f1SRong Xu // variable to be created first.
553294572f1SRong Xu if (FirstProfIncInst != nullptr)
554294572f1SRong Xu static_cast<void>(getOrCreateRegionCounters(FirstProfIncInst));
555294572f1SRong Xu }
5566fac1741SBetul Buyukkurt
5576fac1741SBetul Buyukkurt for (Function &F : M)
558b67530e9SXinliang David Li MadeChange |= lowerIntrinsics(&F);
5596fac1741SBetul Buyukkurt
5601ee511c1SVedant Kumar if (CoverageNamesVar) {
56181056077SXinliang David Li lowerCoverageData(CoverageNamesVar);
562d24e1857SJustin Bogner MadeChange = true;
563d24e1857SJustin Bogner }
5646fac1741SBetul Buyukkurt
56561ba2e39SJustin Bogner if (!MadeChange)
56661ba2e39SJustin Bogner return false;
56761ba2e39SJustin Bogner
568b628dd35SXinliang David Li emitVNodes();
569a82d6c0aSXinliang David Li emitNameData();
570389dc94dSPetr Hosek emitRuntimeHook();
57161ba2e39SJustin Bogner emitRegistration();
57261ba2e39SJustin Bogner emitUses();
57361ba2e39SJustin Bogner emitInitialization();
57461ba2e39SJustin Bogner return true;
57561ba2e39SJustin Bogner }
57661ba2e39SJustin Bogner
getOrInsertValueProfilingCall(Module & M,const TargetLibraryInfo & TLI,ValueProfilingCallType CallType=ValueProfilingCallType::Default)577f78f509cSHiroshi Yamauchi static FunctionCallee getOrInsertValueProfilingCall(
578f78f509cSHiroshi Yamauchi Module &M, const TargetLibraryInfo &TLI,
579f78f509cSHiroshi Yamauchi ValueProfilingCallType CallType = ValueProfilingCallType::Default) {
580c7673239SXinliang David Li LLVMContext &Ctx = M.getContext();
581c7673239SXinliang David Li auto *ReturnTy = Type::getVoidTy(M.getContext());
58260faea19SRong Xu
58313680223SJames Y Knight AttributeList AL;
58413680223SJames Y Knight if (auto AK = TLI.getExtAttrForI32Param(false))
58513680223SJames Y Knight AL = AL.addParamAttribute(M.getContext(), 2, AK);
58613680223SJames Y Knight
5871ebee7adSHiroshi Yamauchi assert((CallType == ValueProfilingCallType::Default ||
5881ebee7adSHiroshi Yamauchi CallType == ValueProfilingCallType::MemOp) &&
5891ebee7adSHiroshi Yamauchi "Must be Default or MemOp");
590c7673239SXinliang David Li Type *ParamTypes[] = {
591c7673239SXinliang David Li #define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType
592c7673239SXinliang David Li #include "llvm/ProfileData/InstrProfData.inc"
593c7673239SXinliang David Li };
5946fac1741SBetul Buyukkurt auto *ValueProfilingCallTy =
595c7673239SXinliang David Li FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
596f78f509cSHiroshi Yamauchi StringRef FuncName = CallType == ValueProfilingCallType::Default
597f78f509cSHiroshi Yamauchi ? getInstrProfValueProfFuncName()
598f78f509cSHiroshi Yamauchi : getInstrProfValueProfMemOpFuncName();
599f78f509cSHiroshi Yamauchi return M.getOrInsertFunction(FuncName, ValueProfilingCallTy, AL);
6006fac1741SBetul Buyukkurt }
6016fac1741SBetul Buyukkurt
computeNumValueSiteCounts(InstrProfValueProfileInst * Ind)6026fac1741SBetul Buyukkurt void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) {
6036fac1741SBetul Buyukkurt GlobalVariable *Name = Ind->getName();
6046fac1741SBetul Buyukkurt uint64_t ValueKind = Ind->getValueKind()->getZExtValue();
6056fac1741SBetul Buyukkurt uint64_t Index = Ind->getIndex()->getZExtValue();
6069e647806SEllis Hoag auto &PD = ProfileDataMap[Name];
6079e647806SEllis Hoag PD.NumValueSites[ValueKind] =
6089e647806SEllis Hoag std::max(PD.NumValueSites[ValueKind], (uint32_t)(Index + 1));
6096fac1741SBetul Buyukkurt }
6106fac1741SBetul Buyukkurt
lowerValueProfileInst(InstrProfValueProfileInst * Ind)6116fac1741SBetul Buyukkurt void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) {
61258d9c1aeSEllis Hoag // TODO: Value profiling heavily depends on the data section which is omitted
61358d9c1aeSEllis Hoag // in lightweight mode. We need to move the value profile pointer to the
61458d9c1aeSEllis Hoag // Counter struct to get this working.
61558d9c1aeSEllis Hoag assert(
61658d9c1aeSEllis Hoag !DebugInfoCorrelate &&
61758d9c1aeSEllis Hoag "Value profiling is not yet supported with lightweight instrumentation");
6186fac1741SBetul Buyukkurt GlobalVariable *Name = Ind->getName();
6196fac1741SBetul Buyukkurt auto It = ProfileDataMap.find(Name);
6206fac1741SBetul Buyukkurt assert(It != ProfileDataMap.end() && It->second.DataVar &&
6216fac1741SBetul Buyukkurt "value profiling detected in function with no counter incerement");
6226fac1741SBetul Buyukkurt
6236fac1741SBetul Buyukkurt GlobalVariable *DataVar = It->second.DataVar;
6246fac1741SBetul Buyukkurt uint64_t ValueKind = Ind->getValueKind()->getZExtValue();
6256fac1741SBetul Buyukkurt uint64_t Index = Ind->getIndex()->getZExtValue();
6266fac1741SBetul Buyukkurt for (uint32_t Kind = IPVK_First; Kind < ValueKind; ++Kind)
6276fac1741SBetul Buyukkurt Index += It->second.NumValueSites[Kind];
6286fac1741SBetul Buyukkurt
6296fac1741SBetul Buyukkurt IRBuilder<> Builder(Ind);
630f78f509cSHiroshi Yamauchi bool IsMemOpSize = (Ind->getValueKind()->getZExtValue() ==
63160faea19SRong Xu llvm::InstrProfValueKind::IPVK_MemOPSize);
63260faea19SRong Xu CallInst *Call = nullptr;
6339c27b59cSTeresa Johnson auto *TLI = &GetTLI(*Ind->getFunction());
634b35b7da4SAndy Kaylor
635b35b7da4SAndy Kaylor // To support value profiling calls within Windows exception handlers, funclet
636b35b7da4SAndy Kaylor // information contained within operand bundles needs to be copied over to
637b35b7da4SAndy Kaylor // the library call. This is required for the IR to be processed by the
638b35b7da4SAndy Kaylor // WinEHPrepare pass.
639b35b7da4SAndy Kaylor SmallVector<OperandBundleDef, 1> OpBundles;
640b35b7da4SAndy Kaylor Ind->getOperandBundlesAsDefs(OpBundles);
641f78f509cSHiroshi Yamauchi if (!IsMemOpSize) {
6426fac1741SBetul Buyukkurt Value *Args[3] = {Ind->getTargetValue(),
6436fac1741SBetul Buyukkurt Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
6446fac1741SBetul Buyukkurt Builder.getInt32(Index)};
645b35b7da4SAndy Kaylor Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI), Args,
646b35b7da4SAndy Kaylor OpBundles);
6471ebee7adSHiroshi Yamauchi } else {
648f78f509cSHiroshi Yamauchi Value *Args[3] = {Ind->getTargetValue(),
649f78f509cSHiroshi Yamauchi Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
650f78f509cSHiroshi Yamauchi Builder.getInt32(Index)};
651f78f509cSHiroshi Yamauchi Call = Builder.CreateCall(
652f78f509cSHiroshi Yamauchi getOrInsertValueProfilingCall(*M, *TLI, ValueProfilingCallType::MemOp),
653f78f509cSHiroshi Yamauchi Args, OpBundles);
65460faea19SRong Xu }
6551c2bd1e9SMarcin Koscielnicki if (auto AK = TLI->getExtAttrForI32Param(false))
656a0b45f4bSReid Kleckner Call->addParamAttr(2, AK);
6571c2bd1e9SMarcin Koscielnicki Ind->replaceAllUsesWith(Call);
6586fac1741SBetul Buyukkurt Ind->eraseFromParent();
6596fac1741SBetul Buyukkurt }
6606fac1741SBetul Buyukkurt
getCounterAddress(InstrProfInstBase * I)66111d30742SEllis Hoag Value *InstrProfiling::getCounterAddress(InstrProfInstBase *I) {
66211d30742SEllis Hoag auto *Counters = getOrCreateRegionCounters(I);
66311d30742SEllis Hoag IRBuilder<> Builder(I);
66461ba2e39SJustin Bogner
66511d30742SEllis Hoag auto *Addr = Builder.CreateConstInBoundsGEP2_32(
66611d30742SEllis Hoag Counters->getValueType(), Counters, 0, I->getIndex()->getZExtValue());
667ee6c233aSVedant Kumar
66811d30742SEllis Hoag if (!isRuntimeCounterRelocationEnabled())
66911d30742SEllis Hoag return Addr;
67011d30742SEllis Hoag
671d3db13afSPetr Hosek Type *Int64Ty = Type::getInt64Ty(M->getContext());
67211d30742SEllis Hoag Function *Fn = I->getParent()->getParent();
6736e23cd2bSEllis Hoag LoadInst *&BiasLI = FunctionToProfileBiasMap[Fn];
6746e23cd2bSEllis Hoag if (!BiasLI) {
6756e23cd2bSEllis Hoag IRBuilder<> EntryBuilder(&Fn->getEntryBlock().front());
67611d30742SEllis Hoag auto *Bias = M->getGlobalVariable(getInstrProfCounterBiasVarName());
677c0c1c3cfSPetr Hosek if (!Bias) {
678c0c1c3cfSPetr Hosek // Compiler must define this variable when runtime counter relocation
679c0c1c3cfSPetr Hosek // is being used. Runtime has a weak external reference that is used
680c0c1c3cfSPetr Hosek // to check whether that's the case or not.
681b72b5601SRoland McGrath Bias = new GlobalVariable(
682b72b5601SRoland McGrath *M, Int64Ty, false, GlobalValue::LinkOnceODRLinkage,
683b72b5601SRoland McGrath Constant::getNullValue(Int64Ty), getInstrProfCounterBiasVarName());
684c0c1c3cfSPetr Hosek Bias->setVisibility(GlobalVariable::HiddenVisibility);
685c0c1c3cfSPetr Hosek // A definition that's weak (linkonce_odr) without being in a COMDAT
686c0c1c3cfSPetr Hosek // section wouldn't lead to link errors, but it would lead to a dead
687c0c1c3cfSPetr Hosek // data word from every TU but one. Putting it in COMDAT ensures there
688c0c1c3cfSPetr Hosek // will be exactly one data slot in the link.
689c0c1c3cfSPetr Hosek if (TT.supportsCOMDAT())
690c0c1c3cfSPetr Hosek Bias->setComdat(M->getOrInsertComdat(Bias->getName()));
691c0c1c3cfSPetr Hosek }
6926e23cd2bSEllis Hoag BiasLI = EntryBuilder.CreateLoad(Int64Ty, Bias);
693d3db13afSPetr Hosek }
6946e23cd2bSEllis Hoag auto *Add = Builder.CreateAdd(Builder.CreatePtrToInt(Addr, Int64Ty), BiasLI);
69511d30742SEllis Hoag return Builder.CreateIntToPtr(Add, Addr->getType());
696d3db13afSPetr Hosek }
697d3db13afSPetr Hosek
lowerCover(InstrProfCoverInst * CoverInstruction)69811d30742SEllis Hoag void InstrProfiling::lowerCover(InstrProfCoverInst *CoverInstruction) {
69911d30742SEllis Hoag auto *Addr = getCounterAddress(CoverInstruction);
70011d30742SEllis Hoag IRBuilder<> Builder(CoverInstruction);
70111d30742SEllis Hoag // We store zero to represent that this block is covered.
70211d30742SEllis Hoag Builder.CreateStore(Builder.getInt8(0), Addr);
70311d30742SEllis Hoag CoverInstruction->eraseFromParent();
70411d30742SEllis Hoag }
70511d30742SEllis Hoag
lowerIncrement(InstrProfIncrementInst * Inc)70611d30742SEllis Hoag void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
70711d30742SEllis Hoag auto *Addr = getCounterAddress(Inc);
70811d30742SEllis Hoag
70911d30742SEllis Hoag IRBuilder<> Builder(Inc);
710b4bceb94SRong Xu if (Options.Atomic || AtomicCounterUpdateAll ||
71111d30742SEllis Hoag (Inc->getIndex()->isZeroValue() && AtomicFirstCounter)) {
712ee6c233aSVedant Kumar Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, Inc->getStep(),
71324539f1eSJames Y Knight MaybeAlign(), AtomicOrdering::Monotonic);
714ee6c233aSVedant Kumar } else {
71514359ef1SJames Y Knight Value *IncStep = Inc->getStep();
71614359ef1SJames Y Knight Value *Load = Builder.CreateLoad(IncStep->getType(), Addr, "pgocount");
717b67530e9SXinliang David Li auto *Count = Builder.CreateAdd(Load, Inc->getStep());
718b67530e9SXinliang David Li auto *Store = Builder.CreateStore(Count, Addr);
719b67530e9SXinliang David Li if (isCounterPromotionEnabled())
720b67530e9SXinliang David Li PromotionCandidates.emplace_back(cast<Instruction>(Load), Store);
721ee6c233aSVedant Kumar }
72261ba2e39SJustin Bogner Inc->eraseFromParent();
72361ba2e39SJustin Bogner }
72461ba2e39SJustin Bogner
lowerCoverageData(GlobalVariable * CoverageNamesVar)72581056077SXinliang David Li void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageNamesVar) {
72681056077SXinliang David Li ConstantArray *Names =
72781056077SXinliang David Li cast<ConstantArray>(CoverageNamesVar->getInitializer());
72881056077SXinliang David Li for (unsigned I = 0, E = Names->getNumOperands(); I < E; ++I) {
72981056077SXinliang David Li Constant *NC = Names->getOperand(I);
73081056077SXinliang David Li Value *V = NC->stripPointerCasts();
731d24e1857SJustin Bogner assert(isa<GlobalVariable>(V) && "Missing reference to function name");
732d24e1857SJustin Bogner GlobalVariable *Name = cast<GlobalVariable>(V);
733d24e1857SJustin Bogner
734a82d6c0aSXinliang David Li Name->setLinkage(GlobalValue::PrivateLinkage);
735a82d6c0aSXinliang David Li ReferencedNames.push_back(Name);
736ba365561SNikita Popov if (isa<ConstantExpr>(NC))
73755891fc7SVedant Kumar NC->dropAllReferences();
738d24e1857SJustin Bogner }
73955891fc7SVedant Kumar CoverageNamesVar->eraseFromParent();
740d24e1857SJustin Bogner }
741d24e1857SJustin Bogner
74261ba2e39SJustin Bogner /// Get the name of a profiling variable for a particular function.
getVarName(InstrProfInstBase * Inc,StringRef Prefix,bool & Renamed)7435b9358d7SEllis Hoag static std::string getVarName(InstrProfInstBase *Inc, StringRef Prefix,
7449ab9a959SFangrui Song bool &Renamed) {
745d1bab960SXinliang David Li StringRef NamePrefix = getInstrProfNameVarPrefix();
746d1bab960SXinliang David Li StringRef Name = Inc->getName()->getName().substr(NamePrefix.size());
74720f5df1dSRong Xu Function *F = Inc->getParent()->getParent();
74820f5df1dSRong Xu Module *M = F->getParent();
74920f5df1dSRong Xu if (!DoHashBasedCounterSplit || !isIRPGOFlagSet(M) ||
7509ab9a959SFangrui Song !canRenameComdatFunc(*F)) {
7519ab9a959SFangrui Song Renamed = false;
75283bc4220SXinliang David Li return (Prefix + Name).str();
7539ab9a959SFangrui Song }
7549ab9a959SFangrui Song Renamed = true;
75520f5df1dSRong Xu uint64_t FuncHash = Inc->getHash()->getZExtValue();
75620f5df1dSRong Xu SmallVector<char, 24> HashPostfix;
75720f5df1dSRong Xu if (Name.endswith((Twine(".") + Twine(FuncHash)).toStringRef(HashPostfix)))
75820f5df1dSRong Xu return (Prefix + Name).str();
75920f5df1dSRong Xu return (Prefix + Name + "." + Twine(FuncHash)).str();
76061ba2e39SJustin Bogner }
76161ba2e39SJustin Bogner
getIntModuleFlagOrZero(const Module & M,StringRef Flag)7629e51d1f3SFangrui Song static uint64_t getIntModuleFlagOrZero(const Module &M, StringRef Flag) {
7639e51d1f3SFangrui Song auto *MD = dyn_cast_or_null<ConstantAsMetadata>(M.getModuleFlag(Flag));
7648f20ac95SReid Kleckner if (!MD)
7658f20ac95SReid Kleckner return 0;
7668f20ac95SReid Kleckner
7678f20ac95SReid Kleckner // If the flag is a ConstantAsMetadata, it should be an integer representable
7688f20ac95SReid Kleckner // in 64-bits.
7698f20ac95SReid Kleckner return cast<ConstantInt>(MD->getValue())->getZExtValue();
7708f20ac95SReid Kleckner }
7718f20ac95SReid Kleckner
enablesValueProfiling(const Module & M)7729e51d1f3SFangrui Song static bool enablesValueProfiling(const Module &M) {
7739e51d1f3SFangrui Song return isIRPGOFlagSet(&M) ||
7749e51d1f3SFangrui Song getIntModuleFlagOrZero(M, "EnableValueProfiling") != 0;
7759e51d1f3SFangrui Song }
7769e51d1f3SFangrui Song
7779e51d1f3SFangrui Song // Conservatively returns true if data variables may be referenced by code.
profDataReferencedByCode(const Module & M)7789e51d1f3SFangrui Song static bool profDataReferencedByCode(const Module &M) {
7799e51d1f3SFangrui Song return enablesValueProfiling(M);
7809e51d1f3SFangrui Song }
7819e51d1f3SFangrui Song
shouldRecordFunctionAddr(Function * F)7826fac1741SBetul Buyukkurt static inline bool shouldRecordFunctionAddr(Function *F) {
7838f20ac95SReid Kleckner // Only record function addresses if IR PGO is enabled or if clang value
7848f20ac95SReid Kleckner // profiling is enabled. Recording function addresses greatly increases object
7858f20ac95SReid Kleckner // file size, because it prevents the inliner from deleting functions that
7868f20ac95SReid Kleckner // have been inlined everywhere.
7879e51d1f3SFangrui Song if (!profDataReferencedByCode(*F->getParent()))
7888f20ac95SReid Kleckner return false;
7898f20ac95SReid Kleckner
7906fac1741SBetul Buyukkurt // Check the linkage
7919c056c9eSVedant Kumar bool HasAvailableExternallyLinkage = F->hasAvailableExternallyLinkage();
7926fac1741SBetul Buyukkurt if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() &&
7939c056c9eSVedant Kumar !HasAvailableExternallyLinkage)
7946fac1741SBetul Buyukkurt return true;
7959c056c9eSVedant Kumar
7969c056c9eSVedant Kumar // A function marked 'alwaysinline' with available_externally linkage can't
7979c056c9eSVedant Kumar // have its address taken. Doing so would create an undefined external ref to
7989c056c9eSVedant Kumar // the function, which would fail to link.
7999c056c9eSVedant Kumar if (HasAvailableExternallyLinkage &&
8009c056c9eSVedant Kumar F->hasFnAttribute(Attribute::AlwaysInline))
8019c056c9eSVedant Kumar return false;
8029c056c9eSVedant Kumar
803af5aebaaSRong Xu // Prohibit function address recording if the function is both internal and
804af5aebaaSRong Xu // COMDAT. This avoids the profile data variable referencing internal symbols
805af5aebaaSRong Xu // in COMDAT.
806af5aebaaSRong Xu if (F->hasLocalLinkage() && F->hasComdat())
807af5aebaaSRong Xu return false;
8089c056c9eSVedant Kumar
8096fac1741SBetul Buyukkurt // Check uses of this function for other than direct calls or invokes to it.
8107008ce3fSXinliang David Li // Inline virtual functions have linkeOnceODR linkage. When a key method
8117008ce3fSXinliang David Li // exists, the vtable will only be emitted in the TU where the key method
8127008ce3fSXinliang David Li // is defined. In a TU where vtable is not available, the function won't
8136c44e9e3SXinliang David Li // be 'addresstaken'. If its address is not recorded here, the profile data
8146c44e9e3SXinliang David Li // with missing address may be picked by the linker leading to missing
8156c44e9e3SXinliang David Li // indirect call target info.
8166c44e9e3SXinliang David Li return F->hasAddressTaken() || F->hasLinkOnceLinkage();
8176fac1741SBetul Buyukkurt }
8186fac1741SBetul Buyukkurt
needsRuntimeRegistrationOfSectionRange(const Triple & TT)819f21c0223SReid Kleckner static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) {
820b628dd35SXinliang David Li // Don't do this for Darwin. compiler-rt uses linker magic.
821f21c0223SReid Kleckner if (TT.isOSDarwin())
822b628dd35SXinliang David Li return false;
823b628dd35SXinliang David Li // Use linker script magic to get data/cnts/name start/end.
8242407c13aSWael Yehia if (TT.isOSAIX() || TT.isOSLinux() || TT.isOSFreeBSD() || TT.isOSNetBSD() ||
8253dbb5cb2SPaul Robinson TT.isOSSolaris() || TT.isOSFuchsia() || TT.isPS() || TT.isOSWindows())
826b628dd35SXinliang David Li return false;
827b628dd35SXinliang David Li
828b628dd35SXinliang David Li return true;
829b628dd35SXinliang David Li }
830b628dd35SXinliang David Li
83161ba2e39SJustin Bogner GlobalVariable *
createRegionCounters(InstrProfInstBase * Inc,StringRef Name,GlobalValue::LinkageTypes Linkage)83211d30742SEllis Hoag InstrProfiling::createRegionCounters(InstrProfInstBase *Inc, StringRef Name,
83311d30742SEllis Hoag GlobalValue::LinkageTypes Linkage) {
83411d30742SEllis Hoag uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
83511d30742SEllis Hoag auto &Ctx = M->getContext();
83611d30742SEllis Hoag GlobalVariable *GV;
83711d30742SEllis Hoag if (isa<InstrProfCoverInst>(Inc)) {
83811d30742SEllis Hoag auto *CounterTy = Type::getInt8Ty(Ctx);
83911d30742SEllis Hoag auto *CounterArrTy = ArrayType::get(CounterTy, NumCounters);
84011d30742SEllis Hoag // TODO: `Constant::getAllOnesValue()` does not yet accept an array type.
84111d30742SEllis Hoag std::vector<Constant *> InitialValues(NumCounters,
84211d30742SEllis Hoag Constant::getAllOnesValue(CounterTy));
84311d30742SEllis Hoag GV = new GlobalVariable(*M, CounterArrTy, false, Linkage,
84411d30742SEllis Hoag ConstantArray::get(CounterArrTy, InitialValues),
84511d30742SEllis Hoag Name);
84611d30742SEllis Hoag GV->setAlignment(Align(1));
84711d30742SEllis Hoag } else {
84811d30742SEllis Hoag auto *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters);
84911d30742SEllis Hoag GV = new GlobalVariable(*M, CounterTy, false, Linkage,
85011d30742SEllis Hoag Constant::getNullValue(CounterTy), Name);
85111d30742SEllis Hoag GV->setAlignment(Align(8));
85211d30742SEllis Hoag }
85311d30742SEllis Hoag return GV;
85411d30742SEllis Hoag }
85511d30742SEllis Hoag
85611d30742SEllis Hoag GlobalVariable *
getOrCreateRegionCounters(InstrProfInstBase * Inc)8575b9358d7SEllis Hoag InstrProfiling::getOrCreateRegionCounters(InstrProfInstBase *Inc) {
858192c7480SXinliang David Li GlobalVariable *NamePtr = Inc->getName();
8599e647806SEllis Hoag auto &PD = ProfileDataMap[NamePtr];
8609e647806SEllis Hoag if (PD.RegionCounters)
8619e647806SEllis Hoag return PD.RegionCounters;
86261ba2e39SJustin Bogner
86387c43f3aSFangrui Song // Match the linkage and visibility of the name global.
864df4837baSDiego Novillo Function *Fn = Inc->getParent()->getParent();
865987d331fSReid Kleckner GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage();
866987d331fSReid Kleckner GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility();
867987d331fSReid Kleckner
86858d9c1aeSEllis Hoag // Use internal rather than private linkage so the counter variable shows up
86958d9c1aeSEllis Hoag // in the symbol table when using debug info for correlation.
87058d9c1aeSEllis Hoag if (DebugInfoCorrelate && TT.isOSBinFormatMachO() &&
87158d9c1aeSEllis Hoag Linkage == GlobalValue::PrivateLinkage)
87258d9c1aeSEllis Hoag Linkage = GlobalValue::InternalLinkage;
87358d9c1aeSEllis Hoag
87425c30324SJinsong Ji // Due to the limitation of binder as of 2021/09/28, the duplicate weak
87525c30324SJinsong Ji // symbols in the same csect won't be discarded. When there are duplicate weak
87625c30324SJinsong Ji // symbols, we can NOT guarantee that the relocations get resolved to the
87725c30324SJinsong Ji // intended weak symbol, so we can not ensure the correctness of the relative
87825c30324SJinsong Ji // CounterPtr, so we have to use private linkage for counter and data symbols.
87925c30324SJinsong Ji if (TT.isOSBinFormatXCOFF()) {
88025c30324SJinsong Ji Linkage = GlobalValue::PrivateLinkage;
88125c30324SJinsong Ji Visibility = GlobalValue::DefaultVisibility;
88225c30324SJinsong Ji }
883987d331fSReid Kleckner // Move the name variable to the right section. Place them in a COMDAT group
884987d331fSReid Kleckner // if the associated function is a COMDAT. This will make sure that only one
8854fb3502bSReid Kleckner // copy of counters of the COMDAT function will be emitted after linking. Keep
8864fb3502bSReid Kleckner // in mind that this pass may run before the inliner, so we need to create a
8874fb3502bSReid Kleckner // new comdat group for the counters and profiling data. If we use the comdat
8884fb3502bSReid Kleckner // of the parent function, that will result in relocations against discarded
8894fb3502bSReid Kleckner // sections.
89087c43f3aSFangrui Song //
8919e51d1f3SFangrui Song // If the data variable is referenced by code, counters and data have to be
8929e51d1f3SFangrui Song // in different comdats for COFF because the Visual C++ linker will report
8939e51d1f3SFangrui Song // duplicate symbol errors if there are multiple external symbols with the
8949e51d1f3SFangrui Song // same name marked IMAGE_COMDAT_SELECT_ASSOCIATIVE.
89587c43f3aSFangrui Song //
89687c43f3aSFangrui Song // For ELF, when not using COMDAT, put counters, data and values into a
89739248779SFangrui Song // nodeduplicate COMDAT which is lowered to a zero-flag section group. This
89887c43f3aSFangrui Song // allows -z start-stop-gc to discard the entire group when the function is
89987c43f3aSFangrui Song // discarded.
90077b435aaSFangrui Song bool DataReferencedByCode = profDataReferencedByCode(*M);
90187c43f3aSFangrui Song bool NeedComdat = needsComdatForCounter(*Fn, *M);
9029ab9a959SFangrui Song bool Renamed;
9039ab9a959SFangrui Song std::string CntsVarName =
9049ab9a959SFangrui Song getVarName(Inc, getInstrProfCountersVarPrefix(), Renamed);
9059ab9a959SFangrui Song std::string DataVarName =
9069ab9a959SFangrui Song getVarName(Inc, getInstrProfDataVarPrefix(), Renamed);
9079e51d1f3SFangrui Song auto MaybeSetComdat = [&](GlobalVariable *GV) {
90877b435aaSFangrui Song bool UseComdat = (NeedComdat || TT.isOSBinFormatELF());
90977b435aaSFangrui Song if (UseComdat) {
91077b435aaSFangrui Song StringRef GroupName = TT.isOSBinFormatCOFF() && DataReferencedByCode
91177b435aaSFangrui Song ? GV->getName()
91277b435aaSFangrui Song : CntsVarName;
91377b435aaSFangrui Song Comdat *C = M->getOrInsertComdat(GroupName);
914c24b7a16SPetr Hosek if (!NeedComdat)
91539248779SFangrui Song C->setSelectionKind(Comdat::NoDeduplicate);
916c24b7a16SPetr Hosek GV->setComdat(C);
917c24b7a16SPetr Hosek }
91823e872a3SReid Kleckner };
91961ba2e39SJustin Bogner
92061ba2e39SJustin Bogner uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
92161ba2e39SJustin Bogner LLVMContext &Ctx = M->getContext();
92261ba2e39SJustin Bogner
92311d30742SEllis Hoag auto *CounterPtr = createRegionCounters(Inc, CntsVarName, Linkage);
924987d331fSReid Kleckner CounterPtr->setVisibility(Visibility);
9251a6a2b64SVedant Kumar CounterPtr->setSection(
9261a6a2b64SVedant Kumar getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat()));
92723e872a3SReid Kleckner MaybeSetComdat(CounterPtr);
92832837a0cSReid Kleckner CounterPtr->setLinkage(Linkage);
9299e647806SEllis Hoag PD.RegionCounters = CounterPtr;
93058d9c1aeSEllis Hoag if (DebugInfoCorrelate) {
93158d9c1aeSEllis Hoag if (auto *SP = Fn->getSubprogram()) {
93258d9c1aeSEllis Hoag DIBuilder DB(*M, true, SP->getUnit());
93358d9c1aeSEllis Hoag Metadata *FunctionNameAnnotation[] = {
93465d7fd02SEllis Hoag MDString::get(Ctx, InstrProfCorrelator::FunctionNameAttributeName),
93558d9c1aeSEllis Hoag MDString::get(Ctx, getPGOFuncNameVarInitializer(NamePtr)),
93658d9c1aeSEllis Hoag };
93758d9c1aeSEllis Hoag Metadata *CFGHashAnnotation[] = {
93865d7fd02SEllis Hoag MDString::get(Ctx, InstrProfCorrelator::CFGHashAttributeName),
93958d9c1aeSEllis Hoag ConstantAsMetadata::get(Inc->getHash()),
94058d9c1aeSEllis Hoag };
94158d9c1aeSEllis Hoag Metadata *NumCountersAnnotation[] = {
94265d7fd02SEllis Hoag MDString::get(Ctx, InstrProfCorrelator::NumCountersAttributeName),
94358d9c1aeSEllis Hoag ConstantAsMetadata::get(Inc->getNumCounters()),
94458d9c1aeSEllis Hoag };
94558d9c1aeSEllis Hoag auto Annotations = DB.getOrCreateArray({
94658d9c1aeSEllis Hoag MDNode::get(Ctx, FunctionNameAnnotation),
94758d9c1aeSEllis Hoag MDNode::get(Ctx, CFGHashAnnotation),
94858d9c1aeSEllis Hoag MDNode::get(Ctx, NumCountersAnnotation),
94958d9c1aeSEllis Hoag });
95058d9c1aeSEllis Hoag auto *DICounter = DB.createGlobalVariableExpression(
95158d9c1aeSEllis Hoag SP, CounterPtr->getName(), /*LinkageName=*/StringRef(), SP->getFile(),
95258d9c1aeSEllis Hoag /*LineNo=*/0, DB.createUnspecifiedType("Profile Data Type"),
95358d9c1aeSEllis Hoag CounterPtr->hasLocalLinkage(), /*IsDefined=*/true, /*Expr=*/nullptr,
95458d9c1aeSEllis Hoag /*Decl=*/nullptr, /*TemplateParams=*/nullptr, /*AlignInBits=*/0,
95558d9c1aeSEllis Hoag Annotations);
95658d9c1aeSEllis Hoag CounterPtr->addDebugInfo(DICounter);
95758d9c1aeSEllis Hoag DB.finalize();
95858d9c1aeSEllis Hoag } else {
95958d9c1aeSEllis Hoag std::string Msg = ("Missing debug info for function " + Fn->getName() +
96058d9c1aeSEllis Hoag "; required for profile correlation.")
96158d9c1aeSEllis Hoag .str();
96258d9c1aeSEllis Hoag Ctx.diagnose(
96358d9c1aeSEllis Hoag DiagnosticInfoPGOProfile(M->getName().data(), Msg, DS_Warning));
96458d9c1aeSEllis Hoag }
96558d9c1aeSEllis Hoag }
96661ba2e39SJustin Bogner
9676fac1741SBetul Buyukkurt auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
968b628dd35SXinliang David Li // Allocate statically the array of pointers to value profile nodes for
969b628dd35SXinliang David Li // the current function.
970b628dd35SXinliang David Li Constant *ValuesPtrExpr = ConstantPointerNull::get(Int8PtrTy);
971b628dd35SXinliang David Li uint64_t NS = 0;
972b628dd35SXinliang David Li for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
973b628dd35SXinliang David Li NS += PD.NumValueSites[Kind];
9743307240fSFangrui Song if (NS > 0 && ValueProfileStaticAlloc &&
9753307240fSFangrui Song !needsRuntimeRegistrationOfSectionRange(TT)) {
976b628dd35SXinliang David Li ArrayType *ValuesTy = ArrayType::get(Type::getInt64Ty(Ctx), NS);
9773307240fSFangrui Song auto *ValuesVar = new GlobalVariable(
9783307240fSFangrui Song *M, ValuesTy, false, Linkage, Constant::getNullValue(ValuesTy),
9799ab9a959SFangrui Song getVarName(Inc, getInstrProfValuesVarPrefix(), Renamed));
980987d331fSReid Kleckner ValuesVar->setVisibility(Visibility);
9811a6a2b64SVedant Kumar ValuesVar->setSection(
9821a6a2b64SVedant Kumar getInstrProfSectionName(IPSK_vals, TT.getObjectFormat()));
9830e62011dSGuillaume Chatelet ValuesVar->setAlignment(Align(8));
98423e872a3SReid Kleckner MaybeSetComdat(ValuesVar);
985b628dd35SXinliang David Li ValuesPtrExpr =
98634c23279SEugene Zelenko ConstantExpr::getBitCast(ValuesVar, Type::getInt8PtrTy(Ctx));
987b628dd35SXinliang David Li }
988b628dd35SXinliang David Li
989a699b2f1SEllis Hoag if (DebugInfoCorrelate) {
990a699b2f1SEllis Hoag // Mark the counter variable as used so that it isn't optimized out.
991a699b2f1SEllis Hoag CompilerUsedVars.push_back(PD.RegionCounters);
99258d9c1aeSEllis Hoag return PD.RegionCounters;
993a699b2f1SEllis Hoag }
99458d9c1aeSEllis Hoag
995b628dd35SXinliang David Li // Create data variable.
996a1532ed2SFangrui Song auto *IntPtrTy = M->getDataLayout().getIntPtrType(M->getContext());
9976fac1741SBetul Buyukkurt auto *Int16Ty = Type::getInt16Ty(Ctx);
9986fac1741SBetul Buyukkurt auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last + 1);
999192c7480SXinliang David Li Type *DataTypes[] = {
1000192c7480SXinliang David Li #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType,
1001192c7480SXinliang David Li #include "llvm/ProfileData/InstrProfData.inc"
1002192c7480SXinliang David Li };
100361ba2e39SJustin Bogner auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes));
1004192c7480SXinliang David Li
100569a00f06SXinliang David Li Constant *FunctionAddr = shouldRecordFunctionAddr(Fn)
100669a00f06SXinliang David Li ? ConstantExpr::getBitCast(Fn, Int8PtrTy)
100769a00f06SXinliang David Li : ConstantPointerNull::get(Int8PtrTy);
10086fac1741SBetul Buyukkurt
10096fac1741SBetul Buyukkurt Constant *Int16ArrayVals[IPVK_Last + 1];
10106fac1741SBetul Buyukkurt for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
10116fac1741SBetul Buyukkurt Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]);
10126fac1741SBetul Buyukkurt
10133307240fSFangrui Song // If the data variable is not referenced by code (if we don't emit
10143307240fSFangrui Song // @llvm.instrprof.value.profile, NS will be 0), and the counter keeps the
10153307240fSFangrui Song // data variable live under linker GC, the data variable can be private. This
101677b435aaSFangrui Song // optimization applies to ELF.
101777b435aaSFangrui Song //
101877b435aaSFangrui Song // On COFF, a comdat leader cannot be local so we require DataReferencedByCode
101977b435aaSFangrui Song // to be false.
10209ab9a959SFangrui Song //
10219ab9a959SFangrui Song // If profd is in a deduplicate comdat, NS==0 with a hash suffix guarantees
10229ab9a959SFangrui Song // that other copies must have the same CFG and cannot have value profiling.
10239ab9a959SFangrui Song // If no hash suffix, other profd copies may be referenced by code.
10249ab9a959SFangrui Song if (NS == 0 && !(DataReferencedByCode && NeedComdat && !Renamed) &&
10259ab9a959SFangrui Song (TT.isOSBinFormatELF() ||
102677b435aaSFangrui Song (!DataReferencedByCode && TT.isOSBinFormatCOFF()))) {
10279e51d1f3SFangrui Song Linkage = GlobalValue::PrivateLinkage;
10289e51d1f3SFangrui Song Visibility = GlobalValue::DefaultVisibility;
10299e51d1f3SFangrui Song }
1030e56626e4SFangrui Song auto *Data =
1031a1532ed2SFangrui Song new GlobalVariable(*M, DataTy, false, Linkage, nullptr, DataVarName);
1032a1532ed2SFangrui Song // Reference the counter variable with a label difference (link-time
1033a1532ed2SFangrui Song // constant).
1034a1532ed2SFangrui Song auto *RelativeCounterPtr =
1035a1532ed2SFangrui Song ConstantExpr::getSub(ConstantExpr::getPtrToInt(CounterPtr, IntPtrTy),
1036a1532ed2SFangrui Song ConstantExpr::getPtrToInt(Data, IntPtrTy));
1037a1532ed2SFangrui Song
1038a1532ed2SFangrui Song Constant *DataVals[] = {
1039a1532ed2SFangrui Song #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init,
1040a1532ed2SFangrui Song #include "llvm/ProfileData/InstrProfData.inc"
1041a1532ed2SFangrui Song };
1042a1532ed2SFangrui Song Data->setInitializer(ConstantStruct::get(DataTy, DataVals));
1043a1532ed2SFangrui Song
1044987d331fSReid Kleckner Data->setVisibility(Visibility);
10451a6a2b64SVedant Kumar Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat()));
10460e62011dSGuillaume Chatelet Data->setAlignment(Align(INSTR_PROF_DATA_ALIGNMENT));
104723e872a3SReid Kleckner MaybeSetComdat(Data);
104832837a0cSReid Kleckner Data->setLinkage(Linkage);
104961ba2e39SJustin Bogner
10506fac1741SBetul Buyukkurt PD.DataVar = Data;
10516fac1741SBetul Buyukkurt
105261ba2e39SJustin Bogner // Mark the data variable as used so that it isn't stripped out.
1053a84f4fc0SFangrui Song CompilerUsedVars.push_back(Data);
1054a82d6c0aSXinliang David Li // Now that the linkage set by the FE has been passed to the data and counter
1055a82d6c0aSXinliang David Li // variables, reset Name variable's linkage and visibility to private so that
1056a82d6c0aSXinliang David Li // it can be removed later by the compiler.
1057a82d6c0aSXinliang David Li NamePtr->setLinkage(GlobalValue::PrivateLinkage);
1058a82d6c0aSXinliang David Li // Collect the referenced names to be used by emitNameData.
1059a82d6c0aSXinliang David Li ReferencedNames.push_back(NamePtr);
106061ba2e39SJustin Bogner
10619e647806SEllis Hoag return PD.RegionCounters;
106261ba2e39SJustin Bogner }
106361ba2e39SJustin Bogner
emitVNodes()1064b628dd35SXinliang David Li void InstrProfiling::emitVNodes() {
1065b628dd35SXinliang David Li if (!ValueProfileStaticAlloc)
1066b628dd35SXinliang David Li return;
10678da773bfSXinliang David Li
1068b628dd35SXinliang David Li // For now only support this on platforms that do
1069b628dd35SXinliang David Li // not require runtime registration to discover
1070b628dd35SXinliang David Li // named section start/end.
1071f21c0223SReid Kleckner if (needsRuntimeRegistrationOfSectionRange(TT))
1072b628dd35SXinliang David Li return;
10738da773bfSXinliang David Li
1074b628dd35SXinliang David Li size_t TotalNS = 0;
1075b628dd35SXinliang David Li for (auto &PD : ProfileDataMap) {
1076b628dd35SXinliang David Li for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
1077b628dd35SXinliang David Li TotalNS += PD.second.NumValueSites[Kind];
1078b628dd35SXinliang David Li }
1079b628dd35SXinliang David Li
1080b628dd35SXinliang David Li if (!TotalNS)
1081b628dd35SXinliang David Li return;
1082b628dd35SXinliang David Li
1083b628dd35SXinliang David Li uint64_t NumCounters = TotalNS * NumCountersPerValueSite;
1084b628dd35SXinliang David Li // Heuristic for small programs with very few total value sites.
1085b628dd35SXinliang David Li // The default value of vp-counters-per-site is chosen based on
1086b628dd35SXinliang David Li // the observation that large apps usually have a low percentage
1087b628dd35SXinliang David Li // of value sites that actually have any profile data, and thus
1088b628dd35SXinliang David Li // the average number of counters per site is low. For small
1089b628dd35SXinliang David Li // apps with very few sites, this may not be true. Bump up the
1090b628dd35SXinliang David Li // number of counters in this case.
1091e4520760SXinliang David Li #define INSTR_PROF_MIN_VAL_COUNTS 10
1092e4520760SXinliang David Li if (NumCounters < INSTR_PROF_MIN_VAL_COUNTS)
1093e4520760SXinliang David Li NumCounters = std::max(INSTR_PROF_MIN_VAL_COUNTS, (int)NumCounters * 2);
1094b628dd35SXinliang David Li
1095b628dd35SXinliang David Li auto &Ctx = M->getContext();
1096b628dd35SXinliang David Li Type *VNodeTypes[] = {
1097b628dd35SXinliang David Li #define INSTR_PROF_VALUE_NODE(Type, LLVMType, Name, Init) LLVMType,
1098b628dd35SXinliang David Li #include "llvm/ProfileData/InstrProfData.inc"
1099b628dd35SXinliang David Li };
1100b628dd35SXinliang David Li auto *VNodeTy = StructType::get(Ctx, makeArrayRef(VNodeTypes));
1101b628dd35SXinliang David Li
1102b628dd35SXinliang David Li ArrayType *VNodesTy = ArrayType::get(VNodeTy, NumCounters);
1103b628dd35SXinliang David Li auto *VNodesVar = new GlobalVariable(
110434c23279SEugene Zelenko *M, VNodesTy, false, GlobalValue::PrivateLinkage,
1105b628dd35SXinliang David Li Constant::getNullValue(VNodesTy), getInstrProfVNodesVarName());
11061a6a2b64SVedant Kumar VNodesVar->setSection(
11071a6a2b64SVedant Kumar getInstrProfSectionName(IPSK_vnodes, TT.getObjectFormat()));
1108a84f4fc0SFangrui Song // VNodesVar is used by runtime but not referenced via relocation by other
1109a84f4fc0SFangrui Song // sections. Conservatively make it linker retained.
1110b628dd35SXinliang David Li UsedVars.push_back(VNodesVar);
11118da773bfSXinliang David Li }
11128da773bfSXinliang David Li
emitNameData()1113a82d6c0aSXinliang David Li void InstrProfiling::emitNameData() {
1114a82d6c0aSXinliang David Li std::string UncompressedData;
1115a82d6c0aSXinliang David Li
1116a82d6c0aSXinliang David Li if (ReferencedNames.empty())
1117a82d6c0aSXinliang David Li return;
1118a82d6c0aSXinliang David Li
1119a82d6c0aSXinliang David Li std::string CompressedNameStr;
11209152fd17SVedant Kumar if (Error E = collectPGOFuncNameStrings(ReferencedNames, CompressedNameStr,
1121dd1ea9deSVedant Kumar DoInstrProfNameCompression)) {
112221661607SSimon Pilgrim report_fatal_error(Twine(toString(std::move(E))), false);
112343cba733SVedant Kumar }
1124a82d6c0aSXinliang David Li
1125a82d6c0aSXinliang David Li auto &Ctx = M->getContext();
1126b72b5601SRoland McGrath auto *NamesVal =
1127b72b5601SRoland McGrath ConstantDataArray::getString(Ctx, StringRef(CompressedNameStr), false);
112834c23279SEugene Zelenko NamesVar = new GlobalVariable(*M, NamesVal->getType(), true,
112934c23279SEugene Zelenko GlobalValue::PrivateLinkage, NamesVal,
113034c23279SEugene Zelenko getInstrProfNamesVarName());
1131a82d6c0aSXinliang David Li NamesSize = CompressedNameStr.size();
11321a6a2b64SVedant Kumar NamesVar->setSection(
11331a6a2b64SVedant Kumar getInstrProfSectionName(IPSK_name, TT.getObjectFormat()));
1134987d331fSReid Kleckner // On COFF, it's important to reduce the alignment down to 1 to prevent the
1135987d331fSReid Kleckner // linker from inserting padding before the start of the names section or
1136987d331fSReid Kleckner // between names entries.
1137805c157eSGuillaume Chatelet NamesVar->setAlignment(Align(1));
1138a84f4fc0SFangrui Song // NamesVar is used by runtime but not referenced via relocation by other
1139a84f4fc0SFangrui Song // sections. Conservatively make it linker retained.
1140a82d6c0aSXinliang David Li UsedVars.push_back(NamesVar);
114155891fc7SVedant Kumar
114255891fc7SVedant Kumar for (auto *NamePtr : ReferencedNames)
114355891fc7SVedant Kumar NamePtr->eraseFromParent();
1144a82d6c0aSXinliang David Li }
1145a82d6c0aSXinliang David Li
emitRegistration()114661ba2e39SJustin Bogner void InstrProfiling::emitRegistration() {
1147f21c0223SReid Kleckner if (!needsRuntimeRegistrationOfSectionRange(TT))
1148aa0592ccSXinliang David Li return;
11493dd8817dSXinliang David Li
115061ba2e39SJustin Bogner // Construct the function.
115161ba2e39SJustin Bogner auto *VoidTy = Type::getVoidTy(M->getContext());
115261ba2e39SJustin Bogner auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext());
1153a82d6c0aSXinliang David Li auto *Int64Ty = Type::getInt64Ty(M->getContext());
115461ba2e39SJustin Bogner auto *RegisterFTy = FunctionType::get(VoidTy, false);
115561ba2e39SJustin Bogner auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage,
11568ee08b0fSXinliang David Li getInstrProfRegFuncsName(), M);
115796efdd61SPeter Collingbourne RegisterF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
115869a00f06SXinliang David Li if (Options.NoRedZone)
115969a00f06SXinliang David Li RegisterF->addFnAttr(Attribute::NoRedZone);
116061ba2e39SJustin Bogner
1161b3029d26SDiego Novillo auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false);
116261ba2e39SJustin Bogner auto *RuntimeRegisterF =
116361ba2e39SJustin Bogner Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage,
11648ee08b0fSXinliang David Li getInstrProfRegFuncName(), M);
116561ba2e39SJustin Bogner
116661ba2e39SJustin Bogner IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", RegisterF));
1167a84f4fc0SFangrui Song for (Value *Data : CompilerUsedVars)
1168a84f4fc0SFangrui Song if (!isa<Function>(Data))
1169a84f4fc0SFangrui Song IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy));
117061ba2e39SJustin Bogner for (Value *Data : UsedVars)
1171ba82788fSReid Kleckner if (Data != NamesVar && !isa<Function>(Data))
117261ba2e39SJustin Bogner IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy));
1173a82d6c0aSXinliang David Li
1174a82d6c0aSXinliang David Li if (NamesVar) {
1175a82d6c0aSXinliang David Li Type *ParamTypes[] = {VoidPtrTy, Int64Ty};
1176a82d6c0aSXinliang David Li auto *NamesRegisterTy =
1177a82d6c0aSXinliang David Li FunctionType::get(VoidTy, makeArrayRef(ParamTypes), false);
1178a82d6c0aSXinliang David Li auto *NamesRegisterF =
1179a82d6c0aSXinliang David Li Function::Create(NamesRegisterTy, GlobalVariable::ExternalLinkage,
1180a82d6c0aSXinliang David Li getInstrProfNamesRegFuncName(), M);
1181a82d6c0aSXinliang David Li IRB.CreateCall(NamesRegisterF, {IRB.CreateBitCast(NamesVar, VoidPtrTy),
1182a82d6c0aSXinliang David Li IRB.getInt64(NamesSize)});
1183a82d6c0aSXinliang David Li }
1184a82d6c0aSXinliang David Li
118561ba2e39SJustin Bogner IRB.CreateRetVoid();
118661ba2e39SJustin Bogner }
118761ba2e39SJustin Bogner
emitRuntimeHook()11889a041a75SVedant Kumar bool InstrProfiling::emitRuntimeHook() {
1189389dc94dSPetr Hosek // We expect the linker to be invoked with -u<hook_var> flag for Linux
1190389dc94dSPetr Hosek // in which case there is no need to emit the external variable.
1191389dc94dSPetr Hosek if (TT.isOSLinux())
1192f50aef74SHans Wennborg return false;
1193f50aef74SHans Wennborg
119461ba2e39SJustin Bogner // If the module's provided its own runtime, we don't need to do anything.
119569a00f06SXinliang David Li if (M->getGlobalVariable(getInstrProfRuntimeHookVarName()))
11969a041a75SVedant Kumar return false;
119761ba2e39SJustin Bogner
119861ba2e39SJustin Bogner // Declare an external variable that will pull in the runtime initialization.
119961ba2e39SJustin Bogner auto *Int32Ty = Type::getInt32Ty(M->getContext());
120061ba2e39SJustin Bogner auto *Var =
120161ba2e39SJustin Bogner new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
12028ee08b0fSXinliang David Li nullptr, getInstrProfRuntimeHookVarName());
1203*3d438ceeSJustin Cady Var->setVisibility(GlobalValue::HiddenVisibility);
120461ba2e39SJustin Bogner
12053f603025SPaul Robinson if (TT.isOSBinFormatELF() && !TT.isPS()) {
1206389dc94dSPetr Hosek // Mark the user variable as used so that it isn't stripped out.
1207389dc94dSPetr Hosek CompilerUsedVars.push_back(Var);
1208389dc94dSPetr Hosek } else {
1209f50aef74SHans Wennborg // Make a function that uses it.
1210f50aef74SHans Wennborg auto *User = Function::Create(FunctionType::get(Int32Ty, false),
1211f50aef74SHans Wennborg GlobalValue::LinkOnceODRLinkage,
1212f50aef74SHans Wennborg getInstrProfRuntimeHookVarUseFuncName(), M);
1213f50aef74SHans Wennborg User->addFnAttr(Attribute::NoInline);
1214f50aef74SHans Wennborg if (Options.NoRedZone)
1215f50aef74SHans Wennborg User->addFnAttr(Attribute::NoRedZone);
1216f50aef74SHans Wennborg User->setVisibility(GlobalValue::HiddenVisibility);
1217f50aef74SHans Wennborg if (TT.supportsCOMDAT())
1218f50aef74SHans Wennborg User->setComdat(M->getOrInsertComdat(User->getName()));
1219f50aef74SHans Wennborg
1220f50aef74SHans Wennborg IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", User));
1221f50aef74SHans Wennborg auto *Load = IRB.CreateLoad(Int32Ty, Var);
1222f50aef74SHans Wennborg IRB.CreateRet(Load);
1223f50aef74SHans Wennborg
1224389dc94dSPetr Hosek // Mark the function as used so that it isn't stripped out.
1225f50aef74SHans Wennborg CompilerUsedVars.push_back(User);
1226389dc94dSPetr Hosek }
12279a041a75SVedant Kumar return true;
122861ba2e39SJustin Bogner }
122961ba2e39SJustin Bogner
emitUses()123061ba2e39SJustin Bogner void InstrProfiling::emitUses() {
1231bf176c49SFangrui Song // The metadata sections are parallel arrays. Optimizers (e.g.
1232bf176c49SFangrui Song // GlobalOpt/ConstantMerge) may not discard associated sections as a unit, so
1233bf176c49SFangrui Song // we conservatively retain all unconditionally in the compiler.
1234bf176c49SFangrui Song //
123568745a55SFangrui Song // On ELF and Mach-O, the linker can guarantee the associated sections will be
123668745a55SFangrui Song // retained or discarded as a unit, so llvm.compiler.used is sufficient.
123768745a55SFangrui Song // Similarly on COFF, if prof data is not referenced by code we use one comdat
123868745a55SFangrui Song // and ensure this GC property as well. Otherwise, we have to conservatively
123968745a55SFangrui Song // make all of the sections retained by the linker.
124068745a55SFangrui Song if (TT.isOSBinFormatELF() || TT.isOSBinFormatMachO() ||
124177b435aaSFangrui Song (TT.isOSBinFormatCOFF() && !profDataReferencedByCode(*M)))
1242a84f4fc0SFangrui Song appendToCompilerUsed(*M, CompilerUsedVars);
1243bf176c49SFangrui Song else
1244a84f4fc0SFangrui Song appendToUsed(*M, CompilerUsedVars);
1245a84f4fc0SFangrui Song
1246a84f4fc0SFangrui Song // We do not add proper references from used metadata sections to NamesVar and
1247a84f4fc0SFangrui Song // VNodesVar, so we have to be conservative and place them in llvm.used
1248a84f4fc0SFangrui Song // regardless of the target,
1249ea6d49d3SEvgeniy Stepanov appendToUsed(*M, UsedVars);
125061ba2e39SJustin Bogner }
125161ba2e39SJustin Bogner
emitInitialization()125261ba2e39SJustin Bogner void InstrProfiling::emitInitialization() {
12536cdf3d80SRong Xu // Create ProfileFileName variable. Don't don't this for the
12546cdf3d80SRong Xu // context-sensitive instrumentation lowering: This lowering is after
12556cdf3d80SRong Xu // LTO/ThinLTO linking. Pass PGOInstrumentationGenCreateVar should
12566cdf3d80SRong Xu // have already create the variable before LTO/ThinLTO linking.
12576cdf3d80SRong Xu if (!IsCS)
1258ce10d5eaSRong Xu createProfileFileNameVar(*M, Options.InstrProfileOutput);
12597976eb58SJames Y Knight Function *RegisterF = M->getFunction(getInstrProfRegFuncsName());
12606f8c504fSXinliang David Li if (!RegisterF)
126169a00f06SXinliang David Li return;
126261ba2e39SJustin Bogner
126361ba2e39SJustin Bogner // Create the initialization function.
126461ba2e39SJustin Bogner auto *VoidTy = Type::getVoidTy(M->getContext());
12658ee08b0fSXinliang David Li auto *F = Function::Create(FunctionType::get(VoidTy, false),
12668ee08b0fSXinliang David Li GlobalValue::InternalLinkage,
12678ee08b0fSXinliang David Li getInstrProfInitFuncName(), M);
126896efdd61SPeter Collingbourne F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
126961ba2e39SJustin Bogner F->addFnAttr(Attribute::NoInline);
127069a00f06SXinliang David Li if (Options.NoRedZone)
127169a00f06SXinliang David Li F->addFnAttr(Attribute::NoRedZone);
127261ba2e39SJustin Bogner
127361ba2e39SJustin Bogner // Add the basic block and the necessary calls.
127461ba2e39SJustin Bogner IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F));
1275ff6409d0SDavid Blaikie IRB.CreateCall(RegisterF, {});
127661ba2e39SJustin Bogner IRB.CreateRetVoid();
127761ba2e39SJustin Bogner
127861ba2e39SJustin Bogner appendToGlobalCtors(*M, F, 0);
127961ba2e39SJustin Bogner }
1280