blob: 581cd423f2d4e99c0b3804a291cdb9bfea42933e [file] [log] [blame]
David Majnemer048d7e52015-09-17 20:45:18 +00001//===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements basic block placement transformations which result in
11// funclets being contiguous.
12//
13//===----------------------------------------------------------------------===//
David Majnemer492f1cf2015-10-04 02:22:52 +000014#include "llvm/CodeGen/Analysis.h"
David Majnemer048d7e52015-09-17 20:45:18 +000015#include "llvm/CodeGen/MachineFunction.h"
16#include "llvm/CodeGen/MachineFunctionPass.h"
Chandler Carruthe3e43d92017-06-06 11:49:48 +000017#include "llvm/CodeGen/Passes.h"
David Majnemer048d7e52015-09-17 20:45:18 +000018using namespace llvm;
19
20#define DEBUG_TYPE "funclet-layout"
21
22namespace {
23class FuncletLayout : public MachineFunctionPass {
24public:
25 static char ID; // Pass identification, replacement for typeid
26 FuncletLayout() : MachineFunctionPass(ID) {
27 initializeFuncletLayoutPass(*PassRegistry::getPassRegistry());
28 }
29
30 bool runOnMachineFunction(MachineFunction &F) override;
Derek Schufffadd1132016-03-28 17:05:30 +000031 MachineFunctionProperties getRequiredProperties() const override {
32 return MachineFunctionProperties().set(
Matthias Braun690a3cb2016-08-25 01:27:13 +000033 MachineFunctionProperties::Property::NoVRegs);
Derek Schufffadd1132016-03-28 17:05:30 +000034 }
David Majnemer048d7e52015-09-17 20:45:18 +000035};
36}
37
David Majnemer048d7e52015-09-17 20:45:18 +000038char FuncletLayout::ID = 0;
39char &llvm::FuncletLayoutID = FuncletLayout::ID;
Matthias Braun94c49042017-05-25 21:26:32 +000040INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE,
David Majnemer048d7e52015-09-17 20:45:18 +000041 "Contiguously Lay Out Funclets", false, false)
42
43bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
Heejin Ahn2522e342018-06-01 00:03:21 +000044 // Even though this gets information from getEHScopeMembership(), this pass is
45 // only necessary for funclet-based EH personalities, in which these EH scopes
46 // are outlined at the end.
David Majnemer492f1cf2015-10-04 02:22:52 +000047 DenseMap<const MachineBasicBlock *, int> FuncletMembership =
Heejin Ahna3ccaa92018-05-23 00:32:46 +000048 getEHScopeMembership(F);
David Majnemer492f1cf2015-10-04 02:22:52 +000049 if (FuncletMembership.empty())
David Majnemer048d7e52015-09-17 20:45:18 +000050 return false;
51
David Majnemer6212b4d2015-10-05 20:09:16 +000052 F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
53 auto FuncletX = FuncletMembership.find(&X);
54 auto FuncletY = FuncletMembership.find(&Y);
55 assert(FuncletX != FuncletMembership.end());
56 assert(FuncletY != FuncletMembership.end());
57 return FuncletX->second < FuncletY->second;
David Majnemer01156432015-09-18 08:18:07 +000058 });
David Majnemer048d7e52015-09-17 20:45:18 +000059
60 // Conservatively assume we changed something.
61 return true;
62}