r203075 - PGO: Use the main file name to help distinguish functions with local linkage.

Bob Wilson bob.wilson at apple.com
Wed Mar 5 20:55:41 PST 2014


Author: bwilson
Date: Wed Mar  5 22:55:41 2014
New Revision: 203075

URL: http://llvm.org/viewvc/llvm-project?rev=203075&view=rev
Log:
PGO: Use the main file name to help distinguish functions with local linkage.

In addition, for all functions, use the name from the llvm::Function to
identify the function in the profile data. Compute that "function name",
including the file name for local functions, once when assigning the PGO
counters and store it in the CodeGenPGO class.

Move the code to add InlineHint and Cold attributes out of StartFunction(),
because the "function name" string isn't available at that point.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
    cfe/trunk/lib/CodeGen/CodeGenPGO.h
    cfe/trunk/test/CodeGen/Inputs/instr-profile.pgodata
    cfe/trunk/test/CodeGen/instr-profile.c

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=203075&r1=203074&r2=203075&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Mar  5 22:55:41 2014
@@ -589,15 +589,6 @@ void CodeGenFunction::StartFunction(Glob
   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(Globa
   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(Globa
   if (!CurFn->doesNotThrow())
     TryMarkNoThrow(CurFn);
 
-  PGO.emitWriteoutFunction(CGM.getMangledName(CurGD));
+  PGO.emitWriteoutFunction();
   PGO.destroyRegionCounters();
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=203075&r1=203074&r2=203075&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Wed Mar  5 22:55:41 2014
@@ -161,7 +161,32 @@ bool PGOProfileData::getFunctionCounts(S
   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(St
     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(CG
   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;

Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=203075&r1=203074&r2=203075&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.h Wed Mar  5 22:55:41 2014
@@ -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

Modified: cfe/trunk/test/CodeGen/Inputs/instr-profile.pgodata
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/Inputs/instr-profile.pgodata?rev=203075&r1=203074&r2=203075&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/Inputs/instr-profile.pgodata (original)
+++ cfe/trunk/test/CodeGen/Inputs/instr-profile.pgodata Wed Mar  5 22:55:41 2014
@@ -132,3 +132,7 @@ no_usable_data 5
 main 1
 1
 
+instr-profile.c:static_func 2
+1
+10
+

Modified: cfe/trunk/test/CodeGen/instr-profile.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/instr-profile.c?rev=203075&r1=203074&r2=203075&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/instr-profile.c (original)
+++ cfe/trunk/test/CodeGen/instr-profile.c Wed Mar  5 22:55:41 2014
@@ -18,6 +18,7 @@
 // PGOGEN: @[[BLC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64]  zeroinitializer
 // PGOGEN: @[[NOC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64]  zeroinitializer
 // PGOGEN: @[[MAC:__llvm_pgo_ctr[0-9]*]] = private global [1 x i64]  zeroinitializer
+// PGOGEN: @[[STF:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64]  zeroinitializer
 
 // PGOGEN-LABEL: @simple_loops()
 // PGOUSE-LABEL: @simple_loops()
@@ -445,6 +446,16 @@ void no_usable_data() {
   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
 }
 
+// PGOGEN-LABEL: @static_func()
+// PGOUSE-LABEL: @static_func()
+// PGOGEN: store {{.*}} @[[STF]], i64 0, i64 0
+static void static_func() {
+  // PGOGEN: store {{.*}} @[[STF]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[ST1:[0-9]+]]
+  for (int i = 0; i < 10; ++i) {
+  }
+}
+
 // PGOUSE-DAG: ![[SL1]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
 // PGOUSE-DAG: ![[SL2]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
 // PGOUSE-DAG: ![[SL3]] = metadata !{metadata !"branch_weights", i32 76, i32 2}
@@ -513,6 +524,7 @@ void no_usable_data() {
 // PGOUSE-DAG: ![[BL6]] = metadata !{metadata !"branch_weights", i32 51, i32 2}
 // PGOUSE-DAG: ![[BL7]] = metadata !{metadata !"branch_weights", i32 26, i32 27}
 // PGOUSE-DAG: ![[BL8]] = metadata !{metadata !"branch_weights", i32 51, i32 2}
+// PGOUSE-DAG: ![[ST1]] = metadata !{metadata !"branch_weights", i32 11, i32 2}
 
 int main(int argc, const char *argv[]) {
   simple_loops();
@@ -525,5 +537,6 @@ int main(int argc, const char *argv[]) {
   boolop_loops();
   do_fallthrough();
   no_usable_data();
+  static_func();
   return 0;
 }





More information about the cfe-commits mailing list