summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp13
-rw-r--r--clang/lib/CodeGen/CodeGenPGO.cpp45
-rw-r--r--clang/lib/CodeGen/CodeGenPGO.h21
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
OpenPOWER on IntegriCloud