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