xref: /src/contrib/llvm-project/llvm/lib/CodeGen/FuncletLayout.cpp (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
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