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