mirror of
https://github.com/llvm/llvm-project.git
synced 2026-10-26 13:53:31 +08:00
Adds a newPM pass for FuncletLayout (funclet-layout).
- Extracts the pass's logic (which has no per-instance state) into a
shared runFuncletLayout free function, called by both the legacy pass
and the new pass manager pass.
- Renames the old pass with the "Legacy" suffix.
- Adds the new pass manager pass FuncletLayoutPass, using
RequiredPassInfoMixin: the legacy pass's runOnMachineFunction never
calls skipFunction, so it always runs unconditionally and should not be
skippable in the new PM either.
- Updates MachinePassRegistry.def, PassBuilder, and CodeGenPassBuilder
-- FuncletLayoutPass was already unconditionally invoked from
CodeGenPassBuilder.h via a DUMMY_MACHINE_FUNCTION_PASS stub, so no
separate enablement change was needed.
- Fixes four pipeline-dump tests (X86, RISC-V x2, Lanai) whose CHECK
lines expected the stub's class-name fallback ("FuncletLayoutPass")
rather than the real pass's registered pipeline name ("funclet-layout").
- Adds a -enable-new-pm RUN line to branchfolding-catchpads.ll, an
existing multi-funclet WinEH test, since no dedicated small unit test
existed to extend the way other newPM ports have done.
Assisted-by: Claude Sonnet 5
72 lines
2.5 KiB
C++
72 lines
2.5 KiB
C++
//===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements basic block placement transformations which result in
|
|
// funclets being contiguous.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "llvm/CodeGen/FuncletLayout.h"
|
|
#include "llvm/CodeGen/Analysis.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/CodeGen/Passes.h"
|
|
#include "llvm/InitializePasses.h"
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "funclet-layout"
|
|
|
|
static bool runFuncletLayout(MachineFunction &F) {
|
|
// 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.
|
|
DenseMap<const MachineBasicBlock *, int> FuncletMembership =
|
|
getEHScopeMembership(F);
|
|
if (FuncletMembership.empty())
|
|
return false;
|
|
|
|
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;
|
|
});
|
|
|
|
// Conservatively assume we changed something.
|
|
return true;
|
|
}
|
|
|
|
namespace {
|
|
class FuncletLayoutLegacy : public MachineFunctionPass {
|
|
public:
|
|
static char ID; // Pass identification, replacement for typeid
|
|
FuncletLayoutLegacy() : MachineFunctionPass(ID) {}
|
|
|
|
bool runOnMachineFunction(MachineFunction &F) override {
|
|
return runFuncletLayout(F);
|
|
}
|
|
MachineFunctionProperties getRequiredProperties() const override {
|
|
return MachineFunctionProperties().setNoVRegs();
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
char FuncletLayoutLegacy::ID = 0;
|
|
char &llvm::FuncletLayoutID = FuncletLayoutLegacy::ID;
|
|
INITIALIZE_PASS(FuncletLayoutLegacy, DEBUG_TYPE,
|
|
"Contiguously Lay Out Funclets", false, false)
|
|
|
|
PreservedAnalyses FuncletLayoutPass::run(MachineFunction &MF,
|
|
MachineFunctionAnalysisManager &MFAM) {
|
|
MFPropsModifier _(*this, MF);
|
|
if (!runFuncletLayout(MF))
|
|
return PreservedAnalyses::all();
|
|
|
|
return getMachineFunctionPassPreservedAnalyses();
|
|
}
|