161ba2e39SJustin Bogner //===-- InstrProfiling.cpp - Frontend instrumentation based profiling -----===//
261ba2e39SJustin Bogner //
361ba2e39SJustin Bogner //                     The LLVM Compiler Infrastructure
461ba2e39SJustin Bogner //
561ba2e39SJustin Bogner // This file is distributed under the University of Illinois Open Source
661ba2e39SJustin Bogner // License. See LICENSE.TXT for details.
761ba2e39SJustin Bogner //
861ba2e39SJustin Bogner //===----------------------------------------------------------------------===//
961ba2e39SJustin Bogner //
1061ba2e39SJustin Bogner // This pass lowers instrprof_increment intrinsics emitted by a frontend for
1161ba2e39SJustin Bogner // profiling. It also builds the data structures and initialization code needed
1261ba2e39SJustin Bogner // for updating execution counts and emitting the profile at runtime.
1361ba2e39SJustin Bogner //
1461ba2e39SJustin Bogner //===----------------------------------------------------------------------===//
1561ba2e39SJustin Bogner 
1661ba2e39SJustin Bogner #include "llvm/Transforms/Instrumentation.h"
1761ba2e39SJustin Bogner 
1861ba2e39SJustin Bogner #include "llvm/ADT/Triple.h"
1961ba2e39SJustin Bogner #include "llvm/IR/IRBuilder.h"
2061ba2e39SJustin Bogner #include "llvm/IR/IntrinsicInst.h"
2161ba2e39SJustin Bogner #include "llvm/IR/Module.h"
2261ba2e39SJustin Bogner #include "llvm/Transforms/Utils/ModuleUtils.h"
2361ba2e39SJustin Bogner 
2461ba2e39SJustin Bogner using namespace llvm;
2561ba2e39SJustin Bogner 
2661ba2e39SJustin Bogner #define DEBUG_TYPE "instrprof"
2761ba2e39SJustin Bogner 
2861ba2e39SJustin Bogner namespace {
2961ba2e39SJustin Bogner 
3061ba2e39SJustin Bogner class InstrProfiling : public ModulePass {
3161ba2e39SJustin Bogner public:
3261ba2e39SJustin Bogner   static char ID;
3361ba2e39SJustin Bogner 
3461ba2e39SJustin Bogner   InstrProfiling() : ModulePass(ID) {}
3561ba2e39SJustin Bogner 
3661ba2e39SJustin Bogner   InstrProfiling(const InstrProfOptions &Options)
3761ba2e39SJustin Bogner       : ModulePass(ID), Options(Options) {}
3861ba2e39SJustin Bogner 
3961ba2e39SJustin Bogner   const char *getPassName() const override {
4061ba2e39SJustin Bogner     return "Frontend instrumentation-based coverage lowering";
4161ba2e39SJustin Bogner   }
4261ba2e39SJustin Bogner 
4361ba2e39SJustin Bogner   bool runOnModule(Module &M) override;
4461ba2e39SJustin Bogner 
4561ba2e39SJustin Bogner   void getAnalysisUsage(AnalysisUsage &AU) const override {
4661ba2e39SJustin Bogner     AU.setPreservesCFG();
4761ba2e39SJustin Bogner   }
4861ba2e39SJustin Bogner 
4961ba2e39SJustin Bogner private:
5061ba2e39SJustin Bogner   InstrProfOptions Options;
5161ba2e39SJustin Bogner   Module *M;
5261ba2e39SJustin Bogner   DenseMap<GlobalVariable *, GlobalVariable *> RegionCounters;
5361ba2e39SJustin Bogner   std::vector<Value *> UsedVars;
5461ba2e39SJustin Bogner 
5561ba2e39SJustin Bogner   bool isMachO() const {
5661ba2e39SJustin Bogner     return Triple(M->getTargetTriple()).isOSBinFormatMachO();
5761ba2e39SJustin Bogner   }
5861ba2e39SJustin Bogner 
5961ba2e39SJustin Bogner   /// Get the section name for the counter variables.
6061ba2e39SJustin Bogner   StringRef getCountersSection() const {
6161ba2e39SJustin Bogner     return isMachO() ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts";
6261ba2e39SJustin Bogner   }
6361ba2e39SJustin Bogner 
6461ba2e39SJustin Bogner   /// Get the section name for the name variables.
6561ba2e39SJustin Bogner   StringRef getNameSection() const {
6661ba2e39SJustin Bogner     return isMachO() ? "__DATA,__llvm_prf_names" : "__llvm_prf_names";
6761ba2e39SJustin Bogner   }
6861ba2e39SJustin Bogner 
6961ba2e39SJustin Bogner   /// Get the section name for the profile data variables.
7061ba2e39SJustin Bogner   StringRef getDataSection() const {
7161ba2e39SJustin Bogner     return isMachO() ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
7261ba2e39SJustin Bogner   }
7361ba2e39SJustin Bogner 
74d24e1857SJustin Bogner   /// Get the section name for the coverage mapping data.
75d24e1857SJustin Bogner   StringRef getCoverageSection() const {
76d24e1857SJustin Bogner     return isMachO() ? "__DATA,__llvm_covmap" : "__llvm_covmap";
77d24e1857SJustin Bogner   }
78d24e1857SJustin Bogner 
7961ba2e39SJustin Bogner   /// Replace instrprof_increment with an increment of the appropriate value.
8061ba2e39SJustin Bogner   void lowerIncrement(InstrProfIncrementInst *Inc);
8161ba2e39SJustin Bogner 
82d24e1857SJustin Bogner   /// Set up the section and uses for coverage data and its references.
83d24e1857SJustin Bogner   void lowerCoverageData(GlobalVariable *CoverageData);
84d24e1857SJustin Bogner 
8561ba2e39SJustin Bogner   /// Get the region counters for an increment, creating them if necessary.
8661ba2e39SJustin Bogner   ///
8761ba2e39SJustin Bogner   /// If the counter array doesn't yet exist, the profile data variables
8861ba2e39SJustin Bogner   /// referring to them will also be created.
8961ba2e39SJustin Bogner   GlobalVariable *getOrCreateRegionCounters(InstrProfIncrementInst *Inc);
9061ba2e39SJustin Bogner 
9161ba2e39SJustin Bogner   /// Emit runtime registration functions for each profile data variable.
9261ba2e39SJustin Bogner   void emitRegistration();
9361ba2e39SJustin Bogner 
9461ba2e39SJustin Bogner   /// Emit the necessary plumbing to pull in the runtime initialization.
9561ba2e39SJustin Bogner   void emitRuntimeHook();
9661ba2e39SJustin Bogner 
9761ba2e39SJustin Bogner   /// Add uses of our data variables and runtime hook.
9861ba2e39SJustin Bogner   void emitUses();
9961ba2e39SJustin Bogner 
100ba1900ceSJustin Bogner   /// Create a static initializer for our data, on platforms that need it,
101ba1900ceSJustin Bogner   /// and for any profile output file that was specified.
10261ba2e39SJustin Bogner   void emitInitialization();
10361ba2e39SJustin Bogner };
10461ba2e39SJustin Bogner 
10561ba2e39SJustin Bogner } // anonymous namespace
10661ba2e39SJustin Bogner 
10761ba2e39SJustin Bogner char InstrProfiling::ID = 0;
10861ba2e39SJustin Bogner INITIALIZE_PASS(InstrProfiling, "instrprof",
10961ba2e39SJustin Bogner                 "Frontend instrumentation-based coverage lowering.", false,
11061ba2e39SJustin Bogner                 false)
11161ba2e39SJustin Bogner 
11261ba2e39SJustin Bogner ModulePass *llvm::createInstrProfilingPass(const InstrProfOptions &Options) {
11361ba2e39SJustin Bogner   return new InstrProfiling(Options);
11461ba2e39SJustin Bogner }
11561ba2e39SJustin Bogner 
11661ba2e39SJustin Bogner bool InstrProfiling::runOnModule(Module &M) {
11761ba2e39SJustin Bogner   bool MadeChange = false;
11861ba2e39SJustin Bogner 
11961ba2e39SJustin Bogner   this->M = &M;
12061ba2e39SJustin Bogner   RegionCounters.clear();
12161ba2e39SJustin Bogner   UsedVars.clear();
12261ba2e39SJustin Bogner 
12361ba2e39SJustin Bogner   for (Function &F : M)
12461ba2e39SJustin Bogner     for (BasicBlock &BB : F)
12561ba2e39SJustin Bogner       for (auto I = BB.begin(), E = BB.end(); I != E;)
12661ba2e39SJustin Bogner         if (auto *Inc = dyn_cast<InstrProfIncrementInst>(I++)) {
12761ba2e39SJustin Bogner           lowerIncrement(Inc);
12861ba2e39SJustin Bogner           MadeChange = true;
12961ba2e39SJustin Bogner         }
130d24e1857SJustin Bogner   if (GlobalVariable *Coverage = M.getNamedGlobal("__llvm_coverage_mapping")) {
131d24e1857SJustin Bogner     lowerCoverageData(Coverage);
132d24e1857SJustin Bogner     MadeChange = true;
133d24e1857SJustin Bogner   }
13461ba2e39SJustin Bogner   if (!MadeChange)
13561ba2e39SJustin Bogner     return false;
13661ba2e39SJustin Bogner 
13761ba2e39SJustin Bogner   emitRegistration();
13861ba2e39SJustin Bogner   emitRuntimeHook();
13961ba2e39SJustin Bogner   emitUses();
14061ba2e39SJustin Bogner   emitInitialization();
14161ba2e39SJustin Bogner   return true;
14261ba2e39SJustin Bogner }
14361ba2e39SJustin Bogner 
14461ba2e39SJustin Bogner void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
14561ba2e39SJustin Bogner   GlobalVariable *Counters = getOrCreateRegionCounters(Inc);
14661ba2e39SJustin Bogner 
147*e82c286fSDuncan P. N. Exon Smith   IRBuilder<> Builder(Inc);
14861ba2e39SJustin Bogner   uint64_t Index = Inc->getIndex()->getZExtValue();
149b3029d26SDiego Novillo   Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters, 0, Index);
150b3029d26SDiego Novillo   Value *Count = Builder.CreateLoad(Addr, "pgocount");
15161ba2e39SJustin Bogner   Count = Builder.CreateAdd(Count, Builder.getInt64(1));
15261ba2e39SJustin Bogner   Inc->replaceAllUsesWith(Builder.CreateStore(Count, Addr));
15361ba2e39SJustin Bogner   Inc->eraseFromParent();
15461ba2e39SJustin Bogner }
15561ba2e39SJustin Bogner 
156d24e1857SJustin Bogner void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageData) {
157d24e1857SJustin Bogner   CoverageData->setSection(getCoverageSection());
158d24e1857SJustin Bogner   CoverageData->setAlignment(8);
159d24e1857SJustin Bogner 
160d24e1857SJustin Bogner   Constant *Init = CoverageData->getInitializer();
161d24e1857SJustin Bogner   // We're expecting { i32, i32, i32, i32, [n x { i8*, i32, i32 }], [m x i8] }
162d24e1857SJustin Bogner   // for some C. If not, the frontend's given us something broken.
163d24e1857SJustin Bogner   assert(Init->getNumOperands() == 6 && "bad number of fields in coverage map");
164d24e1857SJustin Bogner   assert(isa<ConstantArray>(Init->getAggregateElement(4)) &&
165d24e1857SJustin Bogner          "invalid function list in coverage map");
166d24e1857SJustin Bogner   ConstantArray *Records = cast<ConstantArray>(Init->getAggregateElement(4));
167d24e1857SJustin Bogner   for (unsigned I = 0, E = Records->getNumOperands(); I < E; ++I) {
168d24e1857SJustin Bogner     Constant *Record = Records->getOperand(I);
169d24e1857SJustin Bogner     Value *V = const_cast<Value *>(Record->getOperand(0))->stripPointerCasts();
170d24e1857SJustin Bogner 
171d24e1857SJustin Bogner     assert(isa<GlobalVariable>(V) && "Missing reference to function name");
172d24e1857SJustin Bogner     GlobalVariable *Name = cast<GlobalVariable>(V);
173d24e1857SJustin Bogner 
174d24e1857SJustin Bogner     // If we have region counters for this name, we've already handled it.
175d24e1857SJustin Bogner     auto It = RegionCounters.find(Name);
176d24e1857SJustin Bogner     if (It != RegionCounters.end())
177d24e1857SJustin Bogner       continue;
178d24e1857SJustin Bogner 
179d24e1857SJustin Bogner     // Move the name variable to the right section.
180d24e1857SJustin Bogner     Name->setSection(getNameSection());
181d24e1857SJustin Bogner     Name->setAlignment(1);
182d24e1857SJustin Bogner   }
183d24e1857SJustin Bogner }
184d24e1857SJustin Bogner 
18561ba2e39SJustin Bogner /// Get the name of a profiling variable for a particular function.
18661ba2e39SJustin Bogner static std::string getVarName(InstrProfIncrementInst *Inc, StringRef VarName) {
18761ba2e39SJustin Bogner   auto *Arr = cast<ConstantDataArray>(Inc->getName()->getInitializer());
18861ba2e39SJustin Bogner   StringRef Name = Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();
18961ba2e39SJustin Bogner   return ("__llvm_profile_" + VarName + "_" + Name).str();
19061ba2e39SJustin Bogner }
19161ba2e39SJustin Bogner 
19261ba2e39SJustin Bogner GlobalVariable *
19361ba2e39SJustin Bogner InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
19461ba2e39SJustin Bogner   GlobalVariable *Name = Inc->getName();
19561ba2e39SJustin Bogner   auto It = RegionCounters.find(Name);
19661ba2e39SJustin Bogner   if (It != RegionCounters.end())
19761ba2e39SJustin Bogner     return It->second;
19861ba2e39SJustin Bogner 
1993cc9204aSWei Mi   // Move the name variable to the right section. Place them in a COMDAT group
2003cc9204aSWei Mi   // if the associated function is a COMDAT. This will make sure that
2013cc9204aSWei Mi   // only one copy of counters of the COMDAT function will be emitted after
2023cc9204aSWei Mi   // linking.
203df4837baSDiego Novillo   Function *Fn = Inc->getParent()->getParent();
2043cc9204aSWei Mi   Comdat *ProfileVarsComdat = nullptr;
2053cc9204aSWei Mi   if (Fn->hasComdat())
2063cc9204aSWei Mi     ProfileVarsComdat = M->getOrInsertComdat(StringRef(getVarName(Inc, "vars")));
20761ba2e39SJustin Bogner   Name->setSection(getNameSection());
20861ba2e39SJustin Bogner   Name->setAlignment(1);
2093cc9204aSWei Mi   Name->setComdat(ProfileVarsComdat);
21061ba2e39SJustin Bogner 
21161ba2e39SJustin Bogner   uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
21261ba2e39SJustin Bogner   LLVMContext &Ctx = M->getContext();
21361ba2e39SJustin Bogner   ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters);
21461ba2e39SJustin Bogner 
21561ba2e39SJustin Bogner   // Create the counters variable.
21661ba2e39SJustin Bogner   auto *Counters = new GlobalVariable(*M, CounterTy, false, Name->getLinkage(),
21761ba2e39SJustin Bogner                                       Constant::getNullValue(CounterTy),
21861ba2e39SJustin Bogner                                       getVarName(Inc, "counters"));
21961ba2e39SJustin Bogner   Counters->setVisibility(Name->getVisibility());
22061ba2e39SJustin Bogner   Counters->setSection(getCountersSection());
22161ba2e39SJustin Bogner   Counters->setAlignment(8);
2223cc9204aSWei Mi   Counters->setComdat(ProfileVarsComdat);
22361ba2e39SJustin Bogner 
22461ba2e39SJustin Bogner   RegionCounters[Inc->getName()] = Counters;
22561ba2e39SJustin Bogner 
22661ba2e39SJustin Bogner   // Create data variable.
22761ba2e39SJustin Bogner   auto *NameArrayTy = Name->getType()->getPointerElementType();
22861ba2e39SJustin Bogner   auto *Int32Ty = Type::getInt32Ty(Ctx);
22961ba2e39SJustin Bogner   auto *Int64Ty = Type::getInt64Ty(Ctx);
23061ba2e39SJustin Bogner   auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
23161ba2e39SJustin Bogner   auto *Int64PtrTy = Type::getInt64PtrTy(Ctx);
23261ba2e39SJustin Bogner 
23361ba2e39SJustin Bogner   Type *DataTypes[] = {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy};
23461ba2e39SJustin Bogner   auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes));
23561ba2e39SJustin Bogner   Constant *DataVals[] = {
23661ba2e39SJustin Bogner       ConstantInt::get(Int32Ty, NameArrayTy->getArrayNumElements()),
23761ba2e39SJustin Bogner       ConstantInt::get(Int32Ty, NumCounters),
23861ba2e39SJustin Bogner       ConstantInt::get(Int64Ty, Inc->getHash()->getZExtValue()),
23961ba2e39SJustin Bogner       ConstantExpr::getBitCast(Name, Int8PtrTy),
24061ba2e39SJustin Bogner       ConstantExpr::getBitCast(Counters, Int64PtrTy)};
24161ba2e39SJustin Bogner   auto *Data = new GlobalVariable(*M, DataTy, true, Name->getLinkage(),
24261ba2e39SJustin Bogner                                   ConstantStruct::get(DataTy, DataVals),
24361ba2e39SJustin Bogner                                   getVarName(Inc, "data"));
24461ba2e39SJustin Bogner   Data->setVisibility(Name->getVisibility());
24561ba2e39SJustin Bogner   Data->setSection(getDataSection());
24661ba2e39SJustin Bogner   Data->setAlignment(8);
2473cc9204aSWei Mi   Data->setComdat(ProfileVarsComdat);
24861ba2e39SJustin Bogner 
24961ba2e39SJustin Bogner   // Mark the data variable as used so that it isn't stripped out.
25061ba2e39SJustin Bogner   UsedVars.push_back(Data);
25161ba2e39SJustin Bogner 
25261ba2e39SJustin Bogner   return Counters;
25361ba2e39SJustin Bogner }
25461ba2e39SJustin Bogner 
25561ba2e39SJustin Bogner void InstrProfiling::emitRegistration() {
25661ba2e39SJustin Bogner   // Don't do this for Darwin.  compiler-rt uses linker magic.
25761ba2e39SJustin Bogner   if (Triple(M->getTargetTriple()).isOSDarwin())
25861ba2e39SJustin Bogner     return;
25961ba2e39SJustin Bogner 
26061ba2e39SJustin Bogner   // Construct the function.
26161ba2e39SJustin Bogner   auto *VoidTy = Type::getVoidTy(M->getContext());
26261ba2e39SJustin Bogner   auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext());
26361ba2e39SJustin Bogner   auto *RegisterFTy = FunctionType::get(VoidTy, false);
26461ba2e39SJustin Bogner   auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage,
26561ba2e39SJustin Bogner                                      "__llvm_profile_register_functions", M);
26661ba2e39SJustin Bogner   RegisterF->setUnnamedAddr(true);
26761ba2e39SJustin Bogner   if (Options.NoRedZone)
26861ba2e39SJustin Bogner     RegisterF->addFnAttr(Attribute::NoRedZone);
26961ba2e39SJustin Bogner 
270b3029d26SDiego Novillo   auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false);
27161ba2e39SJustin Bogner   auto *RuntimeRegisterF =
27261ba2e39SJustin Bogner       Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage,
27361ba2e39SJustin Bogner                        "__llvm_profile_register_function", M);
27461ba2e39SJustin Bogner 
27561ba2e39SJustin Bogner   IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", RegisterF));
27661ba2e39SJustin Bogner   for (Value *Data : UsedVars)
27761ba2e39SJustin Bogner     IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy));
27861ba2e39SJustin Bogner   IRB.CreateRetVoid();
27961ba2e39SJustin Bogner }
28061ba2e39SJustin Bogner 
28161ba2e39SJustin Bogner void InstrProfiling::emitRuntimeHook() {
28261ba2e39SJustin Bogner   const char *const RuntimeVarName = "__llvm_profile_runtime";
28361ba2e39SJustin Bogner   const char *const RuntimeUserName = "__llvm_profile_runtime_user";
28461ba2e39SJustin Bogner 
28561ba2e39SJustin Bogner   // If the module's provided its own runtime, we don't need to do anything.
28661ba2e39SJustin Bogner   if (M->getGlobalVariable(RuntimeVarName))
28761ba2e39SJustin Bogner     return;
28861ba2e39SJustin Bogner 
28961ba2e39SJustin Bogner   // Declare an external variable that will pull in the runtime initialization.
29061ba2e39SJustin Bogner   auto *Int32Ty = Type::getInt32Ty(M->getContext());
29161ba2e39SJustin Bogner   auto *Var =
29261ba2e39SJustin Bogner       new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
29361ba2e39SJustin Bogner                          nullptr, RuntimeVarName);
29461ba2e39SJustin Bogner 
29561ba2e39SJustin Bogner   // Make a function that uses it.
29661ba2e39SJustin Bogner   auto *User =
29761ba2e39SJustin Bogner       Function::Create(FunctionType::get(Int32Ty, false),
29861ba2e39SJustin Bogner                        GlobalValue::LinkOnceODRLinkage, RuntimeUserName, M);
29961ba2e39SJustin Bogner   User->addFnAttr(Attribute::NoInline);
30061ba2e39SJustin Bogner   if (Options.NoRedZone)
30161ba2e39SJustin Bogner     User->addFnAttr(Attribute::NoRedZone);
3022e427d4dSJustin Bogner   User->setVisibility(GlobalValue::HiddenVisibility);
30361ba2e39SJustin Bogner 
30461ba2e39SJustin Bogner   IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", User));
30561ba2e39SJustin Bogner   auto *Load = IRB.CreateLoad(Var);
30661ba2e39SJustin Bogner   IRB.CreateRet(Load);
30761ba2e39SJustin Bogner 
30861ba2e39SJustin Bogner   // Mark the user variable as used so that it isn't stripped out.
30961ba2e39SJustin Bogner   UsedVars.push_back(User);
31061ba2e39SJustin Bogner }
31161ba2e39SJustin Bogner 
31261ba2e39SJustin Bogner void InstrProfiling::emitUses() {
31361ba2e39SJustin Bogner   if (UsedVars.empty())
31461ba2e39SJustin Bogner     return;
31561ba2e39SJustin Bogner 
31661ba2e39SJustin Bogner   GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used");
31761ba2e39SJustin Bogner   std::vector<Constant *> MergedVars;
31861ba2e39SJustin Bogner   if (LLVMUsed) {
31961ba2e39SJustin Bogner     // Collect the existing members of llvm.used.
32061ba2e39SJustin Bogner     ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
32161ba2e39SJustin Bogner     for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I)
32261ba2e39SJustin Bogner       MergedVars.push_back(Inits->getOperand(I));
32361ba2e39SJustin Bogner     LLVMUsed->eraseFromParent();
32461ba2e39SJustin Bogner   }
32561ba2e39SJustin Bogner 
32661ba2e39SJustin Bogner   Type *i8PTy = Type::getInt8PtrTy(M->getContext());
32761ba2e39SJustin Bogner   // Add uses for our data.
32861ba2e39SJustin Bogner   for (auto *Value : UsedVars)
32961ba2e39SJustin Bogner     MergedVars.push_back(
330b3029d26SDiego Novillo         ConstantExpr::getBitCast(cast<Constant>(Value), i8PTy));
33161ba2e39SJustin Bogner 
33261ba2e39SJustin Bogner   // Recreate llvm.used.
33361ba2e39SJustin Bogner   ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size());
334b3029d26SDiego Novillo   LLVMUsed =
335b3029d26SDiego Novillo       new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage,
336b3029d26SDiego Novillo                          ConstantArray::get(ATy, MergedVars), "llvm.used");
33761ba2e39SJustin Bogner 
33861ba2e39SJustin Bogner   LLVMUsed->setSection("llvm.metadata");
33961ba2e39SJustin Bogner }
34061ba2e39SJustin Bogner 
34161ba2e39SJustin Bogner void InstrProfiling::emitInitialization() {
342ba1900ceSJustin Bogner   std::string InstrProfileOutput = Options.InstrProfileOutput;
343ba1900ceSJustin Bogner 
34461ba2e39SJustin Bogner   Constant *RegisterF = M->getFunction("__llvm_profile_register_functions");
345ba1900ceSJustin Bogner   if (!RegisterF && InstrProfileOutput.empty())
34661ba2e39SJustin Bogner     return;
34761ba2e39SJustin Bogner 
34861ba2e39SJustin Bogner   // Create the initialization function.
34961ba2e39SJustin Bogner   auto *VoidTy = Type::getVoidTy(M->getContext());
35061ba2e39SJustin Bogner   auto *F =
35161ba2e39SJustin Bogner       Function::Create(FunctionType::get(VoidTy, false),
35261ba2e39SJustin Bogner                        GlobalValue::InternalLinkage, "__llvm_profile_init", M);
35361ba2e39SJustin Bogner   F->setUnnamedAddr(true);
35461ba2e39SJustin Bogner   F->addFnAttr(Attribute::NoInline);
35561ba2e39SJustin Bogner   if (Options.NoRedZone)
35661ba2e39SJustin Bogner     F->addFnAttr(Attribute::NoRedZone);
35761ba2e39SJustin Bogner 
35861ba2e39SJustin Bogner   // Add the basic block and the necessary calls.
35961ba2e39SJustin Bogner   IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F));
360ba1900ceSJustin Bogner   if (RegisterF)
361ff6409d0SDavid Blaikie     IRB.CreateCall(RegisterF, {});
362ba1900ceSJustin Bogner   if (!InstrProfileOutput.empty()) {
363ba1900ceSJustin Bogner     auto *Int8PtrTy = Type::getInt8PtrTy(M->getContext());
364ba1900ceSJustin Bogner     auto *SetNameTy = FunctionType::get(VoidTy, Int8PtrTy, false);
365ba1900ceSJustin Bogner     auto *SetNameF =
366ba1900ceSJustin Bogner         Function::Create(SetNameTy, GlobalValue::ExternalLinkage,
36703038a56SJustin Bogner                          "__llvm_profile_override_default_filename", M);
368ba1900ceSJustin Bogner 
369b0257c84SDiego Novillo     // Create variable for profile name.
370ba1900ceSJustin Bogner     Constant *ProfileNameConst =
371ba1900ceSJustin Bogner         ConstantDataArray::getString(M->getContext(), InstrProfileOutput, true);
372ba1900ceSJustin Bogner     GlobalVariable *ProfileName =
373ba1900ceSJustin Bogner         new GlobalVariable(*M, ProfileNameConst->getType(), true,
374ba1900ceSJustin Bogner                            GlobalValue::PrivateLinkage, ProfileNameConst);
375ba1900ceSJustin Bogner 
376ba1900ceSJustin Bogner     IRB.CreateCall(SetNameF, IRB.CreatePointerCast(ProfileName, Int8PtrTy));
377ba1900ceSJustin Bogner   }
37861ba2e39SJustin Bogner   IRB.CreateRetVoid();
37961ba2e39SJustin Bogner 
38061ba2e39SJustin Bogner   appendToGlobalCtors(*M, F, 0);
38161ba2e39SJustin Bogner }
382