197890230SDavid Majnemer //===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===// 297890230SDavid Majnemer // 397890230SDavid Majnemer // The LLVM Compiler Infrastructure 497890230SDavid Majnemer // 597890230SDavid Majnemer // This file is distributed under the University of Illinois Open Source 697890230SDavid Majnemer // License. See LICENSE.TXT for details. 797890230SDavid Majnemer // 897890230SDavid Majnemer //===----------------------------------------------------------------------===// 997890230SDavid Majnemer // 1097890230SDavid Majnemer // This file implements basic block placement transformations which result in 1197890230SDavid Majnemer // funclets being contiguous. 1297890230SDavid Majnemer // 1397890230SDavid Majnemer //===----------------------------------------------------------------------===// 1497890230SDavid Majnemer #include "llvm/CodeGen/Passes.h" 1597890230SDavid Majnemer #include "llvm/CodeGen/MachineBasicBlock.h" 1697890230SDavid Majnemer #include "llvm/CodeGen/MachineFunction.h" 1797890230SDavid Majnemer #include "llvm/CodeGen/MachineFunctionPass.h" 1897890230SDavid Majnemer #include "llvm/CodeGen/MachineModuleInfo.h" 1997890230SDavid Majnemer using namespace llvm; 2097890230SDavid Majnemer 2197890230SDavid Majnemer #define DEBUG_TYPE "funclet-layout" 2297890230SDavid Majnemer 2397890230SDavid Majnemer namespace { 2497890230SDavid Majnemer class FuncletLayout : public MachineFunctionPass { 2597890230SDavid Majnemer public: 2697890230SDavid Majnemer static char ID; // Pass identification, replacement for typeid 2797890230SDavid Majnemer FuncletLayout() : MachineFunctionPass(ID) { 2897890230SDavid Majnemer initializeFuncletLayoutPass(*PassRegistry::getPassRegistry()); 2997890230SDavid Majnemer } 3097890230SDavid Majnemer 3197890230SDavid Majnemer bool runOnMachineFunction(MachineFunction &F) override; 3297890230SDavid Majnemer }; 3397890230SDavid Majnemer } 3497890230SDavid Majnemer 3597890230SDavid Majnemer static void 36*9966fe8fSDavid Majnemer collectFuncletMembers(DenseMap<MachineBasicBlock *, int> &FuncletMembership, 3797890230SDavid Majnemer int Funclet, MachineBasicBlock *MBB) { 3897890230SDavid Majnemer // Don't revisit blocks. 3997890230SDavid Majnemer if (FuncletMembership.count(MBB) > 0) 4097890230SDavid Majnemer return; 4197890230SDavid Majnemer 4297890230SDavid Majnemer // Add this MBB to our funclet. 4397890230SDavid Majnemer FuncletMembership[MBB] = Funclet; 4497890230SDavid Majnemer 4597890230SDavid Majnemer bool IsReturn = false; 4697890230SDavid Majnemer int NumTerminators = 0; 4797890230SDavid Majnemer for (MachineInstr &MI : MBB->terminators()) { 4897890230SDavid Majnemer IsReturn |= MI.isReturn(); 4997890230SDavid Majnemer ++NumTerminators; 5097890230SDavid Majnemer } 5197890230SDavid Majnemer assert((!IsReturn || NumTerminators == 1) && 5297890230SDavid Majnemer "Expected only one terminator when a return is present!"); 5397890230SDavid Majnemer 5497890230SDavid Majnemer // Returns are boundaries where funclet transfer can occur, don't follow 5597890230SDavid Majnemer // successors. 5697890230SDavid Majnemer if (IsReturn) 5797890230SDavid Majnemer return; 5897890230SDavid Majnemer 5997890230SDavid Majnemer for (MachineBasicBlock *SMBB : MBB->successors()) 6097890230SDavid Majnemer if (!SMBB->isEHPad()) 6197890230SDavid Majnemer collectFuncletMembers(FuncletMembership, Funclet, SMBB); 6297890230SDavid Majnemer } 6397890230SDavid Majnemer 6497890230SDavid Majnemer char FuncletLayout::ID = 0; 6597890230SDavid Majnemer char &llvm::FuncletLayoutID = FuncletLayout::ID; 6697890230SDavid Majnemer INITIALIZE_PASS(FuncletLayout, "funclet-layout", 6797890230SDavid Majnemer "Contiguously Lay Out Funclets", false, false) 6897890230SDavid Majnemer 6997890230SDavid Majnemer bool FuncletLayout::runOnMachineFunction(MachineFunction &F) { 7097890230SDavid Majnemer // We don't have anything to do if there aren't any EH pads. 7197890230SDavid Majnemer if (!F.getMMI().hasEHFunclets()) 7297890230SDavid Majnemer return false; 7397890230SDavid Majnemer 7497890230SDavid Majnemer SmallVector<MachineBasicBlock *, 16> FuncletBlocks; 7597890230SDavid Majnemer for (MachineBasicBlock &MBB : F) 7697890230SDavid Majnemer if (MBB.isEHFuncletEntry()) 7797890230SDavid Majnemer FuncletBlocks.push_back(&MBB); 7897890230SDavid Majnemer 7997890230SDavid Majnemer // We don't have anything to do if there aren't any EH pads. 8097890230SDavid Majnemer if (FuncletBlocks.empty()) 8197890230SDavid Majnemer return false; 8297890230SDavid Majnemer 83*9966fe8fSDavid Majnemer DenseMap<MachineBasicBlock *, int> FuncletMembership; 8497890230SDavid Majnemer for (MachineBasicBlock *MBB : FuncletBlocks) 8597890230SDavid Majnemer collectFuncletMembers(FuncletMembership, MBB->getNumber(), MBB); 8697890230SDavid Majnemer 87*9966fe8fSDavid Majnemer F.sort([&](MachineBasicBlock &x, MachineBasicBlock &y) { 88*9966fe8fSDavid Majnemer return FuncletMembership[&x] < FuncletMembership[&y]; 89*9966fe8fSDavid Majnemer }); 9097890230SDavid Majnemer 9197890230SDavid Majnemer // Conservatively assume we changed something. 9297890230SDavid Majnemer return true; 9397890230SDavid Majnemer } 94