blob: 4e99df86ed6ecf9affcb95edbd234f9d1bcadce6 [file] [log] [blame]
Justin Bogner61ba2e32014-12-08 18:02:35 +00001//===-- InstrProfiling.cpp - Frontend instrumentation based profiling -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Betul Buyukkurt6fac1742015-11-18 18:14:55 +000010// This pass lowers instrprof_* intrinsics emitted by a frontend for profiling.
11// It also builds the data structures and initialization code needed for
12// updating execution counts and emitting the profile at runtime.
Justin Bogner61ba2e32014-12-08 18:02:35 +000013//
14//===----------------------------------------------------------------------===//
15
Justin Bogner61ba2e32014-12-08 18:02:35 +000016#include "llvm/ADT/Triple.h"
17#include "llvm/IR/IRBuilder.h"
18#include "llvm/IR/IntrinsicInst.h"
19#include "llvm/IR/Module.h"
Betul Buyukkurt6fac1742015-11-18 18:14:55 +000020#include "llvm/ProfileData/InstrProf.h"
21#include "llvm/Transforms/Instrumentation.h"
Justin Bogner61ba2e32014-12-08 18:02:35 +000022#include "llvm/Transforms/Utils/ModuleUtils.h"
23
24using namespace llvm;
25
26#define DEBUG_TYPE "instrprof"
27
28namespace {
29
Xinliang David Lia82d6c02016-02-08 18:13:49 +000030cl::opt<bool> DoNameCompression("enable-name-compression",
31 cl::desc("Enable name string compression"),
32 cl::init(true));
33
Justin Bogner61ba2e32014-12-08 18:02:35 +000034class InstrProfiling : public ModulePass {
35public:
36 static char ID;
37
38 InstrProfiling() : ModulePass(ID) {}
39
40 InstrProfiling(const InstrProfOptions &Options)
41 : ModulePass(ID), Options(Options) {}
42
43 const char *getPassName() const override {
44 return "Frontend instrumentation-based coverage lowering";
45 }
46
47 bool runOnModule(Module &M) override;
48
49 void getAnalysisUsage(AnalysisUsage &AU) const override {
50 AU.setPreservesCFG();
51 }
52
53private:
54 InstrProfOptions Options;
55 Module *M;
Betul Buyukkurt6fac1742015-11-18 18:14:55 +000056 typedef struct PerFunctionProfileData {
57 uint32_t NumValueSites[IPVK_Last+1];
58 GlobalVariable* RegionCounters;
59 GlobalVariable* DataVar;
60 PerFunctionProfileData() : RegionCounters(nullptr), DataVar(nullptr) {
61 memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last+1));
62 }
63 } PerFunctionProfileData;
64 DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap;
Justin Bogner61ba2e32014-12-08 18:02:35 +000065 std::vector<Value *> UsedVars;
Xinliang David Lia82d6c02016-02-08 18:13:49 +000066 std::vector<GlobalVariable *> ReferencedNames;
67 GlobalVariable *NamesVar;
68 size_t NamesSize;
Justin Bogner61ba2e32014-12-08 18:02:35 +000069
70 bool isMachO() const {
71 return Triple(M->getTargetTriple()).isOSBinFormatMachO();
72 }
73
74 /// Get the section name for the counter variables.
75 StringRef getCountersSection() const {
Xinliang David Li83bc4222015-10-22 20:32:12 +000076 return getInstrProfCountersSectionName(isMachO());
Justin Bogner61ba2e32014-12-08 18:02:35 +000077 }
78
79 /// Get the section name for the name variables.
80 StringRef getNameSection() const {
Xinliang David Li83bc4222015-10-22 20:32:12 +000081 return getInstrProfNameSectionName(isMachO());
Justin Bogner61ba2e32014-12-08 18:02:35 +000082 }
83
84 /// Get the section name for the profile data variables.
85 StringRef getDataSection() const {
Xinliang David Li83bc4222015-10-22 20:32:12 +000086 return getInstrProfDataSectionName(isMachO());
Justin Bogner61ba2e32014-12-08 18:02:35 +000087 }
88
Justin Bognerd24e1852015-02-11 02:52:44 +000089 /// Get the section name for the coverage mapping data.
90 StringRef getCoverageSection() const {
Xinliang David Li83bc4222015-10-22 20:32:12 +000091 return getInstrProfCoverageSectionName(isMachO());
Justin Bognerd24e1852015-02-11 02:52:44 +000092 }
93
Betul Buyukkurt6fac1742015-11-18 18:14:55 +000094 /// Count the number of instrumented value sites for the function.
95 void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);
96
97 /// Replace instrprof_value_profile with a call to runtime library.
98 void lowerValueProfileInst(InstrProfValueProfileInst *Ins);
99
Justin Bogner61ba2e32014-12-08 18:02:35 +0000100 /// Replace instrprof_increment with an increment of the appropriate value.
101 void lowerIncrement(InstrProfIncrementInst *Inc);
102
Xinliang David Li81056072016-01-07 20:05:49 +0000103 /// Force emitting of name vars for unused functions.
104 void lowerCoverageData(GlobalVariable *CoverageNamesVar);
Justin Bognerd24e1852015-02-11 02:52:44 +0000105
Justin Bogner61ba2e32014-12-08 18:02:35 +0000106 /// Get the region counters for an increment, creating them if necessary.
107 ///
108 /// If the counter array doesn't yet exist, the profile data variables
109 /// referring to them will also be created.
110 GlobalVariable *getOrCreateRegionCounters(InstrProfIncrementInst *Inc);
111
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000112 /// Emit the section with compressed function names.
113 void emitNameData();
114
Justin Bogner61ba2e32014-12-08 18:02:35 +0000115 /// Emit runtime registration functions for each profile data variable.
116 void emitRegistration();
117
118 /// Emit the necessary plumbing to pull in the runtime initialization.
119 void emitRuntimeHook();
120
121 /// Add uses of our data variables and runtime hook.
122 void emitUses();
123
Justin Bognerba1900c2015-04-30 23:49:23 +0000124 /// Create a static initializer for our data, on platforms that need it,
125 /// and for any profile output file that was specified.
Justin Bogner61ba2e32014-12-08 18:02:35 +0000126 void emitInitialization();
127};
128
129} // anonymous namespace
130
131char InstrProfiling::ID = 0;
132INITIALIZE_PASS(InstrProfiling, "instrprof",
133 "Frontend instrumentation-based coverage lowering.", false,
134 false)
135
136ModulePass *llvm::createInstrProfilingPass(const InstrProfOptions &Options) {
137 return new InstrProfiling(Options);
138}
139
140bool InstrProfiling::runOnModule(Module &M) {
141 bool MadeChange = false;
142
143 this->M = &M;
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000144 NamesVar = nullptr;
145 NamesSize = 0;
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000146 ProfileDataMap.clear();
Justin Bogner61ba2e32014-12-08 18:02:35 +0000147 UsedVars.clear();
148
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000149 // We did not know how many value sites there would be inside
150 // the instrumented function. This is counting the number of instrumented
151 // target value sites to enter it as field in the profile data variable.
Rong Xu294572f2016-01-19 18:29:54 +0000152 for (Function &F : M) {
153 InstrProfIncrementInst *FirstProfIncInst = nullptr;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000154 for (BasicBlock &BB : F)
Rong Xu294572f2016-01-19 18:29:54 +0000155 for (auto I = BB.begin(), E = BB.end(); I != E; I++)
156 if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(I))
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000157 computeNumValueSiteCounts(Ind);
Rong Xu294572f2016-01-19 18:29:54 +0000158 else if (FirstProfIncInst == nullptr)
159 FirstProfIncInst = dyn_cast<InstrProfIncrementInst>(I);
160
161 // Value profiling intrinsic lowering requires per-function profile data
162 // variable to be created first.
163 if (FirstProfIncInst != nullptr)
164 static_cast<void>(getOrCreateRegionCounters(FirstProfIncInst));
165 }
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000166
167 for (Function &F : M)
168 for (BasicBlock &BB : F)
169 for (auto I = BB.begin(), E = BB.end(); I != E;) {
170 auto Instr = I++;
171 if (auto *Inc = dyn_cast<InstrProfIncrementInst>(Instr)) {
Justin Bogner61ba2e32014-12-08 18:02:35 +0000172 lowerIncrement(Inc);
173 MadeChange = true;
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000174 } else if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(Instr)) {
175 lowerValueProfileInst(Ind);
176 MadeChange = true;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000177 }
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000178 }
179
Xinliang David Li81056072016-01-07 20:05:49 +0000180 if (GlobalVariable *CoverageNamesVar =
Xinliang David Li440cd702016-01-20 00:24:36 +0000181 M.getNamedGlobal(getCoverageUnusedNamesVarName())) {
Xinliang David Li81056072016-01-07 20:05:49 +0000182 lowerCoverageData(CoverageNamesVar);
Justin Bognerd24e1852015-02-11 02:52:44 +0000183 MadeChange = true;
184 }
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000185
Justin Bogner61ba2e32014-12-08 18:02:35 +0000186 if (!MadeChange)
187 return false;
188
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000189 emitNameData();
Justin Bogner61ba2e32014-12-08 18:02:35 +0000190 emitRegistration();
191 emitRuntimeHook();
192 emitUses();
193 emitInitialization();
194 return true;
195}
196
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000197static Constant *getOrInsertValueProfilingCall(Module &M) {
Xinliang David Lic7673232015-11-22 00:22:07 +0000198 LLVMContext &Ctx = M.getContext();
199 auto *ReturnTy = Type::getVoidTy(M.getContext());
200 Type *ParamTypes[] = {
201#define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType
202#include "llvm/ProfileData/InstrProfData.inc"
203 };
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000204 auto *ValueProfilingCallTy =
Xinliang David Lic7673232015-11-22 00:22:07 +0000205 FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
Xinliang David Li924e0582015-11-22 05:42:31 +0000206 return M.getOrInsertFunction(getInstrProfValueProfFuncName(),
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000207 ValueProfilingCallTy);
208}
209
210void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) {
211
212 GlobalVariable *Name = Ind->getName();
213 uint64_t ValueKind = Ind->getValueKind()->getZExtValue();
214 uint64_t Index = Ind->getIndex()->getZExtValue();
215 auto It = ProfileDataMap.find(Name);
216 if (It == ProfileDataMap.end()) {
217 PerFunctionProfileData PD;
218 PD.NumValueSites[ValueKind] = Index + 1;
219 ProfileDataMap[Name] = PD;
220 } else if (It->second.NumValueSites[ValueKind] <= Index)
221 It->second.NumValueSites[ValueKind] = Index + 1;
222}
223
224void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) {
225
226 GlobalVariable *Name = Ind->getName();
227 auto It = ProfileDataMap.find(Name);
228 assert(It != ProfileDataMap.end() && It->second.DataVar &&
229 "value profiling detected in function with no counter incerement");
230
231 GlobalVariable *DataVar = It->second.DataVar;
232 uint64_t ValueKind = Ind->getValueKind()->getZExtValue();
233 uint64_t Index = Ind->getIndex()->getZExtValue();
234 for (uint32_t Kind = IPVK_First; Kind < ValueKind; ++Kind)
235 Index += It->second.NumValueSites[Kind];
236
237 IRBuilder<> Builder(Ind);
238 Value* Args[3] = {Ind->getTargetValue(),
239 Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
240 Builder.getInt32(Index)};
241 Ind->replaceAllUsesWith(
242 Builder.CreateCall(getOrInsertValueProfilingCall(*M), Args));
243 Ind->eraseFromParent();
244}
245
Justin Bogner61ba2e32014-12-08 18:02:35 +0000246void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
247 GlobalVariable *Counters = getOrCreateRegionCounters(Inc);
248
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +0000249 IRBuilder<> Builder(Inc);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000250 uint64_t Index = Inc->getIndex()->getZExtValue();
Diego Novillob3029d22015-06-04 11:45:32 +0000251 Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters, 0, Index);
252 Value *Count = Builder.CreateLoad(Addr, "pgocount");
Justin Bogner61ba2e32014-12-08 18:02:35 +0000253 Count = Builder.CreateAdd(Count, Builder.getInt64(1));
254 Inc->replaceAllUsesWith(Builder.CreateStore(Count, Addr));
255 Inc->eraseFromParent();
256}
257
Xinliang David Li81056072016-01-07 20:05:49 +0000258void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageNamesVar) {
Justin Bognerd24e1852015-02-11 02:52:44 +0000259
Xinliang David Li81056072016-01-07 20:05:49 +0000260 ConstantArray *Names =
261 cast<ConstantArray>(CoverageNamesVar->getInitializer());
262 for (unsigned I = 0, E = Names->getNumOperands(); I < E; ++I) {
263 Constant *NC = Names->getOperand(I);
264 Value *V = NC->stripPointerCasts();
Justin Bognerd24e1852015-02-11 02:52:44 +0000265 assert(isa<GlobalVariable>(V) && "Missing reference to function name");
266 GlobalVariable *Name = cast<GlobalVariable>(V);
267
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000268 Name->setLinkage(GlobalValue::PrivateLinkage);
269 ReferencedNames.push_back(Name);
Justin Bognerd24e1852015-02-11 02:52:44 +0000270 }
271}
272
Justin Bogner61ba2e32014-12-08 18:02:35 +0000273/// Get the name of a profiling variable for a particular function.
Xinliang David Li83bc4222015-10-22 20:32:12 +0000274static std::string getVarName(InstrProfIncrementInst *Inc, StringRef Prefix) {
Xinliang David Lid1bab962015-12-12 17:28:03 +0000275 StringRef NamePrefix = getInstrProfNameVarPrefix();
276 StringRef Name = Inc->getName()->getName().substr(NamePrefix.size());
Xinliang David Li83bc4222015-10-22 20:32:12 +0000277 return (Prefix + Name).str();
Justin Bogner61ba2e32014-12-08 18:02:35 +0000278}
279
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000280static inline bool shouldRecordFunctionAddr(Function *F) {
281 // Check the linkage
282 if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() &&
283 !F->hasAvailableExternallyLinkage())
284 return true;
285 // Check uses of this function for other than direct calls or invokes to it.
286 return F->hasAddressTaken();
287}
288
Xinliang David Li985ff202016-02-27 23:11:30 +0000289static inline bool needsComdatForCounter(Function &F, Module &M) {
290
291 if (F.hasComdat())
292 return true;
293
294 Triple TT(M.getTargetTriple());
295 if (!TT.isOSBinFormatELF())
296 return false;
297
298 // See createPGOFuncNameVar for more details. To avoid link errors, profile
299 // counters for function with available_externally linkage needs to be changed
300 // to linkonce linkage. On ELF based systems, this leads to weak symbols to be
301 // created. Without using comdat, duplicate entries won't be removed by the
302 // linker leading to increased data segement size and raw profile size. Even
303 // worse, since the referenced counter from profile per-function data object
304 // will be resolved to the common strong definition, the profile counts for
305 // available_externally functions will end up being duplicated in raw profile
306 // data. This can result in distorted profile as the counts of those dups
307 // will be accumulated by the profile merger.
308 GlobalValue::LinkageTypes Linkage = F.getLinkage();
309 if (Linkage != GlobalValue::ExternalWeakLinkage &&
310 Linkage != GlobalValue::AvailableExternallyLinkage)
311 return false;
312
313 return true;
314}
315
316static inline Comdat *getOrCreateProfileComdat(Module &M, Function &F,
Xinliang David Liab361ef2015-12-21 21:52:27 +0000317 InstrProfIncrementInst *Inc) {
Xinliang David Li985ff202016-02-27 23:11:30 +0000318 if (!needsComdatForCounter(F, M))
319 return nullptr;
320
Xinliang David Liab361ef2015-12-21 21:52:27 +0000321 // COFF format requires a COMDAT section to have a key symbol with the same
Vedant Kumar2d5b5d32016-02-03 23:22:43 +0000322 // name. The linker targeting COFF also requires that the COMDAT
Xinliang David Li5fe04552015-12-22 00:11:15 +0000323 // a section is associated to must precede the associating section. For this
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000324 // reason, we must choose the counter var's name as the name of the comdat.
Xinliang David Liab361ef2015-12-21 21:52:27 +0000325 StringRef ComdatPrefix = (Triple(M.getTargetTriple()).isOSBinFormatCOFF()
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000326 ? getInstrProfCountersVarPrefix()
Xinliang David Liab361ef2015-12-21 21:52:27 +0000327 : getInstrProfComdatPrefix());
328 return M.getOrInsertComdat(StringRef(getVarName(Inc, ComdatPrefix)));
329}
330
Justin Bogner61ba2e32014-12-08 18:02:35 +0000331GlobalVariable *
332InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
Xinliang David Li192c7482015-11-05 00:47:26 +0000333 GlobalVariable *NamePtr = Inc->getName();
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000334 auto It = ProfileDataMap.find(NamePtr);
335 PerFunctionProfileData PD;
336 if (It != ProfileDataMap.end()) {
337 if (It->second.RegionCounters)
338 return It->second.RegionCounters;
339 PD = It->second;
340 }
Justin Bogner61ba2e32014-12-08 18:02:35 +0000341
Wei Mi3cc92042015-09-23 22:40:45 +0000342 // Move the name variable to the right section. Place them in a COMDAT group
343 // if the associated function is a COMDAT. This will make sure that
344 // only one copy of counters of the COMDAT function will be emitted after
345 // linking.
Diego Novillodf4837b2015-05-27 19:34:01 +0000346 Function *Fn = Inc->getParent()->getParent();
Wei Mi3cc92042015-09-23 22:40:45 +0000347 Comdat *ProfileVarsComdat = nullptr;
Xinliang David Li985ff202016-02-27 23:11:30 +0000348 ProfileVarsComdat = getOrCreateProfileComdat(*M, *Fn, Inc);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000349
350 uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
351 LLVMContext &Ctx = M->getContext();
352 ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters);
353
354 // Create the counters variable.
Xinliang David Li192c7482015-11-05 00:47:26 +0000355 auto *CounterPtr =
356 new GlobalVariable(*M, CounterTy, false, NamePtr->getLinkage(),
Xinliang David Li83bc4222015-10-22 20:32:12 +0000357 Constant::getNullValue(CounterTy),
358 getVarName(Inc, getInstrProfCountersVarPrefix()));
Xinliang David Li192c7482015-11-05 00:47:26 +0000359 CounterPtr->setVisibility(NamePtr->getVisibility());
360 CounterPtr->setSection(getCountersSection());
361 CounterPtr->setAlignment(8);
362 CounterPtr->setComdat(ProfileVarsComdat);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000363
Justin Bogner61ba2e32014-12-08 18:02:35 +0000364 // Create data variable.
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000365 auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
366 auto *Int16Ty = Type::getInt16Ty(Ctx);
367 auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last+1);
Xinliang David Li192c7482015-11-05 00:47:26 +0000368 Type *DataTypes[] = {
369 #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType,
370 #include "llvm/ProfileData/InstrProfData.inc"
371 };
Justin Bogner61ba2e32014-12-08 18:02:35 +0000372 auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes));
Xinliang David Li192c7482015-11-05 00:47:26 +0000373
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000374 Constant *FunctionAddr = shouldRecordFunctionAddr(Fn) ?
375 ConstantExpr::getBitCast(Fn, Int8PtrTy) :
376 ConstantPointerNull::get(Int8PtrTy);
377
378 Constant *Int16ArrayVals[IPVK_Last+1];
379 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
380 Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]);
381
Justin Bogner61ba2e32014-12-08 18:02:35 +0000382 Constant *DataVals[] = {
Xinliang David Li192c7482015-11-05 00:47:26 +0000383 #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init,
384 #include "llvm/ProfileData/InstrProfData.inc"
385 };
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000386 auto *Data = new GlobalVariable(*M, DataTy, false, NamePtr->getLinkage(),
Justin Bogner61ba2e32014-12-08 18:02:35 +0000387 ConstantStruct::get(DataTy, DataVals),
Xinliang David Li83bc4222015-10-22 20:32:12 +0000388 getVarName(Inc, getInstrProfDataVarPrefix()));
Xinliang David Li192c7482015-11-05 00:47:26 +0000389 Data->setVisibility(NamePtr->getVisibility());
Justin Bogner61ba2e32014-12-08 18:02:35 +0000390 Data->setSection(getDataSection());
Xinliang David Lic7c1f852015-11-23 18:02:59 +0000391 Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT);
Wei Mi3cc92042015-09-23 22:40:45 +0000392 Data->setComdat(ProfileVarsComdat);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000393
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000394 PD.RegionCounters = CounterPtr;
395 PD.DataVar = Data;
396 ProfileDataMap[NamePtr] = PD;
397
Justin Bogner61ba2e32014-12-08 18:02:35 +0000398 // Mark the data variable as used so that it isn't stripped out.
399 UsedVars.push_back(Data);
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000400 // Now that the linkage set by the FE has been passed to the data and counter
401 // variables, reset Name variable's linkage and visibility to private so that
402 // it can be removed later by the compiler.
403 NamePtr->setLinkage(GlobalValue::PrivateLinkage);
404 // Collect the referenced names to be used by emitNameData.
405 ReferencedNames.push_back(NamePtr);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000406
Xinliang David Li192c7482015-11-05 00:47:26 +0000407 return CounterPtr;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000408}
409
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000410void InstrProfiling::emitNameData() {
411 std::string UncompressedData;
412
413 if (ReferencedNames.empty())
414 return;
415
416 std::string CompressedNameStr;
417 collectPGOFuncNameStrings(ReferencedNames, CompressedNameStr,
418 DoNameCompression);
419
420 auto &Ctx = M->getContext();
421 auto *NamesVal = llvm::ConstantDataArray::getString(
422 Ctx, StringRef(CompressedNameStr), false);
423 NamesVar = new llvm::GlobalVariable(*M, NamesVal->getType(), true,
424 llvm::GlobalValue::PrivateLinkage,
425 NamesVal, getInstrProfNamesVarName());
426 NamesSize = CompressedNameStr.size();
427 NamesVar->setSection(getNameSection());
428 UsedVars.push_back(NamesVar);
429}
430
Justin Bogner61ba2e32014-12-08 18:02:35 +0000431void InstrProfiling::emitRegistration() {
432 // Don't do this for Darwin. compiler-rt uses linker magic.
433 if (Triple(M->getTargetTriple()).isOSDarwin())
434 return;
435
Xinliang David Li3dd88172015-10-13 18:39:48 +0000436 // Use linker script magic to get data/cnts/name start/end.
Xinliang David Liaa0592c2015-10-19 04:17:10 +0000437 if (Triple(M->getTargetTriple()).isOSLinux() ||
Sean Silvaea399f02016-02-27 06:01:26 +0000438 Triple(M->getTargetTriple()).isOSFreeBSD() ||
439 Triple(M->getTargetTriple()).isPS4CPU())
Xinliang David Liaa0592c2015-10-19 04:17:10 +0000440 return;
Xinliang David Li3dd88172015-10-13 18:39:48 +0000441
Justin Bogner61ba2e32014-12-08 18:02:35 +0000442 // Construct the function.
443 auto *VoidTy = Type::getVoidTy(M->getContext());
444 auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext());
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000445 auto *Int64Ty = Type::getInt64Ty(M->getContext());
Justin Bogner61ba2e32014-12-08 18:02:35 +0000446 auto *RegisterFTy = FunctionType::get(VoidTy, false);
447 auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage,
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000448 getInstrProfRegFuncsName(), M);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000449 RegisterF->setUnnamedAddr(true);
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000450 if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000451
Diego Novillob3029d22015-06-04 11:45:32 +0000452 auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000453 auto *RuntimeRegisterF =
454 Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage,
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000455 getInstrProfRegFuncName(), M);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000456
457 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", RegisterF));
458 for (Value *Data : UsedVars)
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000459 if (Data != NamesVar)
460 IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy));
461
462 if (NamesVar) {
463 Type *ParamTypes[] = {VoidPtrTy, Int64Ty};
464 auto *NamesRegisterTy =
465 FunctionType::get(VoidTy, makeArrayRef(ParamTypes), false);
466 auto *NamesRegisterF =
467 Function::Create(NamesRegisterTy, GlobalVariable::ExternalLinkage,
468 getInstrProfNamesRegFuncName(), M);
469 IRB.CreateCall(NamesRegisterF, {IRB.CreateBitCast(NamesVar, VoidPtrTy),
470 IRB.getInt64(NamesSize)});
471 }
472
Justin Bogner61ba2e32014-12-08 18:02:35 +0000473 IRB.CreateRetVoid();
474}
475
476void InstrProfiling::emitRuntimeHook() {
Justin Bogner61ba2e32014-12-08 18:02:35 +0000477
Xinliang David Li7a88ad62015-10-29 04:08:31 +0000478 // We expect the linker to be invoked with -u<hook_var> flag for linux,
479 // for which case there is no need to emit the user function.
480 if (Triple(M->getTargetTriple()).isOSLinux())
481 return;
482
Justin Bogner61ba2e32014-12-08 18:02:35 +0000483 // If the module's provided its own runtime, we don't need to do anything.
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000484 if (M->getGlobalVariable(getInstrProfRuntimeHookVarName())) return;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000485
486 // Declare an external variable that will pull in the runtime initialization.
487 auto *Int32Ty = Type::getInt32Ty(M->getContext());
488 auto *Var =
489 new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000490 nullptr, getInstrProfRuntimeHookVarName());
Justin Bogner61ba2e32014-12-08 18:02:35 +0000491
492 // Make a function that uses it.
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000493 auto *User = Function::Create(FunctionType::get(Int32Ty, false),
494 GlobalValue::LinkOnceODRLinkage,
495 getInstrProfRuntimeHookVarUseFuncName(), M);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000496 User->addFnAttr(Attribute::NoInline);
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000497 if (Options.NoRedZone) User->addFnAttr(Attribute::NoRedZone);
Justin Bogner2e427d42015-02-25 22:52:20 +0000498 User->setVisibility(GlobalValue::HiddenVisibility);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000499
500 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", User));
501 auto *Load = IRB.CreateLoad(Var);
502 IRB.CreateRet(Load);
503
504 // Mark the user variable as used so that it isn't stripped out.
505 UsedVars.push_back(User);
506}
507
508void InstrProfiling::emitUses() {
509 if (UsedVars.empty())
510 return;
511
512 GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used");
Diego Novillob3029d22015-06-04 11:45:32 +0000513 std::vector<Constant *> MergedVars;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000514 if (LLVMUsed) {
515 // Collect the existing members of llvm.used.
516 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
517 for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I)
518 MergedVars.push_back(Inits->getOperand(I));
519 LLVMUsed->eraseFromParent();
520 }
521
522 Type *i8PTy = Type::getInt8PtrTy(M->getContext());
523 // Add uses for our data.
524 for (auto *Value : UsedVars)
525 MergedVars.push_back(
Diego Novillob3029d22015-06-04 11:45:32 +0000526 ConstantExpr::getBitCast(cast<Constant>(Value), i8PTy));
Justin Bogner61ba2e32014-12-08 18:02:35 +0000527
528 // Recreate llvm.used.
529 ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size());
Diego Novillob3029d22015-06-04 11:45:32 +0000530 LLVMUsed =
531 new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage,
532 ConstantArray::get(ATy, MergedVars), "llvm.used");
Justin Bogner61ba2e32014-12-08 18:02:35 +0000533 LLVMUsed->setSection("llvm.metadata");
534}
535
536void InstrProfiling::emitInitialization() {
Justin Bognerba1900c2015-04-30 23:49:23 +0000537 std::string InstrProfileOutput = Options.InstrProfileOutput;
538
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000539 Constant *RegisterF = M->getFunction(getInstrProfRegFuncsName());
540 if (!RegisterF && InstrProfileOutput.empty()) return;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000541
542 // Create the initialization function.
543 auto *VoidTy = Type::getVoidTy(M->getContext());
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000544 auto *F = Function::Create(FunctionType::get(VoidTy, false),
545 GlobalValue::InternalLinkage,
546 getInstrProfInitFuncName(), M);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000547 F->setUnnamedAddr(true);
548 F->addFnAttr(Attribute::NoInline);
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000549 if (Options.NoRedZone) F->addFnAttr(Attribute::NoRedZone);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000550
551 // Add the basic block and the necessary calls.
552 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F));
Justin Bognerba1900c2015-04-30 23:49:23 +0000553 if (RegisterF)
David Blaikieff6409d2015-05-18 22:13:54 +0000554 IRB.CreateCall(RegisterF, {});
Justin Bognerba1900c2015-04-30 23:49:23 +0000555 if (!InstrProfileOutput.empty()) {
556 auto *Int8PtrTy = Type::getInt8PtrTy(M->getContext());
557 auto *SetNameTy = FunctionType::get(VoidTy, Int8PtrTy, false);
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000558 auto *SetNameF = Function::Create(SetNameTy, GlobalValue::ExternalLinkage,
559 getInstrProfFileOverriderFuncName(), M);
Justin Bognerba1900c2015-04-30 23:49:23 +0000560
Diego Novillob0257c82015-06-29 20:03:46 +0000561 // Create variable for profile name.
Justin Bognerba1900c2015-04-30 23:49:23 +0000562 Constant *ProfileNameConst =
563 ConstantDataArray::getString(M->getContext(), InstrProfileOutput, true);
564 GlobalVariable *ProfileName =
565 new GlobalVariable(*M, ProfileNameConst->getType(), true,
566 GlobalValue::PrivateLinkage, ProfileNameConst);
567
568 IRB.CreateCall(SetNameF, IRB.CreatePointerCast(ProfileName, Int8PtrTy));
569 }
Justin Bogner61ba2e32014-12-08 18:02:35 +0000570 IRB.CreateRetVoid();
571
572 appendToGlobalCtors(*M, F, 0);
573}