summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp20
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h5
-rw-r--r--llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll14
3 files changed, 37 insertions, 2 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index 6c38dead9ae..6b2094679ce 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -694,8 +694,26 @@ void WebAssemblyCFGStackify::removeUnnecessaryInstrs(MachineFunction &MF) {
}
}
+// 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
@@ -1007,6 +1025,7 @@ bool WebAssemblyCFGStackify::fixUnwindMismatches(MachineFunction &MF) {
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);
@@ -1122,6 +1141,7 @@ bool WebAssemblyCFGStackify::fixUnwindMismatches(MachineFunction &MF) {
// 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.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
index 91e5055ad59..16e2f439298 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
@@ -101,6 +101,11 @@ public:
VRegStackified.resize(I + 1);
VRegStackified.set(I);
}
+ void unstackifyVReg(unsigned VReg) {
+ auto I = Register::virtReg2Index(VReg);
+ if (I < VRegStackified.size())
+ VRegStackified.reset(I);
+ }
bool isVRegStackified(unsigned VReg) const {
auto I = Register::virtReg2Index(VReg);
if (I >= VRegStackified.size())
diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
index 9cb5a057ef1..104e324faae 100644
--- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
+++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
@@ -436,13 +436,17 @@ try.cont: ; preds = %catch.start1, %catc
; 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
@@ -460,7 +464,8 @@ bb0:
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
@@ -618,6 +623,9 @@ try.cont: ; preds = %catch.start1, %catc
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)
@@ -627,3 +635,5 @@ declare i8* @__cxa_begin_catch(i8*)
declare void @__cxa_end_catch()
declare void @__clang_call_terminate(i8*)
declare void @_ZSt9terminatev()
+
+attributes #0 = { nounwind }
OpenPOWER on IntegriCloud