1292915Sdim//===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
2292915Sdim//
3292915Sdim//                     The LLVM Compiler Infrastructure
4292915Sdim//
5292915Sdim// This file is distributed under the University of Illinois Open Source
6292915Sdim// License. See LICENSE.TXT for details.
7292915Sdim//
8292915Sdim//===----------------------------------------------------------------------===//
9292915Sdim//
10292915Sdim// This file implements basic block placement transformations which result in
11292915Sdim// funclets being contiguous.
12292915Sdim//
13292915Sdim//===----------------------------------------------------------------------===//
14292915Sdim#include "llvm/CodeGen/Passes.h"
15292915Sdim#include "llvm/CodeGen/Analysis.h"
16292915Sdim#include "llvm/CodeGen/MachineFunction.h"
17292915Sdim#include "llvm/CodeGen/MachineFunctionPass.h"
18292915Sdimusing namespace llvm;
19292915Sdim
20292915Sdim#define DEBUG_TYPE "funclet-layout"
21292915Sdim
22292915Sdimnamespace {
23292915Sdimclass FuncletLayout : public MachineFunctionPass {
24292915Sdimpublic:
25292915Sdim  static char ID; // Pass identification, replacement for typeid
26292915Sdim  FuncletLayout() : MachineFunctionPass(ID) {
27292915Sdim    initializeFuncletLayoutPass(*PassRegistry::getPassRegistry());
28292915Sdim  }
29292915Sdim
30292915Sdim  bool runOnMachineFunction(MachineFunction &F) override;
31292915Sdim};
32292915Sdim}
33292915Sdim
34292915Sdimchar FuncletLayout::ID = 0;
35292915Sdimchar &llvm::FuncletLayoutID = FuncletLayout::ID;
36292915SdimINITIALIZE_PASS(FuncletLayout, "funclet-layout",
37292915Sdim                "Contiguously Lay Out Funclets", false, false)
38292915Sdim
39292915Sdimbool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
40292915Sdim  DenseMap<const MachineBasicBlock *, int> FuncletMembership =
41292915Sdim      getFuncletMembership(F);
42292915Sdim  if (FuncletMembership.empty())
43292915Sdim    return false;
44292915Sdim
45292915Sdim  F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
46292915Sdim    auto FuncletX = FuncletMembership.find(&X);
47292915Sdim    auto FuncletY = FuncletMembership.find(&Y);
48292915Sdim    assert(FuncletX != FuncletMembership.end());
49292915Sdim    assert(FuncletY != FuncletMembership.end());
50292915Sdim    return FuncletX->second < FuncletY->second;
51292915Sdim  });
52292915Sdim
53292915Sdim  // Conservatively assume we changed something.
54292915Sdim  return true;
55292915Sdim}
56