Index: include/llvm/ProfileData/ProfileCommon.h =================================================================== --- include/llvm/ProfileData/ProfileCommon.h +++ include/llvm/ProfileData/ProfileCommon.h @@ -21,6 +21,8 @@ #define LLVM_PROFILEDATA_PROFILE_COMMON_H namespace llvm { +class Function; +class Module; namespace IndexedInstrProf { struct Summary; } @@ -28,6 +30,8 @@ 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 +70,12 @@ public: static const int Scale = 1000000; + // \brief Returns true if profile is available. + static bool hasProfile(const Module *M); + // \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 &getDetailedSummary(); void computeDetailedSummary(); /// \brief A vector of useful cutoff values for detailed summary. Index: lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ 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 @@ return ".data.rel.ro"; } +static cl::opt 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, @@ -294,6 +300,16 @@ Name = getSectionPrefixForGlobal(Kind); } + if (GroupFunctionsByHotness) { + if (const Function *F = dyn_cast(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); Index: lib/ProfileData/ProfileSummary.cpp =================================================================== --- lib/ProfileData/ProfileSummary.cpp +++ lib/ProfileData/ProfileSummary.cpp @@ -11,6 +11,9 @@ // //===----------------------------------------------------------------------===// +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/ProfileData/ProfileCommon.h" #include "llvm/ProfileData/SampleProf.h" @@ -75,6 +78,31 @@ } } +bool ProfileSummary::hasProfile(const Module *M) { + // FIXME: update when summary data is stored in module's metadata. + return false; +} + +// 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; +} + +bool ProfileSummary::isFunctionUnlikely(const Function *F) { + if (F->hasFnAttribute(Attribute::Cold)) { + return true; + } + if (!hasProfile(F->getParent())) { + return false; + } + if (!F->getEntryCount()) { + return true; + } + // 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)),