2015-09-17 22:45:18 +02:00
|
|
|
//===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2015-09-17 22:45:18 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements basic block placement transformations which result in
|
|
|
|
// funclets being contiguous.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-10-04 04:22:52 +02:00
|
|
|
#include "llvm/CodeGen/Analysis.h"
|
2015-09-17 22:45:18 +02:00
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
2017-06-06 13:49:48 +02:00
|
|
|
#include "llvm/CodeGen/Passes.h"
|
2015-09-17 22:45:18 +02:00
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
#define DEBUG_TYPE "funclet-layout"
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
class FuncletLayout : public MachineFunctionPass {
|
|
|
|
public:
|
|
|
|
static char ID; // Pass identification, replacement for typeid
|
|
|
|
FuncletLayout() : MachineFunctionPass(ID) {
|
|
|
|
initializeFuncletLayoutPass(*PassRegistry::getPassRegistry());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool runOnMachineFunction(MachineFunction &F) override;
|
2016-03-28 19:05:30 +02:00
|
|
|
MachineFunctionProperties getRequiredProperties() const override {
|
|
|
|
return MachineFunctionProperties().set(
|
2016-08-25 03:27:13 +02:00
|
|
|
MachineFunctionProperties::Property::NoVRegs);
|
2016-03-28 19:05:30 +02:00
|
|
|
}
|
2015-09-17 22:45:18 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
char FuncletLayout::ID = 0;
|
|
|
|
char &llvm::FuncletLayoutID = FuncletLayout::ID;
|
2017-05-25 23:26:32 +02:00
|
|
|
INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE,
|
2015-09-17 22:45:18 +02:00
|
|
|
"Contiguously Lay Out Funclets", false, false)
|
|
|
|
|
|
|
|
bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
|
2018-06-01 02:03:21 +02:00
|
|
|
// Even though this gets information from getEHScopeMembership(), this pass is
|
|
|
|
// only necessary for funclet-based EH personalities, in which these EH scopes
|
|
|
|
// are outlined at the end.
|
2015-10-04 04:22:52 +02:00
|
|
|
DenseMap<const MachineBasicBlock *, int> FuncletMembership =
|
[WebAssembly] Add functions for EHScopes
Summary:
There are functions using the term 'funclet' to refer to both
1. an EH scopes, the structure of BBs that starts with
catchpad/cleanuppad and ends with catchret/cleanupret, and
2. a small function that gets outlined in AsmPrinter, which is the
original meaning of 'funclet'.
So far the two have been the same thing; EH scopes are always outlined
in AsmPrinter as funclets at the end of the compilation pipeline. But
now wasm also uses scope-based EH but does not outline those, so we now
need to correctly distinguish those two use cases in functions.
This patch splits `MachineBasicBlock::isFuncletEntry` into
`isFuncletEntry` and `isEHScopeEntry`, and
`MachineFunction::hasFunclets` into `hasFunclets` and `hasEHScopes`, in
order to distinguish the two different use cases. And this also changes
some uses of the term 'funclet' to 'scope' in `getFuncletMembership` and
change the function name to `getEHScopeMembership` because this function
is not about outlined funclets but about EH scope memberships.
This change is in the same vein as D45559.
Reviewers: majnemer, dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D47005
llvm-svn: 333045
2018-05-23 02:32:46 +02:00
|
|
|
getEHScopeMembership(F);
|
2015-10-04 04:22:52 +02:00
|
|
|
if (FuncletMembership.empty())
|
2015-09-17 22:45:18 +02:00
|
|
|
return false;
|
|
|
|
|
2015-10-05 22:09:16 +02:00
|
|
|
F.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
|
|
|
|
auto FuncletX = FuncletMembership.find(&X);
|
|
|
|
auto FuncletY = FuncletMembership.find(&Y);
|
|
|
|
assert(FuncletX != FuncletMembership.end());
|
|
|
|
assert(FuncletY != FuncletMembership.end());
|
|
|
|
return FuncletX->second < FuncletY->second;
|
2015-09-18 10:18:07 +02:00
|
|
|
});
|
2015-09-17 22:45:18 +02:00
|
|
|
|
|
|
|
// Conservatively assume we changed something.
|
|
|
|
return true;
|
|
|
|
}
|