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