From 970ac60573da3cce98934d73f65285bbcbfb5ba3 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Mon, 8 Dec 2014 19:04:51 +0000 Subject: [PATCH] InstrProf: Use LLVM's -instrprof pass for profiling The logic for lowering profiling counters has been moved to an LLVM pass. Emit the intrinsics rather than duplicating the whole pass in clang. llvm-svn: 223683 --- clang/lib/CodeGen/BackendUtil.cpp | 6 + clang/lib/CodeGen/CGBlocks.cpp | 2 - clang/lib/CodeGen/CGObjC.cpp | 2 - clang/lib/CodeGen/CGStmt.cpp | 2 - clang/lib/CodeGen/CodeGenFunction.cpp | 3 - clang/lib/CodeGen/CodeGenModule.cpp | 3 - clang/lib/CodeGen/CodeGenPGO.cpp | 286 ++++----------------- clang/lib/CodeGen/CodeGenPGO.h | 24 +- .../test/Profile/c-linkage-available_externally.c | 3 +- clang/test/Profile/c-linkage.c | 13 +- clang/test/Profile/cxx-linkage.cpp | 13 +- 11 files changed, 70 insertions(+), 287 deletions(-) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 41f2131..97485b73 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -366,6 +366,12 @@ void EmitAssemblyHelper::CreatePasses() { MPM->add(createStripSymbolsPass(true)); } + if (CodeGenOpts.ProfileInstrGenerate) { + InstrProfOptions Options; + Options.NoRedZone = CodeGenOpts.DisableRedZone; + MPM->add(createInstrProfilingPass(Options)); + } + PMBuilder.populateModulePassManager(*MPM); } diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index a35076d..be3a5bf 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -1215,8 +1215,6 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, RegionCounter Cnt = getPGORegionCounter(blockDecl->getBody()); Cnt.beginRegion(Builder); EmitStmt(blockDecl->getBody()); - PGO.emitInstrumentationData(); - PGO.destroyRegionCounters(); } // Remember where we were... diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index ca67c4b..42da902 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -508,8 +508,6 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { Cnt.beginRegion(Builder); EmitCompoundStmtWithoutScope(*cast(OMD->getBody())); FinishFunction(OMD->getBodyRBrace()); - PGO.emitInstrumentationData(); - PGO.destroyRegionCounters(); } /// emitStructGetterCall - Call the runtime function to load a property diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index f207a4f..835f043 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2208,8 +2208,6 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) { PGO.assignRegionCounters(CD, F); CapturedStmtInfo->EmitBody(*this, CD->getBody()); FinishFunction(CD->getBodyRBrace()); - PGO.emitInstrumentationData(); - PGO.destroyRegionCounters(); return F; } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 02cca4b..0b9506f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -916,9 +916,6 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // a quick pass now to see if we can. if (!CurFn->doesNotThrow()) TryMarkNoThrow(CurFn); - - PGO.emitInstrumentationData(); - PGO.destroyRegionCounters(); } /// ContainsLabel - Return true if the statement contains a label in it. If diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 1c0e1f8..cd2bbed 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -345,9 +345,6 @@ void CodeGenModule::Release() { if (ObjCRuntime) if (llvm::Function *ObjCInitFunction = ObjCRuntime->ModuleInitFunction()) AddGlobalCtor(ObjCInitFunction); - if (getCodeGenOpts().ProfileInstrGenerate) - if (llvm::Function *PGOInit = CodeGenPGO::emitInitialization(*this)) - AddGlobalCtor(PGOInit, 0); if (PGOReader && PGOStats.hasDiagnostics()) PGOStats.reportDiagnostics(getDiags(), getCodeGenOpts().MainFileName); EmitCtorList(GlobalCtors, "llvm.global_ctors"); diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 38f2162..71bd1ca 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -16,6 +16,7 @@ #include "CoverageMappingGen.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtVisitor.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/Endian.h" @@ -46,190 +47,33 @@ void CodeGenPGO::setFuncName(StringRef Name, else FuncName = FuncName.insert(0, CGM.getCodeGenOpts().MainFileName + ":"); } + + // If we're generating a profile, create a variable for the name. + if (CGM.getCodeGenOpts().ProfileInstrGenerate) + createFuncNameVar(Linkage); } void CodeGenPGO::setFuncName(llvm::Function *Fn) { setFuncName(Fn->getName(), Fn->getLinkage()); } -void CodeGenPGO::setVarLinkage(llvm::GlobalValue::LinkageTypes Linkage) { - // Set the linkage for variables based on the function linkage. Usually, we - // want to match it, but available_externally and extern_weak both have the - // wrong semantics. - VarLinkage = Linkage; - switch (VarLinkage) { - case llvm::GlobalValue::ExternalWeakLinkage: - VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage; - break; - case llvm::GlobalValue::AvailableExternallyLinkage: - VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage; - break; - default: - break; - } -} - -static llvm::Function *getRegisterFunc(CodeGenModule &CGM) { - return CGM.getModule().getFunction("__llvm_profile_register_functions"); -} - -static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) { - // Don't do this for Darwin. compiler-rt uses linker magic. - if (CGM.getTarget().getTriple().isOSDarwin()) - return nullptr; - - // Only need to insert this once per module. - if (llvm::Function *RegisterF = getRegisterFunc(CGM)) - return &RegisterF->getEntryBlock(); - - // Construct the function. - auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext()); - auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false); - auto *RegisterF = llvm::Function::Create(RegisterFTy, - llvm::GlobalValue::InternalLinkage, - "__llvm_profile_register_functions", - &CGM.getModule()); - RegisterF->setUnnamedAddr(true); - if (CGM.getCodeGenOpts().DisableRedZone) - RegisterF->addFnAttr(llvm::Attribute::NoRedZone); - - // Construct and return the entry block. - auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF); - CGBuilderTy Builder(BB); - Builder.CreateRetVoid(); - return BB; -} - -static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) { - auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext()); - auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); - auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false); - return CGM.getModule().getOrInsertFunction("__llvm_profile_register_function", - RuntimeRegisterTy); -} - -static bool isMachO(const CodeGenModule &CGM) { - return CGM.getTarget().getTriple().isOSBinFormatMachO(); -} - -static StringRef getCountersSection(const CodeGenModule &CGM) { - return isMachO(CGM) ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts"; -} - -static StringRef getNameSection(const CodeGenModule &CGM) { - return isMachO(CGM) ? "__DATA,__llvm_prf_names" : "__llvm_prf_names"; -} - -static StringRef getDataSection(const CodeGenModule &CGM) { - return isMachO(CGM) ? "__DATA,__llvm_prf_data" : "__llvm_prf_data"; -} - -llvm::GlobalVariable *CodeGenPGO::buildDataVar() { - // Create name variable. - llvm::LLVMContext &Ctx = CGM.getLLVMContext(); - auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(), - false); - auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(), - true, VarLinkage, VarName, - getFuncVarName("name")); - Name->setSection(getNameSection(CGM)); - Name->setAlignment(1); - - // Create data variable. - auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); - auto *Int64Ty = llvm::Type::getInt64Ty(Ctx); - auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx); - auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx); - llvm::GlobalVariable *Data = nullptr; - if (RegionCounters) { - llvm::Type *DataTypes[] = { - Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy - }; - auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes)); - llvm::Constant *DataVals[] = { - llvm::ConstantInt::get(Int32Ty, getFuncName().size()), - llvm::ConstantInt::get(Int32Ty, NumRegionCounters), - llvm::ConstantInt::get(Int64Ty, FunctionHash), - llvm::ConstantExpr::getBitCast(Name, Int8PtrTy), - llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy) - }; - Data = - new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage, - llvm::ConstantStruct::get(DataTy, DataVals), - getFuncVarName("data")); - - // All the data should be packed into an array in its own section. - Data->setSection(getDataSection(CGM)); - Data->setAlignment(8); - } - - // Create coverage mapping data variable. - if (!CoverageMapping.empty()) - CGM.getCoverageMapping()->addFunctionMappingRecord(Name, getFuncName(), - FunctionHash, - CoverageMapping); - - // Hide all these symbols so that we correctly get a copy for each - // executable. The profile format expects names and counters to be - // contiguous, so references into shared objects would be invalid. - if (!llvm::GlobalValue::isLocalLinkage(VarLinkage)) { - Name->setVisibility(llvm::GlobalValue::HiddenVisibility); - if (Data) { - Data->setVisibility(llvm::GlobalValue::HiddenVisibility); - RegionCounters->setVisibility(llvm::GlobalValue::HiddenVisibility); - } - } - - // Make sure the data doesn't get deleted. - if (Data) CGM.addUsedGlobal(Data); - return Data; -} - -void CodeGenPGO::emitInstrumentationData() { - if (!RegionCounters) - return; - - // Build the data. - auto *Data = buildDataVar(); - - // Register the data. - auto *RegisterBB = getOrInsertRegisterBB(CGM); - if (!RegisterBB) - return; - CGBuilderTy Builder(RegisterBB->getTerminator()); - auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); - Builder.CreateCall(getOrInsertRuntimeRegister(CGM), - Builder.CreateBitCast(Data, VoidPtrTy)); -} - -llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) { - if (!CGM.getCodeGenOpts().ProfileInstrGenerate) - return nullptr; - - assert(CGM.getModule().getFunction("__llvm_profile_init") == nullptr && - "profile initialization already emitted"); +void CodeGenPGO::createFuncNameVar(llvm::GlobalValue::LinkageTypes Linkage) { + // Usually, we want to match the function's linkage, but + // available_externally and extern_weak both have the wrong semantics. + if (Linkage == llvm::GlobalValue::ExternalWeakLinkage) + Linkage = llvm::GlobalValue::LinkOnceAnyLinkage; + else if (Linkage == llvm::GlobalValue::AvailableExternallyLinkage) + Linkage = llvm::GlobalValue::LinkOnceODRLinkage; - // Get the function to call at initialization. - llvm::Constant *RegisterF = getRegisterFunc(CGM); - if (!RegisterF) - return nullptr; + auto *Value = + llvm::ConstantDataArray::getString(CGM.getLLVMContext(), FuncName, false); + FuncNameVar = + new llvm::GlobalVariable(CGM.getModule(), Value->getType(), true, Linkage, + Value, "__llvm_profile_name_" + FuncName); - // Create the initialization function. - auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext()); - auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false), - llvm::GlobalValue::InternalLinkage, - "__llvm_profile_init", &CGM.getModule()); - F->setUnnamedAddr(true); - F->addFnAttr(llvm::Attribute::NoInline); - if (CGM.getCodeGenOpts().DisableRedZone) - F->addFnAttr(llvm::Attribute::NoRedZone); - - // Add the basic block and the necessary calls. - CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F)); - Builder.CreateCall(RegisterF); - Builder.CreateRetVoid(); - - return F; + // Hide the symbol so that we correctly get a copy for each executable. + if (!llvm::GlobalValue::isLocalLinkage(FuncNameVar->getLinkage())) + FuncNameVar->setVisibility(llvm::GlobalValue::HiddenVisibility); } namespace { @@ -809,35 +653,6 @@ uint64_t PGOHash::finalize() { return endian::read(Result); } -static void emitRuntimeHook(CodeGenModule &CGM) { - const char *const RuntimeVarName = "__llvm_profile_runtime"; - const char *const RuntimeUserName = "__llvm_profile_runtime_user"; - if (CGM.getModule().getGlobalVariable(RuntimeVarName)) - return; - - // Declare the runtime hook. - llvm::LLVMContext &Ctx = CGM.getLLVMContext(); - auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); - auto *Var = new llvm::GlobalVariable(CGM.getModule(), Int32Ty, false, - llvm::GlobalValue::ExternalLinkage, - nullptr, RuntimeVarName); - - // Make a function that uses it. - auto *User = llvm::Function::Create(llvm::FunctionType::get(Int32Ty, false), - llvm::GlobalValue::LinkOnceODRLinkage, - RuntimeUserName, &CGM.getModule()); - User->addFnAttr(llvm::Attribute::NoInline); - if (CGM.getCodeGenOpts().DisableRedZone) - User->addFnAttr(llvm::Attribute::NoRedZone); - CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", User)); - auto *Load = Builder.CreateLoad(Var); - Builder.CreateRet(Load); - - // Create a use of the function. Now the definition of the runtime variable - // should get pulled in, along with any static initializears. - CGM.addUsedGlobal(User); -} - void CodeGenPGO::checkGlobalDecl(GlobalDecl GD) { // Make sure we only emit coverage mapping for one constructor/destructor. // Clang emits several functions for the constructor and the destructor of @@ -861,15 +676,10 @@ void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) { return; CGM.ClearUnusedCoverageMapping(D); setFuncName(Fn); - setVarLinkage(Fn->getLinkage()); mapRegionCounters(D); - if (InstrumentRegions) { - emitRuntimeHook(CGM); - emitCounterVariables(); - if (CGM.getCodeGenOpts().CoverageMapping) - emitCounterRegionMapping(D); - } + if (CGM.getCodeGenOpts().CoverageMapping) + emitCounterRegionMapping(D); if (PGOReader) { SourceManager &SM = CGM.getContext().getSourceManager(); loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation())); @@ -902,12 +712,19 @@ void CodeGenPGO::emitCounterRegionMapping(const Decl *D) { if (CGM.getContext().getSourceManager().isInSystemHeader(Loc)) return; + std::string CoverageMapping; llvm::raw_string_ostream OS(CoverageMapping); CoverageMappingGen MappingGen(*CGM.getCoverageMapping(), CGM.getContext().getSourceManager(), CGM.getLangOpts(), RegionCounterMap.get()); MappingGen.emitCounterMapping(D, OS); OS.flush(); + + if (CoverageMapping.empty()) + return; + + CGM.getCoverageMapping()->addFunctionMappingRecord( + FuncNameVar, FuncName, FunctionHash, CoverageMapping); } void @@ -916,20 +733,25 @@ CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef FuncName, if (SkipCoverageMapping) return; setFuncName(FuncName, Linkage); - setVarLinkage(Linkage); // Don't map the functions inside the system headers auto Loc = D->getBody()->getLocStart(); if (CGM.getContext().getSourceManager().isInSystemHeader(Loc)) return; + std::string CoverageMapping; llvm::raw_string_ostream OS(CoverageMapping); CoverageMappingGen MappingGen(*CGM.getCoverageMapping(), CGM.getContext().getSourceManager(), CGM.getLangOpts()); MappingGen.emitEmptyMapping(D, OS); OS.flush(); - buildDataVar(); + + if (CoverageMapping.empty()) + return; + + CGM.getCoverageMapping()->addFunctionMappingRecord( + FuncNameVar, FuncName, FunctionHash, CoverageMapping); } void CodeGenPGO::computeRegionCounts(const Decl *D) { @@ -963,34 +785,23 @@ CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, Fn->addFnAttr(llvm::Attribute::Cold); } -void CodeGenPGO::emitCounterVariables() { - llvm::LLVMContext &Ctx = CGM.getLLVMContext(); - llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx), - NumRegionCounters); - RegionCounters = - new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, VarLinkage, - llvm::Constant::getNullValue(CounterTy), - getFuncVarName("counters")); - RegionCounters->setAlignment(8); - RegionCounters->setSection(getCountersSection(CGM)); -} - void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) { - if (!RegionCounters) + if (!CGM.getCodeGenOpts().ProfileInstrGenerate || !RegionCounterMap) return; - llvm::Value *Addr = - Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter); - llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount"); - Count = Builder.CreateAdd(Count, Builder.getInt64(1)); - Builder.CreateStore(Count, Addr); + auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); + Builder.CreateCall4(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment), + llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), + Builder.getInt64(FunctionHash), + Builder.getInt32(NumRegionCounters), + Builder.getInt32(Counter)); } void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader, bool IsInMainFile) { CGM.getPGOStats().addVisited(IsInMainFile); RegionCounts.clear(); - if (std::error_code EC = PGOReader->getFunctionCounts( - getFuncName(), FunctionHash, RegionCounts)) { + if (std::error_code EC = + PGOReader->getFunctionCounts(FuncName, FunctionHash, RegionCounts)) { if (EC == llvm::instrprof_error::unknown_function) CGM.getPGOStats().addMissing(IsInMainFile); else if (EC == llvm::instrprof_error::hash_mismatch) @@ -1002,13 +813,6 @@ void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader, } } -void CodeGenPGO::destroyRegionCounters() { - RegionCounterMap.reset(); - StmtCountMap.reset(); - RegionCounts.clear(); - RegionCounters = nullptr; -} - /// \brief Calculate what to divide by to scale weights. /// /// Given the maximum weight, calculate a divisor that will scale all the diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 57bde0f..431c850 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -32,24 +32,21 @@ class CodeGenPGO { private: CodeGenModule &CGM; std::string FuncName; - llvm::GlobalValue::LinkageTypes VarLinkage; + llvm::GlobalVariable *FuncNameVar; unsigned NumRegionCounters; uint64_t FunctionHash; - llvm::GlobalVariable *RegionCounters; std::unique_ptr> RegionCounterMap; std::unique_ptr> StmtCountMap; std::vector RegionCounts; uint64_t CurrentRegionCount; - std::string CoverageMapping; /// \brief A flag that is set to true when this function doesn't need /// to have coverage mapping data. bool SkipCoverageMapping; public: CodeGenPGO(CodeGenModule &CGM) - : CGM(CGM), NumRegionCounters(0), FunctionHash(0), - RegionCounters(nullptr), CurrentRegionCount(0), + : CGM(CGM), NumRegionCounters(0), FunctionHash(0), CurrentRegionCount(0), SkipCoverageMapping(false) {} /// Whether or not we have PGO region data for the current function. This is @@ -57,13 +54,6 @@ public: /// discarded. bool haveRegionCounts() const { return !RegionCounts.empty(); } - /// Get the string used to identify this function in the profile data. - /// For functions with local linkage, this includes the main file name. - StringRef getFuncName() const { return StringRef(FuncName); } - std::string getFuncVarName(StringRef VarName) const { - return ("__llvm_profile_" + VarName + "_" + FuncName).str(); - } - /// Return the counter value of the current region. uint64_t getCurrentRegionCount() const { return CurrentRegionCount; } @@ -110,13 +100,6 @@ public: /// generates global variables or associates PGO data with each of the /// counters depending on whether we are generating or using instrumentation. void assignRegionCounters(const Decl *D, llvm::Function *Fn); - /// Emit static data structures for instrumentation data. - void emitInstrumentationData(); - /// Clean up region counter state. Must be called if assignRegionCounters is - /// used. - void destroyRegionCounters(); - /// Emit static initialization code, if any. - static llvm::Function *emitInitialization(CodeGenModule &CGM); /// Emit a coverage mapping range with a counter zero /// for an unused declaration. void emitEmptyCounterMapping(const Decl *D, StringRef FuncName, @@ -124,7 +107,7 @@ public: private: void setFuncName(llvm::Function *Fn); void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes Linkage); - void setVarLinkage(llvm::GlobalValue::LinkageTypes Linkage); + void createFuncNameVar(llvm::GlobalValue::LinkageTypes Linkage); void mapRegionCounters(const Decl *D); void computeRegionCounts(const Decl *D); void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, @@ -132,7 +115,6 @@ private: void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader, bool IsInMainFile); void emitCounterVariables(); - llvm::GlobalVariable *buildDataVar(); void emitCounterRegionMapping(const Decl *D); /// Emit code to increment the counter at the given index diff --git a/clang/test/Profile/c-linkage-available_externally.c b/clang/test/Profile/c-linkage-available_externally.c index aa1080b..e89632a 100644 --- a/clang/test/Profile/c-linkage-available_externally.c +++ b/clang/test/Profile/c-linkage-available_externally.c @@ -2,8 +2,9 @@ // get thrown out. // RUN: %clang_cc1 -O2 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage-available_externally.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck %s -// CHECK: @__llvm_profile_counters_foo = linkonce_odr hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 // CHECK: @__llvm_profile_name_foo = linkonce_odr hidden constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1 + +// CHECK: @__llvm_profile_counters_foo = linkonce_odr hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 // CHECK: @__llvm_profile_data_foo = linkonce_odr hidden constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 inline int foo(void) { return 1; } diff --git a/clang/test/Profile/c-linkage.c b/clang/test/Profile/c-linkage.c index 2406e3e..94393a4 100644 --- a/clang/test/Profile/c-linkage.c +++ b/clang/test/Profile/c-linkage.c @@ -1,20 +1,21 @@ // Check the data structures emitted by instrumentation. // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck %s -// CHECK: @__llvm_profile_runtime = external global i32 -// CHECK: @__llvm_profile_counters_foo = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 // CHECK: @__llvm_profile_name_foo = hidden constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1 +// CHECK: @__llvm_profile_name_foo_weak = weak hidden constant [8 x i8] c"foo_weak", section "__DATA,__llvm_prf_names", align 1 +// CHECK: @__llvm_profile_name_main = hidden constant [4 x i8] c"main", section "__DATA,__llvm_prf_names", align 1 +// CHECK: @"__llvm_profile_name_c-linkage.c:foo_internal" = internal constant [24 x i8] c"c-linkage.c:foo_internal", section "__DATA,__llvm_prf_names", align 1 + +// CHECK: @__llvm_profile_counters_foo = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 // CHECK: @__llvm_profile_data_foo = hidden constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 void foo(void) { } // CHECK: @__llvm_profile_counters_foo_weak = weak hidden global [5 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 -// CHECK: @__llvm_profile_name_foo_weak = weak hidden constant [8 x i8] c"foo_weak", section "__DATA,__llvm_prf_names", align 1 // CHECK: @__llvm_profile_data_foo_weak = weak hidden constant { i32, i32, i64, i8*, i64* } { i32 8, i32 5, i64 {{[0-9]+}}, i8* getelementptr inbounds ([8 x i8]* @__llvm_profile_name_foo_weak, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_profile_counters_foo_weak, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 void foo_weak(void) __attribute__((weak)); void foo_weak(void) { if (0){} if (0){} if (0){} if (0){} } // CHECK: @__llvm_profile_counters_main = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 -// CHECK: @__llvm_profile_name_main = hidden constant [4 x i8] c"main", section "__DATA,__llvm_prf_names", align 1 // CHECK: @__llvm_profile_data_main = hidden constant { i32, i32, i64, i8*, i64* } { i32 4, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([4 x i8]* @__llvm_profile_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 static void foo_internal(void); int main(void) { @@ -25,11 +26,11 @@ int main(void) { } // CHECK: @"__llvm_profile_counters_c-linkage.c:foo_internal" = internal global [3 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 -// CHECK: @"__llvm_profile_name_c-linkage.c:foo_internal" = internal constant [24 x i8] c"c-linkage.c:foo_internal", section "__DATA,__llvm_prf_names", align 1 // CHECK: @"__llvm_profile_data_c-linkage.c:foo_internal" = internal constant { i32, i32, i64, i8*, i64* } { i32 24, i32 3, i64 {{[0-9]+}}, i8* getelementptr inbounds ([24 x i8]* @"__llvm_profile_name_c-linkage.c:foo_internal", i32 0, i32 0), i64* getelementptr inbounds ([3 x i64]* @"__llvm_profile_counters_c-linkage.c:foo_internal", i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 static void foo_internal(void) { if (0){} if (0){} } -// CHECK: @llvm.used = appending global [5 x i8*] [i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo_weak to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_main to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @"__llvm_profile_data_c-linkage.c:foo_internal" to i8*)], section "llvm.metadata" +// CHECK: @__llvm_profile_runtime = external global i32 +// CHECK: @llvm.used = appending global [5 x i8*] [i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo_weak to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_main to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @"__llvm_profile_data_c-linkage.c:foo_internal" to i8*), i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*)], section "llvm.metadata" // CHECK: define linkonce_odr i32 @__llvm_profile_runtime_user() {{.*}} { // CHECK: %[[REG:.*]] = load i32* @__llvm_profile_runtime diff --git a/clang/test/Profile/cxx-linkage.cpp b/clang/test/Profile/cxx-linkage.cpp index df896e7..e410218 100644 --- a/clang/test/Profile/cxx-linkage.cpp +++ b/clang/test/Profile/cxx-linkage.cpp @@ -1,19 +1,20 @@ // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -emit-llvm -main-file-name cxx-linkage.cpp %s -o - -fprofile-instr-generate | FileCheck %s -// CHECK: @__llvm_profile_runtime = external global i32 -// CHECK: @__llvm_profile_counters__Z3foov = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 // CHECK: @__llvm_profile_name__Z3foov = hidden constant [7 x i8] c"_Z3foov", section "__DATA,__llvm_prf_names", align 1 +// CHECK: @__llvm_profile_name__Z8foo_weakv = weak hidden constant [12 x i8] c"_Z8foo_weakv", section "__DATA,__llvm_prf_names", align 1 +// CHECK: @__llvm_profile_name_main = hidden constant [4 x i8] c"main", section "__DATA,__llvm_prf_names", align 1 +// CHECK: @__llvm_profile_name__Z10foo_inlinev = linkonce_odr hidden constant [15 x i8] c"_Z10foo_inlinev", section "__DATA,__llvm_prf_names", align 1 + +// CHECK: @__llvm_profile_counters__Z3foov = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 // CHECK: @__llvm_profile_data__Z3foov = hidden constant { i32, i32, i64, i8*, i64* } { i32 7, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([7 x i8]* @__llvm_profile_name__Z3foov, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters__Z3foov, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 void foo(void) { } // CHECK: @__llvm_profile_counters__Z8foo_weakv = weak hidden global [5 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 -// CHECK: @__llvm_profile_name__Z8foo_weakv = weak hidden constant [12 x i8] c"_Z8foo_weakv", section "__DATA,__llvm_prf_names", align 1 // CHECK: @__llvm_profile_data__Z8foo_weakv = weak hidden constant { i32, i32, i64, i8*, i64* } { i32 12, i32 5, i64 {{[0-9]+}}, i8* getelementptr inbounds ([12 x i8]* @__llvm_profile_name__Z8foo_weakv, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_profile_counters__Z8foo_weakv, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 void foo_weak(void) __attribute__((weak)); void foo_weak(void) { if (0){} if (0){} if (0){} if (0){} } // CHECK: @__llvm_profile_counters_main = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 -// CHECK: @__llvm_profile_name_main = hidden constant [4 x i8] c"main", section "__DATA,__llvm_prf_names", align 1 // CHECK: @__llvm_profile_data_main = hidden constant { i32, i32, i64, i8*, i64* } { i32 4, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([4 x i8]* @__llvm_profile_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 inline void foo_inline(void); int main(void) { @@ -24,11 +25,11 @@ int main(void) { } // CHECK: @__llvm_profile_counters__Z10foo_inlinev = linkonce_odr hidden global [7 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 -// CHECK: @__llvm_profile_name__Z10foo_inlinev = linkonce_odr hidden constant [15 x i8] c"_Z10foo_inlinev", section "__DATA,__llvm_prf_names", align 1 // CHECK: @__llvm_profile_data__Z10foo_inlinev = linkonce_odr hidden constant { i32, i32, i64, i8*, i64* } { i32 15, i32 7, i64 {{[0-9]+}}, i8* getelementptr inbounds ([15 x i8]* @__llvm_profile_name__Z10foo_inlinev, i32 0, i32 0), i64* getelementptr inbounds ([7 x i64]* @__llvm_profile_counters__Z10foo_inlinev, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 inline void foo_inline(void) { if (0){} if (0){} if (0){} if (0){} if (0){} if (0){}} -// CHECK: @llvm.used = appending global [5 x i8*] [i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z3foov to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z8foo_weakv to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_main to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z10foo_inlinev to i8*)], section "llvm.metadata" +// CHECK: @__llvm_profile_runtime = external global i32 +// CHECK: @llvm.used = appending global [5 x i8*] [i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z3foov to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z8foo_weakv to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_main to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z10foo_inlinev to i8*), i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*)], section "llvm.metadata" // CHECK: define linkonce_odr i32 @__llvm_profile_runtime_user() {{.*}} { // CHECK: %[[REG:.*]] = load i32* @__llvm_profile_runtime -- 2.7.4