}
}
+// When MBB is split into MBB and Split, we should unstackify defs in MBB that
+// have their uses in Split.
+static void unstackifyVRegsUsedInSplitBB(MachineBasicBlock &MBB,
+ MachineBasicBlock &Split,
+ WebAssemblyFunctionInfo &MFI,
+ MachineRegisterInfo &MRI) {
+ for (auto &MI : Split) {
+ for (auto &MO : MI.explicit_uses()) {
+ if (!MO.isReg() || Register::isPhysicalRegister(MO.getReg()))
+ continue;
+ if (MachineInstr *Def = MRI.getUniqueVRegDef(MO.getReg()))
+ if (Def->getParent() == &MBB)
+ MFI.unstackifyVReg(MO.getReg());
+ }
+ }
+}
+
bool WebAssemblyCFGStackify::fixUnwindMismatches(MachineFunction &MF) {
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
+ auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
MachineRegisterInfo &MRI = MF.getRegInfo();
// Linearizing the control flow by placing TRY / END_TRY markers can create
BrDest->insert(BrDest->end(), EndTry->removeFromParent());
// Take out the handler body from EH pad to the new branch destination BB.
BrDest->splice(BrDest->end(), EHPad, SplitPos, EHPad->end());
+ unstackifyVRegsUsedInSplitBB(*EHPad, *BrDest, MFI, MRI);
// Fix predecessor-successor relationship.
BrDest->transferSuccessors(EHPad);
EHPad->addSuccessor(BrDest);
// new nested continuation BB.
NestedCont->splice(NestedCont->end(), MBB,
std::next(RangeEnd->getIterator()), MBB->end());
+ unstackifyVRegsUsedInSplitBB(*MBB, *NestedCont, MFI, MRI);
registerTryScope(NestedTry, NestedEndTry, NestedEHPad);
// Fix predecessor-successor relationship.
; the right destination (label4), from which we rethrow the exception to the
; caller.
+; And the return value of 'baz' should NOT be stackified because the BB is split
+; during fixing unwind mismatches.
+
; NOSORT-LABEL: test6
; NOSORT: try
; NOSORT: call foo
; --- Nested try/catch/end_try starts
; NOSORT: try
; NOSORT: call bar
-; NOSORT: call bar
+; NOSORT: i32.call ${{[0-9]+}}=, baz
+; NOSORT-NOT: i32.call $push{{.*}}=, baz
; NOSORT: catch $[[REG:[0-9]+]]=
; NOSORT: br 1 # 1: down to label35
; NOSORT: end_try
bb1: ; preds = %bb0
call void @bar()
- call void @bar()
+ %call = call i32 @baz()
+ call void @nothrow(i32 %call) #0
ret void
catch.dispatch0: ; preds = %bb0
declare void @foo()
declare void @bar()
+declare i32 @baz()
+; Function Attrs: nounwind
+declare void @nothrow(i32) #0
declare i32 @__gxx_wasm_personality_v0(...)
declare i8* @llvm.wasm.get.exception(token)
declare i32 @llvm.wasm.get.ehselector(token)
declare void @__cxa_end_catch()
declare void @__clang_call_terminate(i8*)
declare void @_ZSt9terminatev()
+
+attributes #0 = { nounwind }