From fe7b9dc2d2f3e45cfd91a4311de446431fcea8d2 Mon Sep 17 00:00:00 2001 From: Easwaran Raman Date: Fri, 22 Dec 2017 01:33:52 +0000 Subject: [PATCH] Add hasProfileData() to check if a function has profile data. NFC. Summary: This replaces calls to getEntryCount().hasValue() with hasProfileData that does the same thing. This refactoring is useful to do before adding synthetic function entry counts but also a useful cleanup IMO even otherwise. I have used hasProfileData instead of hasRealProfileData as David had earlier suggested since I think profile implies "real" and I use the phrase "synthetic entry count" and not "synthetic profile count" but I am fine calling it hasRealProfileData if you prefer. Reviewers: davidxl, silvas Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D41461 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321331 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/Function.h | 6 ++++++ lib/Analysis/ModuleSummaryAnalysis.cpp | 2 +- lib/Analysis/ProfileSummaryInfo.cpp | 2 +- lib/Bitcode/Writer/BitcodeWriter.cpp | 2 +- lib/CodeGen/MachineBlockPlacement.cpp | 6 +++--- lib/Transforms/IPO/PartialInlining.cpp | 8 ++++---- lib/Transforms/Scalar/JumpThreading.cpp | 5 ++--- lib/Transforms/Scalar/LoopSink.cpp | 2 +- lib/Transforms/Scalar/LoopUnrollPass.cpp | 2 +- lib/Transforms/Utils/LoopUnrollPeel.cpp | 2 +- 10 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index e811ae5e215..79c56abe1c3 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -248,6 +248,12 @@ public: /// pgo data. Optional getEntryCount() const; + /// Return true if the function is annotated with profile data. + /// + /// Presence of entry counts from a profile run implies the function has + /// profile annotations. + bool hasProfileData() const { return getEntryCount().hasValue(); } + /// Returns the set of GUIDs that needs to be imported to the function for /// sample PGO, to enable the same inlines as the profiled optimized binary. DenseSet getImportGUIDs() const; diff --git a/lib/Analysis/ModuleSummaryAnalysis.cpp b/lib/Analysis/ModuleSummaryAnalysis.cpp index d54fb700200..10badd89a4a 100644 --- a/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -454,7 +454,7 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( std::unique_ptr BFIPtr; if (GetBFICallback) BFI = GetBFICallback(F); - else if (F.getEntryCount().hasValue()) { + else if (F.hasProfileData()) { LoopInfo LI{DominatorTree(const_cast(F))}; BranchProbabilityInfo BPI{F, LI}; BFIPtr = llvm::make_unique(F, BPI, LI); diff --git a/lib/Analysis/ProfileSummaryInfo.cpp b/lib/Analysis/ProfileSummaryInfo.cpp index 3bb4793c3ee..347d093b0f6 100644 --- a/lib/Analysis/ProfileSummaryInfo.cpp +++ b/lib/Analysis/ProfileSummaryInfo.cpp @@ -251,7 +251,7 @@ bool ProfileSummaryInfo::isColdCallSite(const CallSite &CS, // If there is no profile for the caller, and we know the profile is // accurate, we consider the callsite as cold. return (hasSampleProfile() && - (CS.getCaller()->getEntryCount() || ProfileSampleAccurate || + (CS.getCaller()->hasProfileData() || ProfileSampleAccurate || CS.getCaller()->hasFnAttribute("profile-sample-accurate"))); } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index fd13dbc1f1e..a7201ed9735 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3371,7 +3371,7 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord( for (auto &RI : FS->refs()) NameVals.push_back(VE.getValueID(RI.getValue())); - bool HasProfileData = F.getEntryCount().hasValue(); + bool HasProfileData = F.hasProfileData(); for (auto &ECI : FS->calls()) { NameVals.push_back(getValueId(ECI.first)); if (HasProfileData) diff --git a/lib/CodeGen/MachineBlockPlacement.cpp b/lib/CodeGen/MachineBlockPlacement.cpp index 4ce68960773..84c808ee793 100644 --- a/lib/CodeGen/MachineBlockPlacement.cpp +++ b/lib/CodeGen/MachineBlockPlacement.cpp @@ -1235,7 +1235,7 @@ void MachineBlockPlacement::precomputeTriangleChains() { // When profile is available, we need to handle the triangle-shape CFG. static BranchProbability getLayoutSuccessorProbThreshold( const MachineBasicBlock *BB) { - if (!BB->getParent()->getFunction().getEntryCount()) + if (!BB->getParent()->getFunction().hasProfileData()) return BranchProbability(StaticLikelyProb, 100); if (BB->succ_size() == 2) { const MachineBasicBlock *Succ1 = *BB->succ_begin(); @@ -2178,7 +2178,7 @@ MachineBlockPlacement::collectLoopBlockSet(const MachineLoop &L) { // will be merged into the first outer loop chain for which this block is not // cold anymore. This needs precise profile data and we only do this when // profile data is available. - if (F->getFunction().getEntryCount() || ForceLoopColdBlock) { + if (F->getFunction().hasProfileData() || ForceLoopColdBlock) { BlockFrequency LoopFreq(0); for (auto LoopPred : L.getHeader()->predecessors()) if (!L.contains(LoopPred)) @@ -2220,7 +2220,7 @@ void MachineBlockPlacement::buildLoopChains(const MachineLoop &L) { // for better layout. bool RotateLoopWithProfile = ForcePreciseRotationCost || - (PreciseRotationCost && F->getFunction().getEntryCount()); + (PreciseRotationCost && F->getFunction().hasProfileData()); // First check to see if there is an obviously preferable top block for the // loop. This will default to the header, but may end up as one of the diff --git a/lib/Transforms/IPO/PartialInlining.cpp b/lib/Transforms/IPO/PartialInlining.cpp index 5f5b7be3c20..a9cfd8ded6f 100644 --- a/lib/Transforms/IPO/PartialInlining.cpp +++ b/lib/Transforms/IPO/PartialInlining.cpp @@ -710,7 +710,7 @@ PartialInlinerImpl::computeOutliningInfo(Function *F) { // Check if there is PGO data or user annoated branch data: static bool hasProfileData(Function *F, FunctionOutliningInfo *OI) { - if (F->getEntryCount()) + if (F->hasProfileData()) return true; // Now check if any of the entry block has MD_prof data: for (auto *E : OI->Entries) { @@ -1274,7 +1274,7 @@ std::pair PartialInlinerImpl::unswitchFunction(Function *F) { // Only try to outline cold regions if we have a profile summary, which // implies we have profiling information. - if (PSI->hasProfileSummary() && F->getEntryCount().hasValue() && + if (PSI->hasProfileSummary() && F->hasProfileData() && !DisableMultiRegionPartialInline) { std::unique_ptr OMRI = computeOutliningColdRegionsInfo(F); @@ -1380,10 +1380,10 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) { Cloner.ClonedFunc->user_end()); DenseMap CallSiteToProfCountMap; - if (Cloner.OrigFunc->getEntryCount()) + auto CalleeEntryCount = Cloner.OrigFunc->getEntryCount(); + if (CalleeEntryCount) computeCallsiteToProfCountMap(Cloner.ClonedFunc, CallSiteToProfCountMap); - auto CalleeEntryCount = Cloner.OrigFunc->getEntryCount(); uint64_t CalleeEntryCountV = (CalleeEntryCount ? *CalleeEntryCount : 0); bool AnyInline = false; diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 4795db0b155..1476f7850cf 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -282,7 +282,7 @@ bool JumpThreading::runOnFunction(Function &F) { auto AA = &getAnalysis().getAAResults(); std::unique_ptr BFI; std::unique_ptr BPI; - bool HasProfileData = F.getEntryCount().hasValue(); + bool HasProfileData = F.hasProfileData(); if (HasProfileData) { LoopInfo LI{DominatorTree(F)}; BPI.reset(new BranchProbabilityInfo(F, LI, TLI)); @@ -307,8 +307,7 @@ PreservedAnalyses JumpThreadingPass::run(Function &F, std::unique_ptr BFI; std::unique_ptr BPI; - bool HasProfileData = F.getEntryCount().hasValue(); - if (HasProfileData) { + if (F.hasProfileData()) { LoopInfo LI{DominatorTree(F)}; BPI.reset(new BranchProbabilityInfo(F, LI, &TLI)); BFI.reset(new BlockFrequencyInfo(F, *BPI, LI)); diff --git a/lib/Transforms/Scalar/LoopSink.cpp b/lib/Transforms/Scalar/LoopSink.cpp index c9d55b4594f..430a7085d93 100644 --- a/lib/Transforms/Scalar/LoopSink.cpp +++ b/lib/Transforms/Scalar/LoopSink.cpp @@ -247,7 +247,7 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI, // Enable LoopSink only when runtime profile is available. // With static profile, the sinking decision may be sub-optimal. - if (!Preheader->getParent()->getEntryCount()) + if (!Preheader->getParent()->hasProfileData()) return false; const BlockFrequency PreheaderFreq = BFI.getBlockFreq(Preheader); diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp index 7b1d6446a24..15e7da5e1a7 100644 --- a/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -882,7 +882,7 @@ static bool computeUnrollCount( } // Check if the runtime trip count is too small when profile is available. - if (L->getHeader()->getParent()->getEntryCount()) { + if (L->getHeader()->getParent()->hasProfileData()) { if (auto ProfileTripCount = getLoopEstimatedTripCount(L)) { if (*ProfileTripCount < FlatLoopTripCountThreshold) return false; diff --git a/lib/Transforms/Utils/LoopUnrollPeel.cpp b/lib/Transforms/Utils/LoopUnrollPeel.cpp index 4273ce0b620..c84ae7d693d 100644 --- a/lib/Transforms/Utils/LoopUnrollPeel.cpp +++ b/lib/Transforms/Utils/LoopUnrollPeel.cpp @@ -203,7 +203,7 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize, // hit the peeled section. // We only do this in the presence of profile information, since otherwise // our estimates of the trip count are not reliable enough. - if (UP.AllowPeeling && L->getHeader()->getParent()->getEntryCount()) { + if (UP.AllowPeeling && L->getHeader()->getParent()->hasProfileData()) { Optional PeelCount = getLoopEstimatedTripCount(L); if (!PeelCount) return; -- 2.49.0