//
//===----------------------------------------------------------------------===//
#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"
using namespace llvm;
#define DEBUG_TYPE "funclet-layout"
};
}
-static void
-collectFuncletMembers(DenseMap<MachineBasicBlock *, int> &FuncletMembership,
- int Funclet, MachineBasicBlock *MBB) {
- // Don't revisit blocks.
- if (FuncletMembership.count(MBB) > 0)
- 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;
- SmallVector<MachineBasicBlock *, 16> FuncletBlocks;
- for (MachineBasicBlock &MBB : F)
- if (MBB.isEHFuncletEntry())
- FuncletBlocks.push_back(&MBB);
-
- // We don't have anything to do if there aren't any EH pads.
- if (FuncletBlocks.empty())
- return false;
-
- DenseMap<MachineBasicBlock *, int> FuncletMembership;
- for (MachineBasicBlock *MBB : FuncletBlocks)
- collectFuncletMembers(FuncletMembership, MBB->getNumber(), MBB);
-
- F.sort([&](MachineBasicBlock &x, MachineBasicBlock &y) {
- return FuncletMembership[&x] < FuncletMembership[&y];
+ F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
+ auto FuncletX = FuncletMembership.find(&X);
+ auto FuncletY = FuncletMembership.find(&Y);
+ assert(FuncletX != FuncletMembership.end());
+ assert(FuncletY != FuncletMembership.end());
+ return FuncletX->second < FuncletY->second;
});
// Conservatively assume we changed something.