[llvm] [WebAssembly] Add assembly support for final EH proposal (PR #107917)
Derek Schuff via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 10 13:34:08 PDT 2024
================
@@ -259,14 +269,74 @@ bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) {
return Changed;
}
-// Remove unnecessary unreachables after a throw or rethrow.
+// Add CATCH_REF and CATCH_ALL_REF pseudo instructions to EH pads, and convert
+// RETHROWs to THROW_REFs.
+bool WebAssemblyLateEHPrepare::addCatchRefsAndThrowRefs(MachineFunction &MF) {
+ bool Changed = false;
+ const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
+ auto &MRI = MF.getRegInfo();
+ DenseMap<MachineBasicBlock *, SmallVector<MachineInstr *, 2>> EHPadToRethrows;
+
+ // Create a map of <EH pad, a vector of RETHROWs rethrowing its exception>
+ for (auto &MBB : MF) {
+ for (auto &MI : MBB) {
+ if (MI.getOpcode() == WebAssembly::RETHROW) {
+ Changed = true;
+ auto *EHPad = getMatchingEHPad(&MI);
+ EHPadToRethrows[EHPad].push_back(&MI);
+ }
+ }
+ }
+
+ // Convert CATCH into CATCH_REF and CATCH_ALL into CATCH_ALL_REF, when the
+ // caught exception is rethrown. And convert RETHROWs to THROW_REFs.
+ for (auto &[EHPad, Rethrows] : EHPadToRethrows) {
+ auto *Catch = WebAssembly::findCatch(EHPad);
+ auto *InsertPos = Catch->getIterator()->getNextNode();
+ auto ExnReg = MRI.createVirtualRegister(&WebAssembly::EXNREFRegClass);
+ if (Catch->getOpcode() == WebAssembly::CATCH) {
+ MachineInstrBuilder MIB = BuildMI(*EHPad, InsertPos, Catch->getDebugLoc(),
+ TII.get(WebAssembly::CATCH_REF));
+ // Copy defs (= extracted values) from the old CATCH to the new CATCH_REF
+ for (const auto &Def : Catch->defs())
+ MIB.addDef(Def.getReg());
+ MIB.addDef(ExnReg); // Attach the exnref def after extracted values
+ // Copy the tag symbol (The only use operand a CATCH can have is the tag
+ // symbol)
+ for (const auto &Use : Catch->uses()) {
+ MIB.addExternalSymbol(Use.getSymbolName());
+ break;
+ }
+ } else if (Catch->getOpcode() == WebAssembly::CATCH_ALL) {
+ BuildMI(*EHPad, InsertPos, Catch->getDebugLoc(),
+ TII.get(WebAssembly::CATCH_ALL_REF))
+ .addDef(ExnReg);
+ } else {
+ assert(false);
+ }
+ Catch->eraseFromParent();
+
+ for (auto *Rethrow : Rethrows) {
+ auto InsertPos = Rethrow->getIterator()++;
----------------
dschuff wrote:
The use of post-increment on the getter seems a little bit confusing to me (since it seems like it's being used on an rvalue rather than on a variable that is still live after the statement). Is this equivalent to `getIterator()->getNextNode()` like you used above?
https://github.com/llvm/llvm-project/pull/107917
More information about the llvm-commits
mailing list