2015-09-18 04:45:18 +08:00
|
|
|
//===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08: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-18 04:45:18 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements basic block placement transformations which result in
|
|
|
|
// funclets being contiguous.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-10-04 10:22:52 +08:00
|
|
|
#include "llvm/CodeGen/Analysis.h"
|
2015-09-18 04:45:18 +08:00
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "llvm/CodeGen/Passes.h"
|
Sink all InitializePasses.h includes
This file lists every pass in LLVM, and is included by Pass.h, which is
very popular. Every time we add, remove, or rename a pass in LLVM, it
caused lots of recompilation.
I found this fact by looking at this table, which is sorted by the
number of times a file was changed over the last 100,000 git commits
multiplied by the number of object files that depend on it in the
current checkout:
recompiles touches affected_files header
342380 95 3604 llvm/include/llvm/ADT/STLExtras.h
314730 234 1345 llvm/include/llvm/InitializePasses.h
307036 118 2602 llvm/include/llvm/ADT/APInt.h
213049 59 3611 llvm/include/llvm/Support/MathExtras.h
170422 47 3626 llvm/include/llvm/Support/Compiler.h
162225 45 3605 llvm/include/llvm/ADT/Optional.h
158319 63 2513 llvm/include/llvm/ADT/Triple.h
140322 39 3598 llvm/include/llvm/ADT/StringRef.h
137647 59 2333 llvm/include/llvm/Support/Error.h
131619 73 1803 llvm/include/llvm/Support/FileSystem.h
Before this change, touching InitializePasses.h would cause 1345 files
to recompile. After this change, touching it only causes 550 compiles in
an incremental rebuild.
Reviewers: bkramer, asbirlea, bollu, jdoerfert
Differential Revision: https://reviews.llvm.org/D70211
2019-11-14 05:15:01 +08:00
|
|
|
#include "llvm/InitializePasses.h"
|
2015-09-18 04:45:18 +08: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-29 01:05:30 +08:00
|
|
|
MachineFunctionProperties getRequiredProperties() const override {
|
|
|
|
return MachineFunctionProperties().set(
|
2016-08-25 09:27:13 +08:00
|
|
|
MachineFunctionProperties::Property::NoVRegs);
|
2016-03-29 01:05:30 +08:00
|
|
|
}
|
2015-09-18 04:45:18 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
char FuncletLayout::ID = 0;
|
|
|
|
char &llvm::FuncletLayoutID = FuncletLayout::ID;
|
2017-05-26 05:26:32 +08:00
|
|
|
INITIALIZE_PASS(FuncletLayout, DEBUG_TYPE,
|
2015-09-18 04:45:18 +08:00
|
|
|
"Contiguously Lay Out Funclets", false, false)
|
|
|
|
|
|
|
|
bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
|
2018-06-01 08:03:21 +08: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 10:22:52 +08: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 08:32:46 +08:00
|
|
|
getEHScopeMembership(F);
|
2015-10-04 10:22:52 +08:00
|
|
|
if (FuncletMembership.empty())
|
2015-09-18 04:45:18 +08:00
|
|
|
return false;
|
|
|
|
|
2015-10-06 04:09:16 +08: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 16:18:07 +08:00
|
|
|
});
|
2015-09-18 04:45:18 +08:00
|
|
|
|
|
|
|
// Conservatively assume we changed something.
|
|
|
|
return true;
|
|
|
|
}
|