197890230SDavid Majnemer //===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===// 297890230SDavid Majnemer // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 697890230SDavid Majnemer // 797890230SDavid Majnemer //===----------------------------------------------------------------------===// 897890230SDavid Majnemer // 997890230SDavid Majnemer // This file implements basic block placement transformations which result in 1097890230SDavid Majnemer // funclets being contiguous. 1197890230SDavid Majnemer // 1297890230SDavid Majnemer //===----------------------------------------------------------------------===// 1316193552SDavid Majnemer #include "llvm/CodeGen/Analysis.h" 1497890230SDavid Majnemer #include "llvm/CodeGen/MachineFunction.h" 1597890230SDavid Majnemer #include "llvm/CodeGen/MachineFunctionPass.h" 166bda14b3SChandler Carruth #include "llvm/CodeGen/Passes.h" 1797890230SDavid Majnemer using namespace llvm; 1897890230SDavid Majnemer 1997890230SDavid Majnemer #define DEBUG_TYPE "funclet-layout" 2097890230SDavid Majnemer 2197890230SDavid Majnemer namespace { 2297890230SDavid Majnemer class FuncletLayout : public MachineFunctionPass { 2397890230SDavid Majnemer public: 2497890230SDavid Majnemer static char ID; // Pass identification, replacement for typeid 2597890230SDavid Majnemer FuncletLayout() : MachineFunctionPass(ID) { 2697890230SDavid Majnemer initializeFuncletLayoutPass(*PassRegistry::getPassRegistry()); 2797890230SDavid Majnemer } 2897890230SDavid Majnemer 2997890230SDavid Majnemer bool runOnMachineFunction(MachineFunction &F) override; 30ad154c83SDerek Schuff MachineFunctionProperties getRequiredProperties() const override { 31ad154c83SDerek Schuff return MachineFunctionProperties().set( 321eb47368SMatthias Braun MachineFunctionProperties::Property::NoVRegs); 33ad154c83SDerek Schuff } 3497890230SDavid Majnemer }; 3597890230SDavid Majnemer } 3697890230SDavid Majnemer 3797890230SDavid Majnemer char FuncletLayout::ID = 0; 3897890230SDavid Majnemer char &llvm::FuncletLayoutID = FuncletLayout::ID; 391527baabSMatthias Braun INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE, 4097890230SDavid Majnemer "Contiguously Lay Out Funclets", false, false) 4197890230SDavid Majnemer 4297890230SDavid Majnemer bool FuncletLayout::runOnMachineFunction(MachineFunction &F) { 43d69acf3bSHeejin Ahn // Even though this gets information from getEHScopeMembership(), this pass is 44d69acf3bSHeejin Ahn // only necessary for funclet-based EH personalities, in which these EH scopes 45d69acf3bSHeejin Ahn // are outlined at the end. 4616193552SDavid Majnemer DenseMap<const MachineBasicBlock *, int> FuncletMembership = 471e4d3504SHeejin Ahn getEHScopeMembership(F); 4816193552SDavid Majnemer if (FuncletMembership.empty()) 4997890230SDavid Majnemer return false; 5097890230SDavid Majnemer 51e4f9b09bSDavid Majnemer F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) { 52e4f9b09bSDavid Majnemer auto FuncletX = FuncletMembership.find(&X); 53e4f9b09bSDavid Majnemer auto FuncletY = FuncletMembership.find(&Y); 54e4f9b09bSDavid Majnemer assert(FuncletX != FuncletMembership.end()); 55e4f9b09bSDavid Majnemer assert(FuncletY != FuncletMembership.end()); 56e4f9b09bSDavid Majnemer return FuncletX->second < FuncletY->second; 579966fe8fSDavid Majnemer }); 5897890230SDavid Majnemer 5997890230SDavid Majnemer // Conservatively assume we changed something. 6097890230SDavid Majnemer return true; 6197890230SDavid Majnemer } 62