1 //===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements basic block placement transformations which result in 10 // funclets being contiguous. 11 // 12 //===----------------------------------------------------------------------===// 13 #include "llvm/CodeGen/Analysis.h" 14 #include "llvm/CodeGen/MachineFunction.h" 15 #include "llvm/CodeGen/MachineFunctionPass.h" 16 #include "llvm/CodeGen/Passes.h" 17 using namespace llvm; 18 19 #define DEBUG_TYPE "funclet-layout" 20 21 namespace { 22 class FuncletLayout : public MachineFunctionPass { 23 public: 24 static char ID; // Pass identification, replacement for typeid 25 FuncletLayout() : MachineFunctionPass(ID) { 26 initializeFuncletLayoutPass(*PassRegistry::getPassRegistry()); 27 } 28 29 bool runOnMachineFunction(MachineFunction &F) override; 30 MachineFunctionProperties getRequiredProperties() const override { 31 return MachineFunctionProperties().set( 32 MachineFunctionProperties::Property::NoVRegs); 33 } 34 }; 35 } 36 37 char FuncletLayout::ID = 0; 38 char &llvm::FuncletLayoutID = FuncletLayout::ID; 39 INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE, 40 "Contiguously Lay Out Funclets", false, false) 41 42 bool FuncletLayout::runOnMachineFunction(MachineFunction &F) { 43 // Even though this gets information from getEHScopeMembership(), this pass is 44 // only necessary for funclet-based EH personalities, in which these EH scopes 45 // are outlined at the end. 46 DenseMap<const MachineBasicBlock *, int> FuncletMembership = 47 getEHScopeMembership(F); 48 if (FuncletMembership.empty()) 49 return false; 50 51 F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) { 52 auto FuncletX = FuncletMembership.find(&X); 53 auto FuncletY = FuncletMembership.find(&Y); 54 assert(FuncletX != FuncletMembership.end()); 55 assert(FuncletY != FuncletMembership.end()); 56 return FuncletX->second < FuncletY->second; 57 }); 58 59 // Conservatively assume we changed something. 60 return true; 61 } 62