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