197890230SDavid Majnemer //===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
297890230SDavid Majnemer //
397890230SDavid Majnemer //                     The LLVM Compiler Infrastructure
497890230SDavid Majnemer //
597890230SDavid Majnemer // This file is distributed under the University of Illinois Open Source
697890230SDavid Majnemer // License. See LICENSE.TXT for details.
797890230SDavid Majnemer //
897890230SDavid Majnemer //===----------------------------------------------------------------------===//
997890230SDavid Majnemer //
1097890230SDavid Majnemer // This file implements basic block placement transformations which result in
1197890230SDavid Majnemer // funclets being contiguous.
1297890230SDavid Majnemer //
1397890230SDavid Majnemer //===----------------------------------------------------------------------===//
1497890230SDavid Majnemer #include "llvm/CodeGen/Passes.h"
1516193552SDavid Majnemer #include "llvm/CodeGen/Analysis.h"
1697890230SDavid Majnemer #include "llvm/CodeGen/MachineFunction.h"
1797890230SDavid Majnemer #include "llvm/CodeGen/MachineFunctionPass.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
2697890230SDavid Majnemer   FuncletLayout() : MachineFunctionPass(ID) {
2797890230SDavid Majnemer     initializeFuncletLayoutPass(*PassRegistry::getPassRegistry());
2897890230SDavid Majnemer   }
2997890230SDavid Majnemer 
3097890230SDavid Majnemer   bool runOnMachineFunction(MachineFunction &F) override;
3197890230SDavid Majnemer };
3297890230SDavid Majnemer }
3397890230SDavid Majnemer 
3497890230SDavid Majnemer char FuncletLayout::ID = 0;
3597890230SDavid Majnemer char &llvm::FuncletLayoutID = FuncletLayout::ID;
3697890230SDavid Majnemer INITIALIZE_PASS(FuncletLayout, "funclet-layout",
3797890230SDavid Majnemer                 "Contiguously Lay Out Funclets", false, false)
3897890230SDavid Majnemer 
3997890230SDavid Majnemer bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
4016193552SDavid Majnemer   DenseMap<const MachineBasicBlock *, int> FuncletMembership =
4116193552SDavid Majnemer       getFuncletMembership(F);
4216193552SDavid Majnemer   if (FuncletMembership.empty())
4397890230SDavid Majnemer     return false;
4497890230SDavid Majnemer 
45*e4f9b09bSDavid Majnemer   F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
46*e4f9b09bSDavid Majnemer     auto FuncletX = FuncletMembership.find(&X);
47*e4f9b09bSDavid Majnemer     auto FuncletY = FuncletMembership.find(&Y);
48*e4f9b09bSDavid Majnemer     assert(FuncletX != FuncletMembership.end());
49*e4f9b09bSDavid Majnemer     assert(FuncletY != FuncletMembership.end());
50*e4f9b09bSDavid Majnemer     return FuncletX->second < FuncletY->second;
519966fe8fSDavid Majnemer   });
5297890230SDavid Majnemer 
5397890230SDavid Majnemer   // Conservatively assume we changed something.
5497890230SDavid Majnemer   return true;
5597890230SDavid Majnemer }
56