xref: /llvm-project/llvm/lib/CodeGen/FuncletLayout.cpp (revision 05da2fe52162c80dfa18aedf70cf73cb11201811)
197890230SDavid Majnemer //===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
297890230SDavid Majnemer //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler 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"
17*05da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
1897890230SDavid Majnemer using namespace llvm;
1997890230SDavid Majnemer 
2097890230SDavid Majnemer #define DEBUG_TYPE "funclet-layout"
2197890230SDavid Majnemer 
2297890230SDavid Majnemer namespace {
2397890230SDavid Majnemer class FuncletLayout : public MachineFunctionPass {
2497890230SDavid Majnemer public:
2597890230SDavid Majnemer   static char ID; // Pass identification, replacement for typeid
FuncletLayout()2697890230SDavid Majnemer   FuncletLayout() : MachineFunctionPass(ID) {
2797890230SDavid Majnemer     initializeFuncletLayoutPass(*PassRegistry::getPassRegistry());
2897890230SDavid Majnemer   }
2997890230SDavid Majnemer 
3097890230SDavid Majnemer   bool runOnMachineFunction(MachineFunction &F) override;
getRequiredProperties() const31ad154c83SDerek Schuff   MachineFunctionProperties getRequiredProperties() const override {
32ad154c83SDerek Schuff     return MachineFunctionProperties().set(
331eb47368SMatthias Braun         MachineFunctionProperties::Property::NoVRegs);
34ad154c83SDerek Schuff   }
3597890230SDavid Majnemer };
3697890230SDavid Majnemer }
3797890230SDavid Majnemer 
3897890230SDavid Majnemer char FuncletLayout::ID = 0;
3997890230SDavid Majnemer char &llvm::FuncletLayoutID = FuncletLayout::ID;
401527baabSMatthias Braun INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE,
4197890230SDavid Majnemer                 "Contiguously Lay Out Funclets", false, false)
4297890230SDavid Majnemer 
runOnMachineFunction(MachineFunction & F)4397890230SDavid Majnemer bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
44d69acf3bSHeejin Ahn   // Even though this gets information from getEHScopeMembership(), this pass is
45d69acf3bSHeejin Ahn   // only necessary for funclet-based EH personalities, in which these EH scopes
46d69acf3bSHeejin Ahn   // are outlined at the end.
4716193552SDavid Majnemer   DenseMap<const MachineBasicBlock *, int> FuncletMembership =
481e4d3504SHeejin Ahn       getEHScopeMembership(F);
4916193552SDavid Majnemer   if (FuncletMembership.empty())
5097890230SDavid Majnemer     return false;
5197890230SDavid Majnemer 
52e4f9b09bSDavid Majnemer   F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
53e4f9b09bSDavid Majnemer     auto FuncletX = FuncletMembership.find(&X);
54e4f9b09bSDavid Majnemer     auto FuncletY = FuncletMembership.find(&Y);
55e4f9b09bSDavid Majnemer     assert(FuncletX != FuncletMembership.end());
56e4f9b09bSDavid Majnemer     assert(FuncletY != FuncletMembership.end());
57e4f9b09bSDavid Majnemer     return FuncletX->second < FuncletY->second;
589966fe8fSDavid Majnemer   });
5997890230SDavid Majnemer 
6097890230SDavid Majnemer   // Conservatively assume we changed something.
6197890230SDavid Majnemer   return true;
6297890230SDavid Majnemer }
63