blob: 75f6d0b8f0bfe1b8fda2666caedf3bb59c9bdc35 [file] [log] [blame]
David Majnemer97890232015-09-17 20:45:18 +00001//===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
David Majnemer97890232015-09-17 20:45:18 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements basic block placement transformations which result in
10// funclets being contiguous.
11//
12//===----------------------------------------------------------------------===//
David Majnemer16193552015-10-04 02:22:52 +000013#include "llvm/CodeGen/Analysis.h"
David Majnemer97890232015-09-17 20:45:18 +000014#include "llvm/CodeGen/MachineFunction.h"
15#include "llvm/CodeGen/MachineFunctionPass.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000016#include "llvm/CodeGen/Passes.h"
David Majnemer97890232015-09-17 20:45:18 +000017using namespace llvm;
18
19#define DEBUG_TYPE "funclet-layout"
20
21namespace {
22class FuncletLayout : public MachineFunctionPass {
23public:
24 static char ID; // Pass identification, replacement for typeid
25 FuncletLayout() : MachineFunctionPass(ID) {
26 initializeFuncletLayoutPass(*PassRegistry::getPassRegistry());
27 }
28
29 bool runOnMachineFunction(MachineFunction &F) override;
Derek Schuffad154c82016-03-28 17:05:30 +000030 MachineFunctionProperties getRequiredProperties() const override {
31 return MachineFunctionProperties().set(
Matthias Braun1eb47362016-08-25 01:27:13 +000032 MachineFunctionProperties::Property::NoVRegs);
Derek Schuffad154c82016-03-28 17:05:30 +000033 }
David Majnemer97890232015-09-17 20:45:18 +000034};
35}
36
David Majnemer97890232015-09-17 20:45:18 +000037char FuncletLayout::ID = 0;
38char &llvm::FuncletLayoutID = FuncletLayout::ID;
Matthias Braun1527baa2017-05-25 21:26:32 +000039INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE,
David Majnemer97890232015-09-17 20:45:18 +000040 "Contiguously Lay Out Funclets", false, false)
41
42bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
Heejin Ahnd69acf32018-06-01 00:03:21 +000043 // Even though this gets information from getEHScopeMembership(), this pass is
44 // only necessary for funclet-based EH personalities, in which these EH scopes
45 // are outlined at the end.
David Majnemer16193552015-10-04 02:22:52 +000046 DenseMap<const MachineBasicBlock *, int> FuncletMembership =
Heejin Ahn1e4d3502018-05-23 00:32:46 +000047 getEHScopeMembership(F);
David Majnemer16193552015-10-04 02:22:52 +000048 if (FuncletMembership.empty())
David Majnemer97890232015-09-17 20:45:18 +000049 return false;
50
David Majnemere4f9b092015-10-05 20:09:16 +000051 F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
52 auto FuncletX = FuncletMembership.find(&X);
53 auto FuncletY = FuncletMembership.find(&Y);
54 assert(FuncletX != FuncletMembership.end());
55 assert(FuncletY != FuncletMembership.end());
56 return FuncletX->second < FuncletY->second;
David Majnemer9966fe82015-09-18 08:18:07 +000057 });
David Majnemer97890232015-09-17 20:45:18 +000058
59 // Conservatively assume we changed something.
60 return true;
61}