diff options
author | Dehao Chen <dehao@google.com> | 2017-03-20 16:40:44 +0000 |
---|---|---|
committer | Dehao Chen <dehao@google.com> | 2017-03-20 16:40:44 +0000 |
commit | e593049fb057a014e912973e8717463e060c9d60 (patch) | |
tree | 94b2bd2385a92f6fb01f2cda8cb26b8cc2f610e1 /llvm/lib/Transforms/Utils/InlineFunction.cpp | |
parent | 6c2949da393fc3414fa9dca47a8079cc6a8a01a3 (diff) | |
download | bcm5719-llvm-e593049fb057a014e912973e8717463e060c9d60.tar.gz bcm5719-llvm-e593049fb057a014e912973e8717463e060c9d60.zip |
Updates branch_weights annotation for call instructions during inlining.
Summary: Inliner should update the branch_weights annotation to scale it to proper value.
Reviewers: davidxl, eraman
Reviewed By: eraman
Subscribers: zzheng, llvm-commits
Differential Revision: https://reviews.llvm.org/D30767
llvm-svn: 298270
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index a90ef3e5054..0f08d7f66fd 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -25,6 +25,7 @@ #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/CallSite.h" @@ -1425,28 +1426,55 @@ static void updateCallerBFI(BasicBlock *CallSiteBlock, ClonedBBs); } +/// Update the branch metadata for cloned call instructions. +static void updateCallProfile(Function *Callee, const ValueToValueMapTy &VMap, + const Optional<uint64_t> &CalleeEntryCount, + const Instruction *TheCall) { + if (!CalleeEntryCount.hasValue() || CalleeEntryCount.getValue() < 1) + return; + Optional<uint64_t> CallSiteCount = + ProfileSummaryInfo::getProfileCount(TheCall, nullptr); + uint64_t CallCount = + std::min(CallSiteCount.hasValue() ? CallSiteCount.getValue() : 0, + CalleeEntryCount.getValue()); + + for (auto const &Entry : VMap) + if (isa<CallInst>(Entry.first) && &*Entry.second != nullptr && + isa<CallInst>(Entry.second)) + cast<CallInst>(Entry.second) + ->updateProfWeight(CallCount, CalleeEntryCount.getValue()); + for (BasicBlock &BB : *Callee) + // No need to update the callsite if it is pruned during inlining. + if (VMap.count(&BB)) + for (Instruction &I : BB) + if (CallInst *CI = dyn_cast<CallInst>(&I)) + CI->updateProfWeight(CalleeEntryCount.getValue() - CallCount, + CalleeEntryCount.getValue()); +} + /// Update the entry count of callee after inlining. /// /// The callsite's block count is subtracted from the callee's function entry /// count. -static void updateCalleeCount(BlockFrequencyInfo &CallerBFI, BasicBlock *CallBB, - Function *Callee) { +static void updateCalleeCount(BlockFrequencyInfo *CallerBFI, BasicBlock *CallBB, + Instruction *CallInst, Function *Callee) { // If the callee has a original count of N, and the estimated count of // callsite is M, the new callee count is set to N - M. M is estimated from // the caller's entry count, its entry block frequency and the block frequency // of the callsite. Optional<uint64_t> CalleeCount = Callee->getEntryCount(); - if (!CalleeCount) + if (!CalleeCount.hasValue()) return; - Optional<uint64_t> CallSiteCount = CallerBFI.getBlockProfileCount(CallBB); - if (!CallSiteCount) + Optional<uint64_t> CallCount = + ProfileSummaryInfo::getProfileCount(CallInst, CallerBFI); + if (!CallCount.hasValue()) return; // Since CallSiteCount is an estimate, it could exceed the original callee // count and has to be set to 0. - if (CallSiteCount.getValue() > CalleeCount.getValue()) + if (CallCount.getValue() > CalleeCount.getValue()) Callee->setEntryCount(0); else - Callee->setEntryCount(CalleeCount.getValue() - CallSiteCount.getValue()); + Callee->setEntryCount(CalleeCount.getValue() - CallCount.getValue()); } /// This function inlines the called function into the basic block of the @@ -1636,13 +1664,14 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // Remember the first block that is newly cloned over. FirstNewBlock = LastBlock; ++FirstNewBlock; - if (IFI.CallerBFI != nullptr && IFI.CalleeBFI != nullptr) { + if (IFI.CallerBFI != nullptr && IFI.CalleeBFI != nullptr) // Update the BFI of blocks cloned into the caller. updateCallerBFI(OrigBB, VMap, IFI.CallerBFI, IFI.CalleeBFI, CalledFunc->front()); - // Update the profile count of callee. - updateCalleeCount(*IFI.CallerBFI, OrigBB, CalledFunc); - } + + updateCallProfile(CalledFunc, VMap, CalledFunc->getEntryCount(), TheCall); + // Update the profile count of callee. + updateCalleeCount(IFI.CallerBFI, OrigBB, TheCall, CalledFunc); // Inject byval arguments initialization. for (std::pair<Value*, Value*> &Init : ByValInit) |