diff options
author | Dehao Chen <dehao@google.com> | 2016-02-23 03:39:24 +0000 |
---|---|---|
committer | Dehao Chen <dehao@google.com> | 2016-02-23 03:39:24 +0000 |
commit | f84b6300445e726f318ecafd8fec4048a7af1d6e (patch) | |
tree | e845b45480f5a34a21b60416beacdbe3cb7d43c3 | |
parent | c00718fd8e19eb078a9d263c1e59587fbfd6b00a (diff) | |
download | bcm5719-llvm-f84b6300445e726f318ecafd8fec4048a7af1d6e.tar.gz bcm5719-llvm-f84b6300445e726f318ecafd8fec4048a7af1d6e.zip |
Add prefix based function layout when profile is available.
Summary: If a function is hot, put it in text.hot section.
Reviewers: davidxl
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D17532
llvm-svn: 261607
-rw-r--r-- | llvm/include/llvm/ProfileData/ProfileCommon.h | 7 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/ProfileData/ProfileSummary.cpp | 20 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/partition-sections.ll | 31 |
4 files changed, 74 insertions, 0 deletions
diff --git a/llvm/include/llvm/ProfileData/ProfileCommon.h b/llvm/include/llvm/ProfileData/ProfileCommon.h index e7d69431542..c0774d4b818 100644 --- a/llvm/include/llvm/ProfileData/ProfileCommon.h +++ b/llvm/include/llvm/ProfileData/ProfileCommon.h @@ -21,6 +21,7 @@ #define LLVM_PROFILEDATA_PROFILE_COMMON_H namespace llvm { +class Function; namespace IndexedInstrProf { struct Summary; } @@ -28,6 +29,8 @@ namespace sampleprof { class FunctionSamples; } struct InstrProfRecord; +inline const char *getHotSectionPrefix() { return ".hot"; } +inline const char *getUnlikelySectionPrefix() { return ".unlikely"; } // The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets. // The semantics of counts depend on the type of profile. For instrumentation // profile, counts are block counts and for sample profile, counts are @@ -66,6 +69,10 @@ protected: public: static const int Scale = 1000000; + // \brief Returns true if F is a hot function. + static bool isFunctionHot(const Function *F); + // \brief Returns true if F is unlikley executed. + static bool isFunctionUnlikely(const Function *F); inline std::vector<ProfileSummaryEntry> &getDetailedSummary(); void computeDetailedSummary(); /// \brief A vector of useful cutoff values for detailed summary. diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 6756e9df384..4229741cf5a 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -34,6 +34,7 @@ #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCValue.h" #include "llvm/ProfileData/InstrProf.h" +#include "llvm/ProfileData/ProfileCommon.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ELF.h" @@ -244,6 +245,11 @@ static StringRef getSectionPrefixForGlobal(SectionKind Kind) { return ".data.rel.ro"; } +static cl::opt<bool> GroupFunctionsByHotness( + "group-functions-by-hotness", + llvm::cl::desc("Partition hot/cold functions by sections prefix"), + cl::init(false)); + static MCSectionELF * selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV, SectionKind Kind, Mangler &Mang, @@ -296,6 +302,16 @@ selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV, Name = getSectionPrefixForGlobal(Kind); } + if (GroupFunctionsByHotness) { + if (const Function *F = dyn_cast<Function>(GV)) { + if (ProfileSummary::isFunctionHot(F)) { + Name += getHotSectionPrefix(); + } else if (ProfileSummary::isFunctionUnlikely(F)) { + Name += getUnlikelySectionPrefix(); + } + } + } + if (EmitUniqueSection && UniqueSectionNames) { Name.push_back('.'); TM.getNameWithPrefix(Name, GV, Mang, true); diff --git a/llvm/lib/ProfileData/ProfileSummary.cpp b/llvm/lib/ProfileData/ProfileSummary.cpp index 0e2c43e5e91..a98af2c462c 100644 --- a/llvm/lib/ProfileData/ProfileSummary.cpp +++ b/llvm/lib/ProfileData/ProfileSummary.cpp @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Function.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/ProfileData/ProfileCommon.h" #include "llvm/ProfileData/SampleProf.h" @@ -75,6 +77,24 @@ void ProfileSummary::computeDetailedSummary() { } } +// Returns true if the function is a hot function. +bool ProfileSummary::isFunctionHot(const Function *F) { + // FIXME: update when summary data is stored in module's metadata. + return false; +} + +// Returns true if the function is a cold function. +bool ProfileSummary::isFunctionUnlikely(const Function *F) { + if (F->hasFnAttribute(Attribute::Cold)) { + return true; + } + if (!F->getEntryCount()) { + return false; + } + // FIXME: update when summary data is stored in module's metadata. + return (*F->getEntryCount()) == 0; +} + InstrProfSummary::InstrProfSummary(const IndexedInstrProf::Summary &S) : ProfileSummary(), MaxInternalBlockCount(S.get( IndexedInstrProf::Summary::MaxInternalBlockCount)), diff --git a/llvm/test/CodeGen/X86/partition-sections.ll b/llvm/test/CodeGen/X86/partition-sections.ll new file mode 100644 index 00000000000..bc7d4b1a7cf --- /dev/null +++ b/llvm/test/CodeGen/X86/partition-sections.ll @@ -0,0 +1,31 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux -group-functions-by-hotness=true | FileCheck %s -check-prefix=PARTITION +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -group-functions-by-hotness=false | FileCheck %s -check-prefix=NO-PARTITION-FUNCTION-SECTION +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -group-functions-by-hotness=true | FileCheck %s -check-prefix=PARTITION-FUNCTION-SECTION + +; PARTITION: .text.unlikely +; PARTITION: .globl _Z3foov +; NO-PARTITION-FUNCTION-SECTION: .text._Z3foov +; PARTITION-FUNCTION-SECTION: .text.unlikely._Z3foov +define i32 @_Z3foov() #0 { + ret i32 0 +} + +; PARTITION: .globl _Z3barv +; NO-PARTITION-FUNCTION-SECTION: .text._Z3barv +; PARTITION-FUNCTION-SECTION: .text.unlikely._Z3barv +define i32 @_Z3barv() #1 !prof !0 { + ret i32 1 +} + +; PARTITION: .text +; PARTITION: .globl _Z3bazv +; NO-PARTITION-FUNCTION-SECTION: .text._Z3bazv +; PARTITION-FUNCTION-SECTION: .text._Z3bazv +define i32 @_Z3bazv() #1 { + ret i32 2 +} + +attributes #0 = { nounwind uwtable cold } +attributes #1 = { nounwind uwtable } + +!0 = !{!"function_entry_count", i64 0} |