2015-09-17 20:45:18 +00:00
|
|
|
//===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
|
|
|
|
//
|
2019-01-19 08:50:56 +00: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 20:45:18 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements basic block placement transformations which result in
|
|
|
|
// funclets being contiguous.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-10-04 02:22:52 +00:00
|
|
|
#include "llvm/CodeGen/Analysis.h"
|
2015-09-17 20:45:18 +00:00
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
2017-06-06 11:49:48 +00:00
|
|
|
#include "llvm/CodeGen/Passes.h"
|
2015-09-17 20:45:18 +00: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 17:05:30 +00:00
|
|
|
MachineFunctionProperties getRequiredProperties() const override {
|
|
|
|
return MachineFunctionProperties().set(
|
2016-08-25 01:27:13 +00:00
|
|
|
MachineFunctionProperties::Property::NoVRegs);
|
2016-03-28 17:05:30 +00:00
|
|
|
}
|
2015-09-17 20:45:18 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
char FuncletLayout::ID = 0;
|
|
|
|
char &llvm::FuncletLayoutID = FuncletLayout::ID;
|
2017-05-25 21:26:32 +00:00
|
|
|
INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE,
|
2015-09-17 20:45:18 +00:00
|
|
|
"Contiguously Lay Out Funclets", false, false)
|
|
|
|
|
|
|
|
bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
|
2018-06-01 00:03:21 +00: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 02:22:52 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333045 91177308-0d34-0410-b5e6-96231b3b80d8
2018-05-23 00:32:46 +00:00
|
|
|
getEHScopeMembership(F);
|
2015-10-04 02:22:52 +00:00
|
|
|
if (FuncletMembership.empty())
|
2015-09-17 20:45:18 +00:00
|
|
|
return false;
|
|
|
|
|
2015-10-05 20:09:16 +00: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 08:18:07 +00:00
|
|
|
});
|
2015-09-17 20:45:18 +00:00
|
|
|
|
|
|
|
// Conservatively assume we changed something.
|
|
|
|
return true;
|
|
|
|
}
|