17d523365SDimitry Andric //===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===// 27d523365SDimitry Andric // 37d523365SDimitry Andric // The LLVM Compiler Infrastructure 47d523365SDimitry Andric // 57d523365SDimitry Andric // This file is distributed under the University of Illinois Open Source 67d523365SDimitry Andric // License. See LICENSE.TXT for details. 77d523365SDimitry Andric // 87d523365SDimitry Andric //===----------------------------------------------------------------------===// 97d523365SDimitry Andric // 107d523365SDimitry Andric // This file implements basic block placement transformations which result in 117d523365SDimitry Andric // funclets being contiguous. 127d523365SDimitry Andric // 137d523365SDimitry Andric //===----------------------------------------------------------------------===// 147d523365SDimitry Andric #include "llvm/CodeGen/Analysis.h" 157d523365SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 167d523365SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 17db17bf38SDimitry Andric #include "llvm/CodeGen/Passes.h" 187d523365SDimitry Andric using namespace llvm; 197d523365SDimitry Andric 207d523365SDimitry Andric #define DEBUG_TYPE "funclet-layout" 217d523365SDimitry Andric 227d523365SDimitry Andric namespace { 237d523365SDimitry Andric class FuncletLayout : public MachineFunctionPass { 247d523365SDimitry Andric public: 257d523365SDimitry Andric static char ID; // Pass identification, replacement for typeid FuncletLayout()267d523365SDimitry Andric FuncletLayout() : MachineFunctionPass(ID) { 277d523365SDimitry Andric initializeFuncletLayoutPass(*PassRegistry::getPassRegistry()); 287d523365SDimitry Andric } 297d523365SDimitry Andric 307d523365SDimitry Andric bool runOnMachineFunction(MachineFunction &F) override; getRequiredProperties() const313ca95b02SDimitry Andric MachineFunctionProperties getRequiredProperties() const override { 323ca95b02SDimitry Andric return MachineFunctionProperties().set( 33d88c1a5aSDimitry Andric MachineFunctionProperties::Property::NoVRegs); 343ca95b02SDimitry Andric } 357d523365SDimitry Andric }; 367d523365SDimitry Andric } 377d523365SDimitry Andric 387d523365SDimitry Andric char FuncletLayout::ID = 0; 397d523365SDimitry Andric char &llvm::FuncletLayoutID = FuncletLayout::ID; 40302affcbSDimitry Andric INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE, 417d523365SDimitry Andric "Contiguously Lay Out Funclets", false, false) 427d523365SDimitry Andric runOnMachineFunction(MachineFunction & F)437d523365SDimitry Andricbool FuncletLayout::runOnMachineFunction(MachineFunction &F) { 44*4ba319b5SDimitry Andric // Even though this gets information from getEHScopeMembership(), this pass is 45*4ba319b5SDimitry Andric // only necessary for funclet-based EH personalities, in which these EH scopes 46*4ba319b5SDimitry Andric // are outlined at the end. 477d523365SDimitry Andric DenseMap<const MachineBasicBlock *, int> FuncletMembership = 48*4ba319b5SDimitry Andric getEHScopeMembership(F); 497d523365SDimitry Andric if (FuncletMembership.empty()) 507d523365SDimitry Andric return false; 517d523365SDimitry Andric 527d523365SDimitry Andric F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) { 537d523365SDimitry Andric auto FuncletX = FuncletMembership.find(&X); 547d523365SDimitry Andric auto FuncletY = FuncletMembership.find(&Y); 557d523365SDimitry Andric assert(FuncletX != FuncletMembership.end()); 567d523365SDimitry Andric assert(FuncletY != FuncletMembership.end()); 577d523365SDimitry Andric return FuncletX->second < FuncletY->second; 587d523365SDimitry Andric }); 597d523365SDimitry Andric 607d523365SDimitry Andric // Conservatively assume we changed something. 617d523365SDimitry Andric return true; 627d523365SDimitry Andric } 63