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