-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[WebAssembly] Fix rethrow's index calculation #114693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
71b0a4e
037036a
82ab656
275b383
80cd16e
2a182ba
a83b535
16df64b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -251,15 +251,40 @@ bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) { | |
Changed = true; | ||
break; | ||
} | ||
case WebAssembly::RETHROW: | ||
// These RETHROWs here were lowered from llvm.wasm.rethrow() intrinsics, | ||
// generated in Clang for when an exception is not caught by the given | ||
// type (e.g. catch (int)). | ||
// | ||
// RETHROW's BB argument is the EH pad the exception to rethrow has been | ||
aheejin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// caught. (Until this point, RETHROW has just a '0' as a placeholder | ||
// argument.) For these llvm.wasm.rethrow()s, we can safely assume the | ||
// exception comes from the nearest dominating EH pad, because catch.start | ||
// EH pad is structured like this: | ||
// | ||
// catch.start: | ||
// catchpad ... | ||
// %matches = compare ehselector with typeid | ||
// br i1 %matches, label %catch, label %rethrow | ||
// | ||
// rethrow: | ||
// ;; rethrows the exception caught in 'catch.start' | ||
// call @llvm.wasm.rethrow() | ||
while (TI->getNumOperands() > 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we expect there to be more than one operand on the end here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking about the implicit operands ( RETHROW 0, implicit-def dead $arguments But turns out all explicit operands automatically go before implicit ones so I think I can just do |
||
TI->removeOperand(TI->getNumOperands() - 1); | ||
TI->addOperand(MachineOperand::CreateMBB(getMatchingEHPad(TI))); | ||
Changed = true; | ||
break; | ||
case WebAssembly::CLEANUPRET: { | ||
// Replace a cleanupret with a rethrow. For C++ support, currently | ||
// rethrow's immediate argument is always 0 (= the latest exception). | ||
// CLEANUPRETs have the EH pad BB the exception to rethrow has been caught | ||
// as an argument. Use it and change the instruction opcode to 'RETHROW' | ||
// to make rethrowing instructions consistent. | ||
// | ||
// Even when -wasm-enable-exnref is true, we use a RETHROW here for the | ||
// moment. This will be converted to a THROW_REF in | ||
// addCatchRefsAndThrowRefs. | ||
// This is because we cannot safely assume that it is always the nearest | ||
// dominating EH pad, in case there are code transformations such as | ||
// inlining. | ||
BuildMI(MBB, TI, TI->getDebugLoc(), TII.get(WebAssembly::RETHROW)) | ||
.addImm(0); | ||
.addMBB(TI->getOperand(0).getMBB()); | ||
TI->eraseFromParent(); | ||
Changed = true; | ||
break; | ||
|
@@ -272,21 +297,17 @@ bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) { | |
// 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); | ||
} | ||
} | ||
} | ||
for (auto &MBB : MF) | ||
for (auto &MI : MBB) | ||
if (MI.getOpcode() == WebAssembly::RETHROW) | ||
EHPadToRethrows[MI.getOperand(0).getMBB()].push_back(&MI); | ||
if (EHPadToRethrows.empty()) | ||
return false; | ||
|
||
// Convert CATCH into CATCH_REF and CATCH_ALL into CATCH_ALL_REF, when the | ||
// caught exception is rethrown. And convert RETHROWs to THROW_REFs. | ||
|
@@ -325,7 +346,7 @@ bool WebAssemblyLateEHPrepare::addCatchRefsAndThrowRefs(MachineFunction &MF) { | |
} | ||
} | ||
|
||
return Changed; | ||
return true; | ||
} | ||
|
||
// Remove unnecessary unreachables after a throw/rethrow/throw_ref. | ||
|
Uh oh!
There was an error while loading. Please reload this page.