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