Skip to content

Commit 7317be6

Browse files
authored
Change effect for pause (WebAssembly#8401)
The `pause` instruction doesn't have observable side effects, but for it to fulfill its purpose of making spinlocks more efficient, we need to avoid moving it out of loops. We previously did this by setting the `isAtomic` effect, but that effect will soon go away in favor of a more detailed analysis of how expressions may synchronize across threads. Switch to using `branchesOut` as the effect to keep `pause` from being moved instead and add a test demonstrating that it works as intended.
1 parent ce8f2d1 commit 7317be6

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

src/ir/effects.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,10 @@ class EffectAnalyzer {
644644
parent.isAtomic = true;
645645
}
646646
void visitPause(Pause* curr) {
647-
// It's not much of a problem if pause gets reordered with anything, but
648-
// we don't want it to be removed entirely.
649-
parent.isAtomic = true;
647+
// We don't want this to be moved out of loops, but it doesn't otherwises
648+
// matter much how it gets reordered. Say we transfer control as a coarse
649+
// approximation of this.
650+
parent.branchesOut = true;
650651
}
651652
void visitSIMDExtract(SIMDExtract* curr) {}
652653
void visitSIMDReplace(SIMDReplace* curr) {}

test/lit/passes/licm.wast

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
22

3-
;; RUN: foreach %s %t wasm-opt --licm -S -o - | filecheck %s
3+
;; RUN: foreach %s %t wasm-opt -all --licm -S -o - | filecheck %s
44

55
(module
66
(memory 10 20)
@@ -11,7 +11,7 @@
1111

1212
;; CHECK: (memory $0 10 20)
1313

14-
;; CHECK: (func $unreachable-get
14+
;; CHECK: (func $unreachable-get (type $1)
1515
;; CHECK-NEXT: (local $x i32)
1616
;; CHECK-NEXT: (drop
1717
;; CHECK-NEXT: (local.get $x)
@@ -35,7 +35,7 @@
3535
)
3636
)
3737

38-
;; CHECK: (func $unreachable-get-call (param $p i32)
38+
;; CHECK: (func $unreachable-get-call (type $0) (param $p i32)
3939
;; CHECK-NEXT: (local $x i32)
4040
;; CHECK-NEXT: (loop $loop
4141
;; CHECK-NEXT: (unreachable)
@@ -56,7 +56,7 @@
5656
)
5757
)
5858

59-
;; CHECK: (func $unreachable-get-store (param $p i32)
59+
;; CHECK: (func $unreachable-get-store (type $0) (param $p i32)
6060
;; CHECK-NEXT: (local $x i32)
6161
;; CHECK-NEXT: (loop $loop
6262
;; CHECK-NEXT: (unreachable)
@@ -78,5 +78,30 @@
7878
)
7979
)
8080
)
81-
)
8281

82+
;; CHECK: (func $pause (type $0) (param $p i32)
83+
;; CHECK-NEXT: (drop
84+
;; CHECK-NEXT: (i32.const 0)
85+
;; CHECK-NEXT: )
86+
;; CHECK-NEXT: (loop $loop
87+
;; CHECK-NEXT: (nop)
88+
;; CHECK-NEXT: (pause)
89+
;; CHECK-NEXT: (drop
90+
;; CHECK-NEXT: (i32.const 1)
91+
;; CHECK-NEXT: )
92+
;; CHECK-NEXT: (br $loop)
93+
;; CHECK-NEXT: )
94+
;; CHECK-NEXT: )
95+
(func $pause (param $p i32)
96+
;; We don't want pause to be moved out of loops. In principle we should be
97+
;; able to move side-effect-free expressions back before the pause, but we
98+
;; currently do not. Pause is rare and specialized enough that this shouldn't
99+
;; be a problem.
100+
(loop $loop
101+
(drop (i32.const 0))
102+
(pause)
103+
(drop (i32.const 1))
104+
(br $loop)
105+
)
106+
)
107+
)

0 commit comments

Comments
 (0)