diff options
author | Cong Hou <congh@google.com> | 2015-10-12 23:02:58 +0000 |
---|---|---|
committer | Cong Hou <congh@google.com> | 2015-10-12 23:02:58 +0000 |
commit | bf22f5063a92555508413a46df68f129c7d037f4 (patch) | |
tree | 60accd0153108b1e5a90a8ae29c14d59ec4a83a3 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | |
parent | c8832fc23363321dea5c289007390c84c483f9cf (diff) | |
download | bcm5719-llvm-bf22f5063a92555508413a46df68f129c7d037f4.tar.gz bcm5719-llvm-bf22f5063a92555508413a46df68f129c7d037f4.zip |
Assign correct edge weights to unwind destinations when lowering invoke statement.
When lowering invoke statement, all unwind destinations are directly added as successors of call site block, and the weight of those new edges are not assigned properly. Actually, default weight 16 are used for those edges. This patch calculates the proper edge weights for those edges when collecting all unwind destinations.
Differential revision: http://reviews.llvm.org/D13354
llvm-svn: 250119
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 70a6f918657..3d483464f65 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -64,6 +64,7 @@ #include "llvm/Target/TargetSelectionDAGInfo.h" #include "llvm/Target/TargetSubtargetInfo.h" #include <algorithm> +#include <utility> using namespace llvm; #define DEBUG_TYPE "isel" @@ -1243,50 +1244,66 @@ void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) { /// destination, but in the machine CFG, we enumerate all the possible blocks. /// This function skips over imaginary basic blocks that hold catchpad, /// terminatepad, or catchendpad instructions, and finds all the "real" machine -/// basic block destinations. -static void -findUnwindDestinations(FunctionLoweringInfo &FuncInfo, - const BasicBlock *EHPadBB, - SmallVectorImpl<MachineBasicBlock *> &UnwindDests) { +/// basic block destinations. As those destinations may not be successors of +/// EHPadBB, here we also calculate the edge weight to those destinations. The +/// passed-in Weight is the edge weight to EHPadBB. +static void findUnwindDestinations( + FunctionLoweringInfo &FuncInfo, const BasicBlock *EHPadBB, uint32_t Weight, + SmallVectorImpl<std::pair<MachineBasicBlock *, uint32_t>> &UnwindDests) { EHPersonality Personality = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()); bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX; bool IsCoreCLR = Personality == EHPersonality::CoreCLR; + while (EHPadBB) { const Instruction *Pad = EHPadBB->getFirstNonPHI(); + BasicBlock *NewEHPadBB = nullptr; if (isa<LandingPadInst>(Pad)) { // Stop on landingpads. They are not funclets. - UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); + UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight); break; } else if (isa<CleanupPadInst>(Pad)) { // Stop on cleanup pads. Cleanups are always funclet entries for all known // personalities. - UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); - UnwindDests.back()->setIsEHFuncletEntry(); + UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight); + UnwindDests.back().first->setIsEHFuncletEntry(); break; } else if (const auto *CPI = dyn_cast<CatchPadInst>(Pad)) { // Add the catchpad handler to the possible destinations. - UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); + UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight); // In MSVC C++, catchblocks are funclets and need prologues. if (IsMSVCCXX || IsCoreCLR) - UnwindDests.back()->setIsEHFuncletEntry(); - EHPadBB = CPI->getUnwindDest(); - } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(Pad)) { - EHPadBB = CEPI->getUnwindDest(); - } else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(Pad)) { - EHPadBB = CEPI->getUnwindDest(); + UnwindDests.back().first->setIsEHFuncletEntry(); + NewEHPadBB = CPI->getUnwindDest(); + } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(Pad)) + NewEHPadBB = CEPI->getUnwindDest(); + else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(Pad)) + NewEHPadBB = CEPI->getUnwindDest(); + else + continue; + + BranchProbabilityInfo *BPI = FuncInfo.BPI; + if (BPI && NewEHPadBB) { + // When BPI is available, the calculated weight cannot be zero as zero + // will be turned to a default weight in MachineBlockFrequencyInfo. + Weight = std::max<uint32_t>( + BPI->getEdgeProbability(EHPadBB, NewEHPadBB).scale(Weight), 1); } + EHPadBB = NewEHPadBB; } } void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) { // Update successor info. - // FIXME: The weights for catchpads will be wrong. - SmallVector<MachineBasicBlock *, 1> UnwindDests; - findUnwindDestinations(FuncInfo, I.getUnwindDest(), UnwindDests); - for (MachineBasicBlock *UnwindDest : UnwindDests) { - UnwindDest->setIsEHPad(); - addSuccessorWithWeight(FuncInfo.MBB, UnwindDest); + SmallVector<std::pair<MachineBasicBlock *, uint32_t>, 1> UnwindDests; + auto UnwindDest = I.getUnwindDest(); + BranchProbabilityInfo *BPI = FuncInfo.BPI; + uint32_t UnwindDestWeight = + BPI ? BPI->getEdgeWeight(FuncInfo.MBB->getBasicBlock(), UnwindDest) : 0; + findUnwindDestinations(FuncInfo, UnwindDest, UnwindDestWeight, UnwindDests); + for (auto &UnwindDest : UnwindDests) { + UnwindDest.first->setIsEHPad(); + addSuccessorWithWeight(FuncInfo.MBB, UnwindDest.first, UnwindDest.second); } // Create the terminator node. @@ -2128,15 +2145,17 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { CopyToExportRegsIfNeeded(&I); } - SmallVector<MachineBasicBlock *, 1> UnwindDests; - findUnwindDestinations(FuncInfo, EHPadBB, UnwindDests); + SmallVector<std::pair<MachineBasicBlock *, uint32_t>, 1> UnwindDests; + BranchProbabilityInfo *BPI = FuncInfo.BPI; + uint32_t EHPadBBWeight = + BPI ? BPI->getEdgeWeight(InvokeMBB->getBasicBlock(), EHPadBB) : 0; + findUnwindDestinations(FuncInfo, EHPadBB, EHPadBBWeight, UnwindDests); // Update successor info. - // FIXME: The weights for catchpads will be wrong. addSuccessorWithWeight(InvokeMBB, Return); - for (MachineBasicBlock *UnwindDest : UnwindDests) { - UnwindDest->setIsEHPad(); - addSuccessorWithWeight(InvokeMBB, UnwindDest); + for (auto &UnwindDest : UnwindDests) { + UnwindDest.first->setIsEHPad(); + addSuccessorWithWeight(InvokeMBB, UnwindDest.first, UnwindDest.second); } // Drop into normal successor. |