r200874 - PGO: instrumentation based profiling sets function attributes.

Manman Ren manman.ren at gmail.com
Wed Feb 5 16:17:12 PST 2014


Thanks Nick. Fixed in r200891 and r200893.

Manman


On Wed, Feb 5, 2014 at 3:40 PM, Nick Lewycky <nlewycky at google.com> wrote:

> 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/f777b72f/attachment.html>


More information about the cfe-commits mailing list