blob: ab88818998782809db764febf911dd80d8324889 [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 Liab361ef2015-12-21 21:52:27 +0000289static inline Comdat *getOrCreateProfileComdat(Module &M,
290 InstrProfIncrementInst *Inc) {
291 // COFF format requires a COMDAT section to have a key symbol with the same
Vedant Kumar2d5b5d32016-02-03 23:22:43 +0000292 // name. The linker targeting COFF also requires that the COMDAT
Xinliang David Li5fe04552015-12-22 00:11:15 +0000293 // a section is associated to must precede the associating section. For this
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000294 // reason, we must choose the counter var's name as the name of the comdat.
Xinliang David Liab361ef2015-12-21 21:52:27 +0000295 StringRef ComdatPrefix = (Triple(M.getTargetTriple()).isOSBinFormatCOFF()
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000296 ? getInstrProfCountersVarPrefix()
Xinliang David Liab361ef2015-12-21 21:52:27 +0000297 : getInstrProfComdatPrefix());
298 return M.getOrInsertComdat(StringRef(getVarName(Inc, ComdatPrefix)));
299}
300
Justin Bogner61ba2e32014-12-08 18:02:35 +0000301GlobalVariable *
302InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
Xinliang David Li192c7482015-11-05 00:47:26 +0000303 GlobalVariable *NamePtr = Inc->getName();
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000304 auto It = ProfileDataMap.find(NamePtr);
305 PerFunctionProfileData PD;
306 if (It != ProfileDataMap.end()) {
307 if (It->second.RegionCounters)
308 return It->second.RegionCounters;
309 PD = It->second;
310 }
Justin Bogner61ba2e32014-12-08 18:02:35 +0000311
Wei Mi3cc92042015-09-23 22:40:45 +0000312 // Move the name variable to the right section. Place them in a COMDAT group
313 // if the associated function is a COMDAT. This will make sure that
314 // only one copy of counters of the COMDAT function will be emitted after
315 // linking.
Diego Novillodf4837b2015-05-27 19:34:01 +0000316 Function *Fn = Inc->getParent()->getParent();
Wei Mi3cc92042015-09-23 22:40:45 +0000317 Comdat *ProfileVarsComdat = nullptr;
318 if (Fn->hasComdat())
Xinliang David Liab361ef2015-12-21 21:52:27 +0000319 ProfileVarsComdat = getOrCreateProfileComdat(*M, Inc);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000320
321 uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
322 LLVMContext &Ctx = M->getContext();
323 ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters);
324
325 // Create the counters variable.
Xinliang David Li192c7482015-11-05 00:47:26 +0000326 auto *CounterPtr =
327 new GlobalVariable(*M, CounterTy, false, NamePtr->getLinkage(),
Xinliang David Li83bc4222015-10-22 20:32:12 +0000328 Constant::getNullValue(CounterTy),
329 getVarName(Inc, getInstrProfCountersVarPrefix()));
Xinliang David Li192c7482015-11-05 00:47:26 +0000330 CounterPtr->setVisibility(NamePtr->getVisibility());
331 CounterPtr->setSection(getCountersSection());
332 CounterPtr->setAlignment(8);
333 CounterPtr->setComdat(ProfileVarsComdat);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000334
Justin Bogner61ba2e32014-12-08 18:02:35 +0000335 // Create data variable.
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000336 auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
337 auto *Int16Ty = Type::getInt16Ty(Ctx);
338 auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last+1);
Xinliang David Li192c7482015-11-05 00:47:26 +0000339 Type *DataTypes[] = {
340 #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType,
341 #include "llvm/ProfileData/InstrProfData.inc"
342 };
Justin Bogner61ba2e32014-12-08 18:02:35 +0000343 auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes));
Xinliang David Li192c7482015-11-05 00:47:26 +0000344
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000345 Constant *FunctionAddr = shouldRecordFunctionAddr(Fn) ?
346 ConstantExpr::getBitCast(Fn, Int8PtrTy) :
347 ConstantPointerNull::get(Int8PtrTy);
348
349 Constant *Int16ArrayVals[IPVK_Last+1];
350 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
351 Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]);
352
Justin Bogner61ba2e32014-12-08 18:02:35 +0000353 Constant *DataVals[] = {
Xinliang David Li192c7482015-11-05 00:47:26 +0000354 #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init,
355 #include "llvm/ProfileData/InstrProfData.inc"
356 };
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000357 auto *Data = new GlobalVariable(*M, DataTy, false, NamePtr->getLinkage(),
Justin Bogner61ba2e32014-12-08 18:02:35 +0000358 ConstantStruct::get(DataTy, DataVals),
Xinliang David Li83bc4222015-10-22 20:32:12 +0000359 getVarName(Inc, getInstrProfDataVarPrefix()));
Xinliang David Li192c7482015-11-05 00:47:26 +0000360 Data->setVisibility(NamePtr->getVisibility());
Justin Bogner61ba2e32014-12-08 18:02:35 +0000361 Data->setSection(getDataSection());
Xinliang David Lic7c1f852015-11-23 18:02:59 +0000362 Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT);
Wei Mi3cc92042015-09-23 22:40:45 +0000363 Data->setComdat(ProfileVarsComdat);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000364
Betul Buyukkurt6fac1742015-11-18 18:14:55 +0000365 PD.RegionCounters = CounterPtr;
366 PD.DataVar = Data;
367 ProfileDataMap[NamePtr] = PD;
368
Justin Bogner61ba2e32014-12-08 18:02:35 +0000369 // Mark the data variable as used so that it isn't stripped out.
370 UsedVars.push_back(Data);
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000371 // Now that the linkage set by the FE has been passed to the data and counter
372 // variables, reset Name variable's linkage and visibility to private so that
373 // it can be removed later by the compiler.
374 NamePtr->setLinkage(GlobalValue::PrivateLinkage);
375 // Collect the referenced names to be used by emitNameData.
376 ReferencedNames.push_back(NamePtr);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000377
Xinliang David Li192c7482015-11-05 00:47:26 +0000378 return CounterPtr;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000379}
380
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000381void InstrProfiling::emitNameData() {
382 std::string UncompressedData;
383
384 if (ReferencedNames.empty())
385 return;
386
387 std::string CompressedNameStr;
388 collectPGOFuncNameStrings(ReferencedNames, CompressedNameStr,
389 DoNameCompression);
390
391 auto &Ctx = M->getContext();
392 auto *NamesVal = llvm::ConstantDataArray::getString(
393 Ctx, StringRef(CompressedNameStr), false);
394 NamesVar = new llvm::GlobalVariable(*M, NamesVal->getType(), true,
395 llvm::GlobalValue::PrivateLinkage,
396 NamesVal, getInstrProfNamesVarName());
397 NamesSize = CompressedNameStr.size();
398 NamesVar->setSection(getNameSection());
399 UsedVars.push_back(NamesVar);
400}
401
Justin Bogner61ba2e32014-12-08 18:02:35 +0000402void InstrProfiling::emitRegistration() {
403 // Don't do this for Darwin. compiler-rt uses linker magic.
404 if (Triple(M->getTargetTriple()).isOSDarwin())
405 return;
406
Xinliang David Li3dd88172015-10-13 18:39:48 +0000407 // Use linker script magic to get data/cnts/name start/end.
Xinliang David Liaa0592c2015-10-19 04:17:10 +0000408 if (Triple(M->getTargetTriple()).isOSLinux() ||
409 Triple(M->getTargetTriple()).isOSFreeBSD())
410 return;
Xinliang David Li3dd88172015-10-13 18:39:48 +0000411
Justin Bogner61ba2e32014-12-08 18:02:35 +0000412 // Construct the function.
413 auto *VoidTy = Type::getVoidTy(M->getContext());
414 auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext());
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000415 auto *Int64Ty = Type::getInt64Ty(M->getContext());
Justin Bogner61ba2e32014-12-08 18:02:35 +0000416 auto *RegisterFTy = FunctionType::get(VoidTy, false);
417 auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage,
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000418 getInstrProfRegFuncsName(), M);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000419 RegisterF->setUnnamedAddr(true);
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000420 if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000421
Diego Novillob3029d22015-06-04 11:45:32 +0000422 auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000423 auto *RuntimeRegisterF =
424 Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage,
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000425 getInstrProfRegFuncName(), M);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000426
427 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", RegisterF));
428 for (Value *Data : UsedVars)
Xinliang David Lia82d6c02016-02-08 18:13:49 +0000429 if (Data != NamesVar)
430 IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy));
431
432 if (NamesVar) {
433 Type *ParamTypes[] = {VoidPtrTy, Int64Ty};
434 auto *NamesRegisterTy =
435 FunctionType::get(VoidTy, makeArrayRef(ParamTypes), false);
436 auto *NamesRegisterF =
437 Function::Create(NamesRegisterTy, GlobalVariable::ExternalLinkage,
438 getInstrProfNamesRegFuncName(), M);
439 IRB.CreateCall(NamesRegisterF, {IRB.CreateBitCast(NamesVar, VoidPtrTy),
440 IRB.getInt64(NamesSize)});
441 }
442
Justin Bogner61ba2e32014-12-08 18:02:35 +0000443 IRB.CreateRetVoid();
444}
445
446void InstrProfiling::emitRuntimeHook() {
Justin Bogner61ba2e32014-12-08 18:02:35 +0000447
Xinliang David Li7a88ad62015-10-29 04:08:31 +0000448 // We expect the linker to be invoked with -u<hook_var> flag for linux,
449 // for which case there is no need to emit the user function.
450 if (Triple(M->getTargetTriple()).isOSLinux())
451 return;
452
Justin Bogner61ba2e32014-12-08 18:02:35 +0000453 // If the module's provided its own runtime, we don't need to do anything.
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000454 if (M->getGlobalVariable(getInstrProfRuntimeHookVarName())) return;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000455
456 // Declare an external variable that will pull in the runtime initialization.
457 auto *Int32Ty = Type::getInt32Ty(M->getContext());
458 auto *Var =
459 new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000460 nullptr, getInstrProfRuntimeHookVarName());
Justin Bogner61ba2e32014-12-08 18:02:35 +0000461
462 // Make a function that uses it.
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000463 auto *User = Function::Create(FunctionType::get(Int32Ty, false),
464 GlobalValue::LinkOnceODRLinkage,
465 getInstrProfRuntimeHookVarUseFuncName(), M);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000466 User->addFnAttr(Attribute::NoInline);
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000467 if (Options.NoRedZone) User->addFnAttr(Attribute::NoRedZone);
Justin Bogner2e427d42015-02-25 22:52:20 +0000468 User->setVisibility(GlobalValue::HiddenVisibility);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000469
470 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", User));
471 auto *Load = IRB.CreateLoad(Var);
472 IRB.CreateRet(Load);
473
474 // Mark the user variable as used so that it isn't stripped out.
475 UsedVars.push_back(User);
476}
477
478void InstrProfiling::emitUses() {
479 if (UsedVars.empty())
480 return;
481
482 GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used");
Diego Novillob3029d22015-06-04 11:45:32 +0000483 std::vector<Constant *> MergedVars;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000484 if (LLVMUsed) {
485 // Collect the existing members of llvm.used.
486 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
487 for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I)
488 MergedVars.push_back(Inits->getOperand(I));
489 LLVMUsed->eraseFromParent();
490 }
491
492 Type *i8PTy = Type::getInt8PtrTy(M->getContext());
493 // Add uses for our data.
494 for (auto *Value : UsedVars)
495 MergedVars.push_back(
Diego Novillob3029d22015-06-04 11:45:32 +0000496 ConstantExpr::getBitCast(cast<Constant>(Value), i8PTy));
Justin Bogner61ba2e32014-12-08 18:02:35 +0000497
498 // Recreate llvm.used.
499 ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size());
Diego Novillob3029d22015-06-04 11:45:32 +0000500 LLVMUsed =
501 new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage,
502 ConstantArray::get(ATy, MergedVars), "llvm.used");
Justin Bogner61ba2e32014-12-08 18:02:35 +0000503 LLVMUsed->setSection("llvm.metadata");
504}
505
506void InstrProfiling::emitInitialization() {
Justin Bognerba1900c2015-04-30 23:49:23 +0000507 std::string InstrProfileOutput = Options.InstrProfileOutput;
508
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000509 Constant *RegisterF = M->getFunction(getInstrProfRegFuncsName());
510 if (!RegisterF && InstrProfileOutput.empty()) return;
Justin Bogner61ba2e32014-12-08 18:02:35 +0000511
512 // Create the initialization function.
513 auto *VoidTy = Type::getVoidTy(M->getContext());
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000514 auto *F = Function::Create(FunctionType::get(VoidTy, false),
515 GlobalValue::InternalLinkage,
516 getInstrProfInitFuncName(), M);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000517 F->setUnnamedAddr(true);
518 F->addFnAttr(Attribute::NoInline);
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000519 if (Options.NoRedZone) F->addFnAttr(Attribute::NoRedZone);
Justin Bogner61ba2e32014-12-08 18:02:35 +0000520
521 // Add the basic block and the necessary calls.
522 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F));
Justin Bognerba1900c2015-04-30 23:49:23 +0000523 if (RegisterF)
David Blaikieff6409d2015-05-18 22:13:54 +0000524 IRB.CreateCall(RegisterF, {});
Justin Bognerba1900c2015-04-30 23:49:23 +0000525 if (!InstrProfileOutput.empty()) {
526 auto *Int8PtrTy = Type::getInt8PtrTy(M->getContext());
527 auto *SetNameTy = FunctionType::get(VoidTy, Int8PtrTy, false);
Xinliang David Li8ee08b02015-10-23 04:22:58 +0000528 auto *SetNameF = Function::Create(SetNameTy, GlobalValue::ExternalLinkage,
529 getInstrProfFileOverriderFuncName(), M);
Justin Bognerba1900c2015-04-30 23:49:23 +0000530
Diego Novillob0257c82015-06-29 20:03:46 +0000531 // Create variable for profile name.
Justin Bognerba1900c2015-04-30 23:49:23 +0000532 Constant *ProfileNameConst =
533 ConstantDataArray::getString(M->getContext(), InstrProfileOutput, true);
534 GlobalVariable *ProfileName =
535 new GlobalVariable(*M, ProfileNameConst->getType(), true,
536 GlobalValue::PrivateLinkage, ProfileNameConst);
537
538 IRB.CreateCall(SetNameF, IRB.CreatePointerCast(ProfileName, Int8PtrTy));
539 }
Justin Bogner61ba2e32014-12-08 18:02:35 +0000540 IRB.CreateRetVoid();
541
542 appendToGlobalCtors(*M, F, 0);
543}