diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 13 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenPGO.cpp | 45 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenPGO.h | 21 |
3 files changed, 56 insertions, 23 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index d0f1cb6b258..975ae6cb46b 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -589,15 +589,6 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, if (CGM.getCodeGenOpts().InstrumentForProfiling) EmitMCountInstrumentation(); - if (CGM.getPGOData() && D) { - // Turn on InlineHint attribute for hot functions. - if (CGM.getPGOData()->isHotFunction(CGM.getMangledName(GD))) - Fn->addFnAttr(llvm::Attribute::InlineHint); - // Turn on Cold attribute for cold functions. - else if (CGM.getPGOData()->isColdFunction(CGM.getMangledName(GD))) - Fn->addFnAttr(llvm::Attribute::Cold); - } - if (RetTy->isVoidType()) { // Void type; nothing to return. ReturnValue = 0; @@ -770,7 +761,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, StartFunction(GD, ResTy, Fn, FnInfo, Args, BodyRange.getBegin()); // Generate the body of the function. - PGO.assignRegionCounters(GD.getDecl(), CGM.getMangledName(GD)); + PGO.assignRegionCounters(GD.getDecl(), CurFn); if (isa<CXXDestructorDecl>(FD)) EmitDestructorBody(Args); else if (isa<CXXConstructorDecl>(FD)) @@ -831,7 +822,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, if (!CurFn->doesNotThrow()) TryMarkNoThrow(CurFn); - PGO.emitWriteoutFunction(CGM.getMangledName(CurGD)); + PGO.emitWriteoutFunction(); PGO.destroyRegionCounters(); } diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 658fb2c9986..6678c37929b 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -161,7 +161,32 @@ bool PGOProfileData::getFunctionCounts(StringRef FuncName, return false; } -void CodeGenPGO::emitWriteoutFunction(StringRef Name) { +void CodeGenPGO::setFuncName(llvm::Function *Fn) { + StringRef Func = Fn->getName(); + + // Function names may be prefixed with a binary '1' to indicate + // that the backend should not modify the symbols due to any platform + // naming convention. Do not include that '1' in the PGO profile name. + if (Func[0] == '\1') + Func = Func.substr(1); + + if (!Fn->hasLocalLinkage()) { + FuncName = new std::string(Func); + return; + } + + // For local symbols, prepend the main file name to distinguish them. + // Do not include the full path in the file name since there's no guarantee + // that it will stay the same, e.g., if the files are checked out from + // version control in different locations. + FuncName = new std::string(CGM.getCodeGenOpts().MainFileName); + if (FuncName->empty()) + FuncName->assign("<unknown>"); + FuncName->append(":"); + FuncName->append(Func); +} + +void CodeGenPGO::emitWriteoutFunction() { if (!CGM.getCodeGenOpts().ProfileInstrGenerate) return; @@ -206,7 +231,7 @@ void CodeGenPGO::emitWriteoutFunction(StringRef Name) { CGM.getModule().getOrInsertFunction("llvm_pgo_emit", FTy); llvm::Constant *NameString = - CGM.GetAddrOfConstantCString(Name, "__llvm_pgo_name"); + CGM.GetAddrOfConstantCString(getFuncName(), "__llvm_pgo_name"); NameString = llvm::ConstantExpr::getBitCast(NameString, Int8PtrTy); PGOBuilder.CreateCall3(EmitFunc, NameString, PGOBuilder.getInt32(NumRegionCounters), @@ -727,19 +752,27 @@ namespace { }; } -void CodeGenPGO::assignRegionCounters(const Decl *D, StringRef Name) { +void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) { bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate; PGOProfileData *PGOData = CGM.getPGOData(); if (!InstrumentRegions && !PGOData) return; if (!D) return; + setFuncName(Fn); mapRegionCounters(D); if (InstrumentRegions) emitCounterVariables(); if (PGOData) { - loadRegionCounts(Name, PGOData); + loadRegionCounts(PGOData); computeRegionCounts(D); + + // Turn on InlineHint attribute for hot functions. + if (PGOData->isHotFunction(getFuncName())) + Fn->addFnAttr(llvm::Attribute::InlineHint); + // Turn on Cold attribute for cold functions. + else if (PGOData->isColdFunction(getFuncName())) + Fn->addFnAttr(llvm::Attribute::Cold); } } @@ -779,13 +812,13 @@ void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) { Builder.CreateStore(Count, Addr); } -void CodeGenPGO::loadRegionCounts(StringRef Name, PGOProfileData *PGOData) { +void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) { // For now, ignore the counts from the PGO data file only if the number of // counters does not match. This could be tightened down in the future to // ignore counts when the input changes in various ways, e.g., by comparing a // hash value based on some characteristics of the input. RegionCounts = new std::vector<uint64_t>(); - if (PGOData->getFunctionCounts(Name, *RegionCounts) || + if (PGOData->getFunctionCounts(getFuncName(), *RegionCounts) || RegionCounts->size() != NumRegionCounters) { delete RegionCounts; RegionCounts = 0; diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index c9c0e8b004c..0fc570ad9cd 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -56,6 +56,7 @@ public: class CodeGenPGO { private: CodeGenModule &CGM; + std::string *FuncName; unsigned NumRegionCounters; llvm::GlobalVariable *RegionCounters; @@ -66,15 +67,22 @@ private: public: CodeGenPGO(CodeGenModule &CGM) - : CGM(CGM), NumRegionCounters(0), RegionCounters(0), RegionCounterMap(0), - StmtCountMap(0), RegionCounts(0), CurrentRegionCount(0) {} - ~CodeGenPGO() {} + : CGM(CGM), FuncName(0), NumRegionCounters(0), RegionCounters(0), + RegionCounterMap(0), StmtCountMap(0), RegionCounts(0), + CurrentRegionCount(0) {} + ~CodeGenPGO() { + if (FuncName) delete FuncName; + } /// Whether or not we have PGO region data for the current function. This is /// false both when we have no data at all and when our data has been /// discarded. bool haveRegionCounts() const { return RegionCounts != 0; } + /// Get the string used to identify this function in the profile data. + /// For functions with local linkage, this includes the main file name. + const StringRef getFuncName() const { return StringRef(*FuncName); } + /// Return the counter value of the current region. uint64_t getCurrentRegionCount() const { return CurrentRegionCount; } @@ -118,9 +126,9 @@ public: /// function. Does nothing if instrumentation is not enabled and either /// 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, StringRef Name); + void assignRegionCounters(const Decl *D, llvm::Function *Fn); /// Emit code to write counts for a given function to disk, if necessary. - void emitWriteoutFunction(StringRef Name); + void emitWriteoutFunction(); /// Clean up region counter state. Must be called if assignRegionCounters is /// used. void destroyRegionCounters(); @@ -129,9 +137,10 @@ public: static llvm::Function *emitInitialization(CodeGenModule &CGM); private: + void setFuncName(llvm::Function *Fn); void mapRegionCounters(const Decl *D); void computeRegionCounts(const Decl *D); - void loadRegionCounts(StringRef Name, PGOProfileData *PGOData); + void loadRegionCounts(PGOProfileData *PGOData); void emitCounterVariables(); /// Emit code to increment the counter at the given index |