diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-10-04 02:22:52 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-10-04 02:22:52 +0000 |
commit | 161935520d5a9cd1fcaddee39bb8438bcfec5552 (patch) | |
tree | 63b25b0718d66c622eb27efa8213105ef4e984fc /llvm/lib/CodeGen/FuncletLayout.cpp | |
parent | 65b9056f3dbba45ffd16d780b058a3d044115a59 (diff) | |
download | bcm5719-llvm-161935520d5a9cd1fcaddee39bb8438bcfec5552.tar.gz bcm5719-llvm-161935520d5a9cd1fcaddee39bb8438bcfec5552.zip |
[WinEH] Permit branch folding in the face of funclets
Track which basic blocks belong to which funclets. Permit branch
folding to fire but only if it can prove that doing so will not cause
code in one funclet to be reused in another.
llvm-svn: 249257
Diffstat (limited to 'llvm/lib/CodeGen/FuncletLayout.cpp')
-rw-r--r-- | llvm/lib/CodeGen/FuncletLayout.cpp | 75 |
1 files changed, 4 insertions, 71 deletions
diff --git a/llvm/lib/CodeGen/FuncletLayout.cpp b/llvm/lib/CodeGen/FuncletLayout.cpp index 4fdb66700b2..4307c1524ad 100644 --- a/llvm/lib/CodeGen/FuncletLayout.cpp +++ b/llvm/lib/CodeGen/FuncletLayout.cpp @@ -12,12 +12,9 @@ // //===----------------------------------------------------------------------===// #include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; #define DEBUG_TYPE "funclet-layout" @@ -34,81 +31,17 @@ public: }; } -static void -collectFuncletMembers(DenseMap<MachineBasicBlock *, int> &FuncletMembership, - int Funclet, MachineBasicBlock *MBB) { - // Don't revisit blocks. - if (FuncletMembership.count(MBB) > 0) { - if (FuncletMembership[MBB] != Funclet) { - assert(false && "MBB is part of two funclets!"); - report_fatal_error("MBB is part of two funclets!"); - } - return; - } - - // Add this MBB to our funclet. - FuncletMembership[MBB] = Funclet; - - bool IsReturn = false; - int NumTerminators = 0; - for (MachineInstr &MI : MBB->terminators()) { - IsReturn |= MI.isReturn(); - ++NumTerminators; - } - assert((!IsReturn || NumTerminators == 1) && - "Expected only one terminator when a return is present!"); - - // Returns are boundaries where funclet transfer can occur, don't follow - // successors. - if (IsReturn) - return; - - for (MachineBasicBlock *SMBB : MBB->successors()) - if (!SMBB->isEHPad()) - collectFuncletMembers(FuncletMembership, Funclet, SMBB); -} - char FuncletLayout::ID = 0; char &llvm::FuncletLayoutID = FuncletLayout::ID; INITIALIZE_PASS(FuncletLayout, "funclet-layout", "Contiguously Lay Out Funclets", false, false) bool FuncletLayout::runOnMachineFunction(MachineFunction &F) { - // We don't have anything to do if there aren't any EH pads. - if (!F.getMMI().hasEHFunclets()) + DenseMap<const MachineBasicBlock *, int> FuncletMembership = + getFuncletMembership(F); + if (FuncletMembership.empty()) return false; - const TargetInstrInfo *TII = F.getSubtarget().getInstrInfo(); - SmallVector<MachineBasicBlock *, 16> FuncletBlocks; - SmallVector<std::pair<MachineBasicBlock *, int>, 16> CatchRetSuccessors; - for (MachineBasicBlock &MBB : F) { - if (MBB.isEHFuncletEntry()) - FuncletBlocks.push_back(&MBB); - - MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); - if (MBBI->getOpcode() != TII->getCatchReturnOpcode()) - continue; - - MachineBasicBlock *Successor = MBBI->getOperand(0).getMBB(); - MachineBasicBlock *SuccessorColor = MBBI->getOperand(1).getMBB(); - CatchRetSuccessors.push_back({Successor, SuccessorColor->getNumber()}); - } - - // We don't have anything to do if there aren't any EH pads. - if (FuncletBlocks.empty()) - return false; - - DenseMap<MachineBasicBlock *, int> FuncletMembership; - // Identify all the basic blocks reachable from the function entry. - collectFuncletMembers(FuncletMembership, F.front().getNumber(), F.begin()); - // Next, identify all the blocks inside the funclets. - for (MachineBasicBlock *MBB : FuncletBlocks) - collectFuncletMembers(FuncletMembership, MBB->getNumber(), MBB); - // Finally, identify all the targets of a catchret. - for (std::pair<MachineBasicBlock *, int> CatchRetPair : CatchRetSuccessors) - collectFuncletMembers(FuncletMembership, CatchRetPair.second, - CatchRetPair.first); - F.sort([&](MachineBasicBlock &x, MachineBasicBlock &y) { return FuncletMembership[&x] < FuncletMembership[&y]; }); |