r200874 - PGO: instrumentation based profiling sets function attributes.

Nick Lewycky nlewycky at google.com
Wed Feb 5 15:40:12 PST 2014


On 5 February 2014 12:40, Manman Ren <manman.ren at gmail.com> wrote:

> Author: mren
> Date: Wed Feb  5 14:40:15 2014
> New Revision: 200874
>
> URL: http://llvm.org/viewvc/llvm-project?rev=200874&view=rev
> Log:
> PGO: instrumentation based profiling sets function attributes.
>
> We collect a maximal function count among all functions in the pgo data
> file.
> For functions that are hot, we set its InlineHint attribute. For functions
> that
> are cold, we set its Cold attribute.
>
> We currently treat functions with >= 30% of the maximal function count as
> hot
> and functions with <= 1% of the maximal function count are treated as cold.
> These two numbers are from preliminary tuning on SPEC.
>
> This commit should not affect non-PGO builds and should boost performance
> on
> instrumentation based PGO.
>
> Added:
>     cfe/trunk/test/CodeGen/Inputs/instr-attribute.pgodata
>     cfe/trunk/test/CodeGen/instr-attribute.c
> Modified:
>     cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
>     cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
>     cfe/trunk/lib/CodeGen/CodeGenPGO.h
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=200874&r1=200873&r2=200874&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Feb  5 14:40:15 2014
> @@ -591,6 +591,16 @@ void CodeGenFunction::StartFunction(Glob
>      EmitMCountInstrumentation();
>
>    PGO.assignRegionCounters(GD);
> +  if (CGM.getPGOData()) {
> +    if (const Decl *D = GD.getDecl()) {
>

-Werror, unused variable 'D'.


> +      // Turn on InlineHint attribute for hot functions.
> +      if (CGM.getPGOData()->isHotFunction(CGM.getMangledName(GD)))
>

Do you want to pass "D" here instead, or remove the "const Decl *D =" part
from the if-statement above?

Nick


> +        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.
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=200874&r1=200873&r2=200874&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Wed Feb  5 14:40:15 2014
> @@ -45,6 +45,7 @@ PGOProfileData::PGOProfileData(CodeGenMo
>    const char *BufferStart = DataBuffer->getBufferStart();
>    const char *BufferEnd = DataBuffer->getBufferEnd();
>    const char *CurPtr = BufferStart;
> +  uint64_t MaxCount = 0;
>    while (CurPtr < BufferEnd) {
>      // Read the mangled function name.
>      const char *FuncName = CurPtr;
> @@ -65,8 +66,19 @@ PGOProfileData::PGOProfileData(CodeGenMo
>      }
>      CurPtr = EndPtr;
>
> +    // Read function count.
> +    uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
> +    if (EndPtr == CurPtr || *EndPtr != '\n') {
> +      ReportBadPGOData(CGM, "pgo-data file has bad count value");
> +      return;
> +    }
> +    CurPtr = EndPtr + 1;
> +    FunctionCounts[MangledName] = Count;
> +    MaxCount = Count > MaxCount ? Count : MaxCount;
> +
>      // There is one line for each counter; skip over those lines.
> -    for (unsigned N = 0; N < NumCounters; ++N) {
> +    // Since function count is already read, we start the loop from 1.
> +    for (unsigned N = 1; N < NumCounters; ++N) {
>        CurPtr = strchr(++CurPtr, '\n');
>        if (!CurPtr) {
>          ReportBadPGOData(CGM, "pgo data file is missing some counter
> info");
> @@ -79,6 +91,33 @@ PGOProfileData::PGOProfileData(CodeGenMo
>
>      DataOffsets[MangledName] = FuncName - BufferStart;
>    }
> +  MaxFunctionCount = MaxCount;
> +}
> +
> +/// Return true if a function is hot. If we know nothing about the
> function,
> +/// return false.
> +bool PGOProfileData::isHotFunction(StringRef MangledName) {
> +  llvm::StringMap<uint64_t>::const_iterator CountIter =
> +    FunctionCounts.find(MangledName);
> +  // If we know nothing about the function, return false.
> +  if (CountIter == FunctionCounts.end())
> +    return false;
> +  // FIXME: functions with >= 30% of the maximal function count are
> +  // treated as hot. This number is from preliminary tuning on SPEC.
> +  return CountIter->getValue() >= (uint64_t)(0.3 *
> (double)MaxFunctionCount);
> +}
> +
> +/// Return true if a function is cold. If we know nothing about the
> function,
> +/// return false.
> +bool PGOProfileData::isColdFunction(StringRef MangledName) {
> +  llvm::StringMap<uint64_t>::const_iterator CountIter =
> +    FunctionCounts.find(MangledName);
> +  // If we know nothing about the function, return false.
> +  if (CountIter == FunctionCounts.end())
> +    return false;
> +  // FIXME: functions with <= 1% of the maximal function count are
> treated as
> +  // cold. This number is from preliminary tuning on SPEC.
> +  return CountIter->getValue() <= (uint64_t)(0.01 *
> (double)MaxFunctionCount);
>  }
>
>  bool PGOProfileData::getFunctionCounts(StringRef MangledName,
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=200874&r1=200873&r2=200874&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenPGO.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenPGO.h Wed Feb  5 14:40:15 2014
> @@ -33,12 +33,22 @@ private:
>    llvm::OwningPtr<llvm::MemoryBuffer> DataBuffer;
>    /// Offsets into DataBuffer for each function's counters
>    llvm::StringMap<unsigned> DataOffsets;
> +  /// Execution counts for each function.
> +  llvm::StringMap<uint64_t> FunctionCounts;
> +  /// The maximal execution count among all functions.
> +  uint64_t MaxFunctionCount;
>    CodeGenModule &CGM;
>  public:
>    PGOProfileData(CodeGenModule &CGM, std::string Path);
>    /// Fill Counts with the profile data for the given function name.
> Returns
>    /// false on success.
>    bool getFunctionCounts(StringRef MangledName, std::vector<uint64_t>
> &Counts);
> +  /// Return true if a function is hot. If we know nothing about the
> function,
> +  /// return false.
> +  bool isHotFunction(StringRef MangledName);
> +  /// Return true if a function is cold. If we know nothing about the
> function,
> +  /// return false.
> +  bool isColdFunction(StringRef MangledName);
>  };
>
>  /// Per-function PGO state. This class should generally not be used
> directly,
>
> Added: cfe/trunk/test/CodeGen/Inputs/instr-attribute.pgodata
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/Inputs/instr-attribute.pgodata?rev=200874&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/CodeGen/Inputs/instr-attribute.pgodata (added)
> +++ cfe/trunk/test/CodeGen/Inputs/instr-attribute.pgodata Wed Feb  5
> 14:40:15 2014
> @@ -0,0 +1,39 @@
> +hot_100_percent 4
> +100000
> +4999950000
> +0
> +0
> +
> +hot_40_percent 4
> +40000
> +799980000
> +0
> +0
> +
> +normal_func 4
> +20000
> +199990000
> +0
> +0
> +
> +cold_func 4
> +500
> +124750
> +0
> +0
> +
> +main 13
> +1
> +100000
> +0
> +0
> +40000
> +0
> +0
> +20000
> +0
> +0
> +500
> +0
> +0
> +
>
> Added: cfe/trunk/test/CodeGen/instr-attribute.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/instr-attribute.c?rev=200874&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/CodeGen/instr-attribute.c (added)
> +++ cfe/trunk/test/CodeGen/instr-attribute.c Wed Feb  5 14:40:15 2014
> @@ -0,0 +1,47 @@
> +// Test that instrumentation based profiling sets function attributes
> correctly.
> +
> +// RUN: %clang %s -o - -mllvm -disable-llvm-optzns -emit-llvm -S
> -fprofile-instr-use=%S/Inputs/instr-attribute.pgodata | FileCheck %s
> +
> +extern int atoi(const char *);
> +
> +// CHECK: hot_100_percent(i32 %i) [[HOT:#[0-9]+]]
> +void hot_100_percent(int i) {
> +  while (i > 0)
> +    i--;
> +}
> +
> +// CHECK: hot_40_percent(i32 %i) [[HOT]]
> +void hot_40_percent(int i) {
> +  while (i > 0)
> +    i--;
> +}
> +
> +// CHECK: normal_func(i32 %i) [[NORMAL:#[0-9]+]]
> +void normal_func(int i) {
> +  while (i > 0)
> +    i--;
> +}
> +
> +// CHECK: cold_func(i32 %i) [[COLD:#[0-9]+]]
> +void cold_func(int i) {
> +  while (i > 0)
> +    i--;
> +}
> +
> +// CHECK: attributes [[HOT]] = { inlinehint nounwind {{.*}} }
> +// CHECK: attributes [[NORMAL]] = { nounwind {{.*}} }
> +// CHECK: attributes [[COLD]] = { cold nounwind {{.*}} }
> +
> +int main(int argc, const char *argv[]) {
> +  int max = atoi(argv[1]);
> +  int i;
> +  for (i = 0; i < max; i++)
> +    hot_100_percent(i);
> +  for (i = 0; i < max * 4 / 10; i++)
> +    hot_40_percent(i);
> +  for (i = 0; i < max * 2 / 10; i++)
> +    normal_func(i);
> +  for (i = 0; i < max / 200; i++)
> +    cold_func(i);
> +  return 0;
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140205/06919bea/attachment.html>


More information about the cfe-commits mailing list