Skip to content

Commit eaddadd

Browse files
committed
Add wasm unreachable peephole optimisation
1 parent 05d0c17 commit eaddadd

File tree

5 files changed

+71
-9
lines changed

5 files changed

+71
-9
lines changed

lld/test/wasm/init-fini.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ entry:
7777
; CHECK-NEXT: Body: 10031004100A100F1012100F10141003100C100F10161001100E0B
7878
; CHECK: - Index: 22
7979
; CHECK-NEXT: Locals:
80-
; CHECK-NEXT: Body: 02404186808080004100418088808000108780808000450D0000000B0B
80+
; CHECK-NEXT: Body: 02404186808080004100418088808000108780808000450D00000B0B
8181
; CHECK-NEXT: - Type: CUSTOM
8282
; CHECK-NEXT: Name: name
8383
; CHECK-NEXT: FunctionNames:

llvm/lib/Target/WebAssembly/WebAssemblyDebugFixup.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,22 @@ bool WebAssemblyDebugFixup::runOnMachineFunction(MachineFunction &MF) {
122122
// it will be culled later.
123123
}
124124
} else {
125+
126+
// WebAssembly Peephole optimisation can remove instructions around wasm
127+
// unreachable. This is valid for wasm, as unreachable is operand stack
128+
// polymorphic. But this is not modeled in llvm at the moment, and so
129+
// the stack may not seem to pop all that it pushes. Clear the stack so
130+
// we don't violate the assert(Stack.empty()) later on.
131+
if (MI.getOpcode() == WebAssembly::UNREACHABLE) {
132+
Stack.clear();
133+
break;
134+
}
135+
125136
// Track stack depth.
126137
for (MachineOperand &MO : reverse(MI.explicit_uses())) {
127138
if (MO.isReg() && MFI.isVRegStackified(MO.getReg())) {
139+
assert(Stack.size() != 0 &&
140+
"WebAssemblyDebugFixup: Pop: Operand stack empty!");
128141
auto Prev = Stack.back();
129142
Stack.pop_back();
130143
assert(Prev.Reg == MO.getReg() &&

llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/CodeGen/MachineFunctionPass.h"
2121
#include "llvm/CodeGen/MachineInstrBuilder.h"
2222
#include "llvm/CodeGen/MachineRegisterInfo.h"
23+
#include <iterator>
2324
using namespace llvm;
2425

2526
#define DEBUG_TYPE "wasm-peephole"
@@ -109,6 +110,53 @@ static bool maybeRewriteToFallthrough(MachineInstr &MI, MachineBasicBlock &MBB,
109110
return true;
110111
}
111112

113+
static bool eraseDeadCodeAroundUnreachable(MachineInstr &UnreachbleMI,
114+
MachineBasicBlock &MBB) {
115+
SmallVector<MachineInstr *, 16> ToDelete;
116+
117+
// Because wasm unreachable is stack polymorphic and unconditionally ends
118+
// control, all instructions after it can be removed until the end of this
119+
// block. We remove the common case of double unreachable.
120+
auto ForwardsIterator = UnreachbleMI.getIterator();
121+
for (ForwardsIterator++; !ForwardsIterator.isEnd(); ForwardsIterator++) {
122+
MachineInstr &MI = *ForwardsIterator;
123+
if (MI.getOpcode() == WebAssembly::UNREACHABLE) {
124+
ToDelete.push_back(&MI);
125+
} else {
126+
break;
127+
}
128+
}
129+
130+
// For the same reasons as above, previous instructions that only affect
131+
// local function state can be removed (e.g. local.set, drop, various reads).
132+
// We remove the common case of "drop unreachable".
133+
auto BackwardsIterator = UnreachbleMI.getReverseIterator();
134+
for (BackwardsIterator++; !BackwardsIterator.isEnd(); BackwardsIterator++) {
135+
MachineInstr &MI = *BackwardsIterator;
136+
switch (MI.getOpcode()) {
137+
case WebAssembly::DROP_I32:
138+
case WebAssembly::DROP_I64:
139+
case WebAssembly::DROP_F32:
140+
case WebAssembly::DROP_F64:
141+
case WebAssembly::DROP_EXTERNREF:
142+
case WebAssembly::DROP_FUNCREF:
143+
case WebAssembly::DROP_V128:
144+
ToDelete.push_back(&MI);
145+
continue;
146+
default:
147+
goto exit_loop;
148+
}
149+
}
150+
exit_loop:;
151+
152+
bool Changed = false;
153+
for (MachineInstr *MI : ToDelete) {
154+
MI->eraseFromParent();
155+
Changed = true;
156+
}
157+
return Changed;
158+
}
159+
112160
bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) {
113161
LLVM_DEBUG({
114162
dbgs() << "********** Peephole **********\n"
@@ -159,6 +207,9 @@ bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) {
159207
case WebAssembly::RETURN:
160208
Changed |= maybeRewriteToFallthrough(MI, MBB, MF, MFI, MRI, TII);
161209
break;
210+
case WebAssembly::UNREACHABLE:
211+
Changed |= eraseDeadCodeAroundUnreachable(MI, MBB);
212+
break;
162213
}
163214

164215
return Changed;

llvm/test/CodeGen/WebAssembly/unreachable.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ define void @trap_unreach() {
4141
; CHECK: .functype trap_unreach () -> ()
4242
; CHECK-NEXT: # %bb.0:
4343
; CHECK-NEXT: unreachable
44-
; CHECK-NEXT: unreachable
4544
; CHECK-NEXT: end_function
4645
call void @llvm.trap()
4746
unreachable
@@ -99,7 +98,6 @@ define i32 @i32_sig_match_unreach() {
9998
; CHECK: .functype i32_sig_match_unreach () -> (i32)
10099
; CHECK-NEXT: # %bb.0:
101100
; CHECK-NEXT: call ext_func_i32
102-
; CHECK-NEXT: drop
103101
; CHECK-NEXT: unreachable
104102
; CHECK-NEXT: end_function
105103
call i32 @ext_func_i32()

llvm/test/MC/WebAssembly/global-ctor-dtor.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,29 +80,29 @@ declare void @func3()
8080
; CHECK-NEXT: Offset: 0x1D
8181
; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
8282
; CHECK-NEXT: Index: 6
83-
; CHECK-NEXT: Offset: 0x2C
83+
; CHECK-NEXT: Offset: 0x2B
8484
; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
8585
; CHECK-NEXT: Index: 5
86-
; CHECK-NEXT: Offset: 0x37
86+
; CHECK-NEXT: Offset: 0x36
8787
; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
8888
; CHECK-NEXT: Index: 3
89-
; CHECK-NEXT: Offset: 0x3F
89+
; CHECK-NEXT: Offset: 0x3E
9090
; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
9191
; CHECK-NEXT: Index: 4
92-
; CHECK-NEXT: Offset: 0x45
92+
; CHECK-NEXT: Offset: 0x44
9393
; CHECK-NEXT: Functions:
9494
; CHECK-NEXT: - Index: 5
9595
; CHECK-NEXT: Locals:
9696
; CHECK-NEXT: Body: 1080808080000B
9797
; CHECK-NEXT: - Index: 6
9898
; CHECK-NEXT: Locals:
99-
; CHECK-NEXT: Body: 02404181808080004100418080808000108180808000450D0000000B0B
99+
; CHECK-NEXT: Body: 02404181808080004100418080808000108180808000450D00000B0B
100100
; CHECK-NEXT: - Index: 7
101101
; CHECK-NEXT: Locals:
102102
; CHECK-NEXT: Body: 1082808080000B
103103
; CHECK-NEXT: - Index: 8
104104
; CHECK-NEXT: Locals:
105-
; CHECK-NEXT: Body: 02404182808080004100418080808000108180808000450D0000000B0B
105+
; CHECK-NEXT: Body: 02404182808080004100418080808000108180808000450D00000B0B
106106
; CHECK-NEXT: - Type: DATA
107107
; CHECK-NEXT: Segments:
108108
; CHECK-NEXT: - SectionOffset: 6

0 commit comments

Comments
 (0)