[WebAssembly] Port WebAssemblyCFGStackifyPass
Standard NewPM pass porting.
Reviewers: dschuff, sbc100, aheejin
Pull Request: https://github.com/llvm/llvm-project/pull/210255
diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h
index 57a1cc0..91c8828 100644
--- a/llvm/lib/Target/WebAssembly/WebAssembly.h
+++ b/llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -246,7 +246,15 @@
};
FunctionPass *createWebAssemblyCFGSortLegacyPass();
-FunctionPass *createWebAssemblyCFGStackify();
+
+class WebAssemblyCFGStackifyPass
+ : public RequiredPassInfoMixin<WebAssemblyCFGStackifyPass> {
+public:
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createWebAssemblyCFGStackifyLegacyPass();
FunctionPass *createWebAssemblyExplicitLocals();
FunctionPass *createWebAssemblyLowerBrUnless();
FunctionPass *createWebAssemblyRegNumbering();
@@ -263,7 +271,7 @@
void initializeWebAssemblyAsmPrinterPass(PassRegistry &);
void initializeWebAssemblyCleanCodeAfterTrapLegacyPass(PassRegistry &);
void initializeWebAssemblyCFGSortLegacyPass(PassRegistry &);
-void initializeWebAssemblyCFGStackifyPass(PassRegistry &);
+void initializeWebAssemblyCFGStackifyLegacyPass(PassRegistry &);
void initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &);
void initializeWebAssemblyDebugFixupPass(PassRegistry &);
void initializeWebAssemblyExceptionInfoWrapperPassPass(PassRegistry &);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index be781af..b609f3e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -33,8 +33,12 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/IR/Analysis.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
@@ -46,19 +50,10 @@
STATISTIC(NumCatchUnwindMismatches, "Number of catch unwind mismatches found");
namespace {
-class WebAssemblyCFGStackify final : public MachineFunctionPass {
- MachineDominatorTree *MDT;
-
- StringRef getPassName() const override { return "WebAssembly CFG Stackify"; }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<MachineDominatorTreeWrapperPass>();
- AU.addRequired<MachineLoopInfoWrapperPass>();
- AU.addRequired<WebAssemblyExceptionInfoWrapperPass>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
+class WebAssemblyCFGStackifyImpl {
+ MachineDominatorTree &MDT;
+ MachineLoopInfo &MLI;
+ WebAssemblyExceptionInfo &WEI;
// For each block whose label represents the end of a scope, record the block
// which holds the beginning of the scope. This will allow us to quickly skip
@@ -169,21 +164,38 @@
void unregisterScope(MachineInstr *Begin);
public:
+ WebAssemblyCFGStackifyImpl(MachineDominatorTree &MDT, MachineLoopInfo &MLI,
+ WebAssemblyExceptionInfo &WEI)
+ : MDT(MDT), MLI(MLI), WEI(WEI) {}
+
+ bool runOnMachineFunction(MachineFunction &MF);
+};
+
+class WebAssemblyCFGStackifyLegacy : public MachineFunctionPass {
+ StringRef getPassName() const override { return "WebAssembly CFG Stackify"; }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<MachineDominatorTreeWrapperPass>();
+ AU.addRequired<MachineLoopInfoWrapperPass>();
+ AU.addRequired<WebAssemblyExceptionInfoWrapperPass>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+public:
+ bool runOnMachineFunction(MachineFunction &MF) override;
static char ID; // Pass identification, replacement for typeid
- WebAssemblyCFGStackify() : MachineFunctionPass(ID) {}
- ~WebAssemblyCFGStackify() override { releaseMemory(); }
- void releaseMemory() override;
+ WebAssemblyCFGStackifyLegacy() : MachineFunctionPass(ID) {}
};
} // end anonymous namespace
-char WebAssemblyCFGStackify::ID = 0;
+char WebAssemblyCFGStackifyLegacy::ID = 0;
INITIALIZE_PASS(
- WebAssemblyCFGStackify, DEBUG_TYPE,
+ WebAssemblyCFGStackifyLegacy, DEBUG_TYPE,
"Insert BLOCK/LOOP/TRY/TRY_TABLE markers for WebAssembly scopes", false,
false)
-FunctionPass *llvm::createWebAssemblyCFGStackify() {
- return new WebAssemblyCFGStackify();
+FunctionPass *llvm::createWebAssemblyCFGStackifyLegacyPass() {
+ return new WebAssemblyCFGStackifyLegacy();
}
/// Test whether Pred has any terminators explicitly branching to MBB, as
@@ -248,22 +260,22 @@
return InsertPos;
}
-void WebAssemblyCFGStackify::registerScope(MachineInstr *Begin,
- MachineInstr *End) {
+void WebAssemblyCFGStackifyImpl::registerScope(MachineInstr *Begin,
+ MachineInstr *End) {
BeginToEnd[Begin] = End;
EndToBegin[End] = Begin;
}
// When 'End' is not an 'end_try' but a 'delegate', EHPad is nullptr.
-void WebAssemblyCFGStackify::registerTryScope(MachineInstr *Begin,
- MachineInstr *End,
- MachineBasicBlock *EHPad) {
+void WebAssemblyCFGStackifyImpl::registerTryScope(MachineInstr *Begin,
+ MachineInstr *End,
+ MachineBasicBlock *EHPad) {
registerScope(Begin, End);
TryToEHPad[Begin] = EHPad;
EHPadToTry[EHPad] = Begin;
}
-void WebAssemblyCFGStackify::unregisterScope(MachineInstr *Begin) {
+void WebAssemblyCFGStackifyImpl::unregisterScope(MachineInstr *Begin) {
assert(BeginToEnd.count(Begin));
MachineInstr *End = BeginToEnd[Begin];
assert(EndToBegin.count(End));
@@ -280,7 +292,7 @@
/// Insert a BLOCK marker for branches to MBB (if needed).
// TODO Consider a more generalized way of handling block (and also loop and
// try) signatures when we implement the multi-value proposal later.
-void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
+void WebAssemblyCFGStackifyImpl::placeBlockMarker(MachineBasicBlock &MBB) {
assert(!MBB.isEHPad());
MachineFunction &MF = *MBB.getParent();
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
@@ -294,7 +306,7 @@
int MBBNumber = MBB.getNumber();
for (MachineBasicBlock *Pred : MBB.predecessors()) {
if (Pred->getNumber() < MBBNumber) {
- Header = Header ? MDT->findNearestCommonDominator(Header, Pred) : Pred;
+ Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
if (explicitlyBranchesTo(Pred, &MBB))
IsBranchedTo = true;
}
@@ -431,10 +443,8 @@
}
/// Insert a LOOP marker for a loop starting at MBB (if it's a loop header).
-void WebAssemblyCFGStackify::placeLoopMarker(MachineBasicBlock &MBB) {
+void WebAssemblyCFGStackifyImpl::placeLoopMarker(MachineBasicBlock &MBB) {
MachineFunction &MF = *MBB.getParent();
- const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
- const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
SortRegionInfo SRI(MLI, WEI);
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
@@ -498,13 +508,10 @@
updateScopeTops(&MBB, AfterLoop);
}
-void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
+void WebAssemblyCFGStackifyImpl::placeTryMarker(MachineBasicBlock &MBB) {
assert(MBB.isEHPad());
MachineFunction &MF = *MBB.getParent();
- auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
- const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
- const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
SortRegionInfo SRI(MLI, WEI);
const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
@@ -692,13 +699,10 @@
updateScopeTops(Header, End);
}
-void WebAssemblyCFGStackify::placeTryTableMarker(MachineBasicBlock &MBB) {
+void WebAssemblyCFGStackifyImpl::placeTryTableMarker(MachineBasicBlock &MBB) {
assert(MBB.isEHPad());
MachineFunction &MF = *MBB.getParent();
- auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
- const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
- const auto &WEI = getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
SortRegionInfo SRI(MLI, WEI);
const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
@@ -989,7 +993,7 @@
updateScopeTops(Header, End);
}
-void WebAssemblyCFGStackify::removeUnnecessaryInstrs(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::removeUnnecessaryInstrs(MachineFunction &MF) {
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
// When there is an unconditional branch right before a catch instruction and
@@ -1171,7 +1175,7 @@
// Wrap the given range of instructions with a try-delegate that targets
// 'UnwindDest'. RangeBegin and RangeEnd are inclusive.
-void WebAssemblyCFGStackify::addNestedTryDelegate(
+void WebAssemblyCFGStackifyImpl::addNestedTryDelegate(
MachineInstr *RangeBegin, MachineInstr *RangeEnd,
MachineBasicBlock *UnwindDest) {
auto *BeginBB = RangeBegin->getParent();
@@ -1309,7 +1313,7 @@
// throw_ref
// end_try_table
MachineBasicBlock *
-WebAssemblyCFGStackify::getTrampolineBlock(MachineBasicBlock *UnwindDest) {
+WebAssemblyCFGStackifyImpl::getTrampolineBlock(MachineBasicBlock *UnwindDest) {
// We need one trampoline BB per unwind destination, even though there are
// multiple try_tables target the same unwind destination. If we have already
// created one for the given UnwindDest, return it.
@@ -1380,9 +1384,9 @@
// Wrap the given range of instructions with a try_table-end_try_table that
// targets 'UnwindDest'. RangeBegin and RangeEnd are inclusive.
-void WebAssemblyCFGStackify::addNestedTryTable(MachineInstr *RangeBegin,
- MachineInstr *RangeEnd,
- MachineBasicBlock *UnwindDest) {
+void WebAssemblyCFGStackifyImpl::addNestedTryTable(
+ MachineInstr *RangeBegin, MachineInstr *RangeEnd,
+ MachineBasicBlock *UnwindDest) {
auto *BeginBB = RangeBegin->getParent();
auto *EndBB = RangeEnd->getParent();
@@ -1589,7 +1593,7 @@
return Name;
}
-bool WebAssemblyCFGStackify::fixCallUnwindMismatches(MachineFunction &MF) {
+bool WebAssemblyCFGStackifyImpl::fixCallUnwindMismatches(MachineFunction &MF) {
// This function is used for both the legacy EH and the standard (exnref) EH,
// and the reason we have unwind mismatches is the same for the both of them,
// but the code examples in the comments are going to be different. To make
@@ -2073,7 +2077,7 @@
return true;
}
-bool WebAssemblyCFGStackify::fixCatchUnwindMismatches(MachineFunction &MF) {
+bool WebAssemblyCFGStackifyImpl::fixCatchUnwindMismatches(MachineFunction &MF) {
// This function is used for both the legacy EH and the standard (exnref) EH,
// and the reason we have unwind mismatches is the same for the both of them,
// but the code examples in the comments are going to be different. To make
@@ -2364,7 +2368,7 @@
return true;
}
-void WebAssemblyCFGStackify::recalculateScopeTops(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::recalculateScopeTops(MachineFunction &MF) {
// Renumber BBs and recalculate ScopeTop info because new BBs might have been
// created and inserted during fixing unwind mismatches.
MF.RenumberBlocks();
@@ -2398,7 +2402,7 @@
/// that end at the function end need to have a return type signature that
/// matches the function signature, even though it's unreachable. This function
/// checks for such cases and fixes up the signatures.
-void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::fixEndsAtEndOfFunction(MachineFunction &MF) {
const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
if (MFI.getResults().empty())
@@ -2506,7 +2510,7 @@
}
/// Insert BLOCK/LOOP/TRY/TRY_TABLE markers at appropriate places.
-void WebAssemblyCFGStackify::placeMarkers(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::placeMarkers(MachineFunction &MF) {
// We allocate one more than the number of blocks in the function to
// accommodate for the possible fake block we may insert at the end.
ScopeTops.resize(MF.getNumBlockIDs() + 1);
@@ -2548,7 +2552,7 @@
}
}
-unsigned WebAssemblyCFGStackify::getBranchDepth(
+unsigned WebAssemblyCFGStackifyImpl::getBranchDepth(
const SmallVectorImpl<EndMarkerInfo> &Stack, const MachineBasicBlock *MBB) {
unsigned Depth = 0;
for (auto X : reverse(Stack)) {
@@ -2560,7 +2564,7 @@
return Depth;
}
-unsigned WebAssemblyCFGStackify::getDelegateDepth(
+unsigned WebAssemblyCFGStackifyImpl::getDelegateDepth(
const SmallVectorImpl<EndMarkerInfo> &Stack, const MachineBasicBlock *MBB) {
if (MBB == FakeCallerBB)
return Stack.size();
@@ -2595,7 +2599,7 @@
return Depth;
}
-unsigned WebAssemblyCFGStackify::getRethrowDepth(
+unsigned WebAssemblyCFGStackifyImpl::getRethrowDepth(
const SmallVectorImpl<EndMarkerInfo> &Stack,
const MachineBasicBlock *EHPadToRethrow) {
unsigned Depth = 0;
@@ -2612,7 +2616,7 @@
return Depth;
}
-void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::rewriteDepthImmediates(MachineFunction &MF) {
// Now rewrite references to basic blocks to be depth immediates.
SmallVector<EndMarkerInfo, 8> Stack;
@@ -2683,29 +2687,17 @@
assert(Stack.empty() && "Control flow should be balanced");
}
-void WebAssemblyCFGStackify::cleanupFunctionData(MachineFunction &MF) {
+void WebAssemblyCFGStackifyImpl::cleanupFunctionData(MachineFunction &MF) {
if (FakeCallerBB)
MF.deleteMachineBasicBlock(FakeCallerBB);
AppendixBB = FakeCallerBB = CallerTrampolineBB = nullptr;
}
-void WebAssemblyCFGStackify::releaseMemory() {
- ScopeTops.clear();
- BeginToEnd.clear();
- EndToBegin.clear();
- TryToEHPad.clear();
- EHPadToTry.clear();
- UnwindDestToTrampoline.clear();
-}
-
-bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
+bool WebAssemblyCFGStackifyImpl::runOnMachineFunction(MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "********** CFG Stackifying **********\n"
"********** Function: "
<< MF.getName() << '\n');
const MCAsmInfo &MCAI = MF.getTarget().getMCAsmInfo();
- MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
-
- releaseMemory();
// Liveness is not tracked for VALUE_STACK physreg.
MF.getRegInfo().invalidateLiveness();
@@ -2735,3 +2727,26 @@
MF.getInfo<WebAssemblyFunctionInfo>()->setCFGStackified();
return true;
}
+
+bool WebAssemblyCFGStackifyLegacy::runOnMachineFunction(MachineFunction &MF) {
+ MachineDominatorTree &MDT =
+ getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+ MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
+ WebAssemblyExceptionInfo &WEI =
+ getAnalysis<WebAssemblyExceptionInfoWrapperPass>().getWEI();
+ WebAssemblyCFGStackifyImpl Impl(MDT, MLI, WEI);
+ return Impl.runOnMachineFunction(MF);
+}
+
+PreservedAnalyses
+WebAssemblyCFGStackifyPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+ MachineLoopInfo &MLI = MFAM.getResult<MachineLoopAnalysis>(MF);
+ WebAssemblyExceptionInfo &WEI =
+ MFAM.getResult<WebAssemblyExceptionAnalysis>(MF);
+ WebAssemblyCFGStackifyImpl Impl(MDT, MLI, WEI);
+ return Impl.runOnMachineFunction(MF)
+ ? getMachineFunctionPassPreservedAnalyses()
+ : PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
index 4cf950f..9cdb42b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
@@ -220,7 +220,7 @@
addMachineFunctionPass(WebAssemblyCFGSortPass(), PMW);
// Insert BLOCK and LOOP markers.
- // TODO(boomanaiden154): WebAssemblyCFGStackify
+ addMachineFunctionPass(WebAssemblyCFGStackifyPass(), PMW);
// Insert explicit local.get and local.set operators.
if (!WasmDisableExplicitLocals) {
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
index 93e9d51..467a88e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
@@ -40,6 +40,7 @@
#endif
MACHINE_FUNCTION_PASS("wasm-argument-move", WebAssemblyArgumentMovePass())
MACHINE_FUNCTION_PASS("wasm-cfg-sort", WebAssemblyCFGSortPass())
+MACHINE_FUNCTION_PASS("wasm-cfg-stackify", WebAssemblyCFGStackifyPass())
MACHINE_FUNCTION_PASS("wasm-clean-code-after-trap",
WebAssemblyCleanCodeAfterTrapPass())
MACHINE_FUNCTION_PASS("wasm-isel", WebAssemblyISelDAGToDAGPass(*this, getOptLevel()))
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index ef2add0..ac242f3 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -112,7 +112,7 @@
initializeWebAssemblyLateEHPrepareLegacyPass(PR);
initializeWebAssemblyExceptionInfoWrapperPassPass(PR);
initializeWebAssemblyCFGSortLegacyPass(PR);
- initializeWebAssemblyCFGStackifyPass(PR);
+ initializeWebAssemblyCFGStackifyLegacyPass(PR);
initializeWebAssemblyExplicitLocalsPass(PR);
initializeWebAssemblyLowerBrUnlessPass(PR);
initializeWebAssemblyRegNumberingPass(PR);
@@ -486,7 +486,7 @@
addPass(createWebAssemblyCFGSortLegacyPass());
// Insert BLOCK and LOOP markers.
- addPass(createWebAssemblyCFGStackify());
+ addPass(createWebAssemblyCFGStackifyLegacyPass());
// Insert explicit local.get and local.set operators.
if (!WasmDisableExplicitLocals)