You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/smalltalk/en/st0060.md
+10-10Lines changed: 10 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,27 +1,27 @@
1
-
# Process of solving the "Parallel ϕ-nodes" problem in Go and Wa-lang
1
+
# Process of solving the "Parallel ϕ-nodes" problem in Go and Wa
2
2
3
3
Ernan Ding, Shushan Chai
4
4
5
5
---
6
6
7
-
Recently, we (the [Wa-lang](https://github.com/wa-lang/wa) development team), discovered a bug that also exists in Go. It's related to SSA and the process was quite dramatic, as recorded below.
7
+
Recently, we (the [Wa](https://github.com/wa-lang/wa) development team), discovered a bug that also exists in Go. It's related to SSA and the process was quite dramatic, as recorded below.
8
8
9
9
## 1. Background introduction
10
10
11
-
Wa-lang is a general-purpose programming language based on Go, its semantics is quite similar with Go, but designed for WebAssembly. The frontend of Wa-lang (source code to AST) is modified from Go 1.17, AST to SSA conversion uses the `golang.org/x/tools/go/ssa` package, and we write the backend (SSA to Wasm) from scrath.
11
+
Wa (Chinese name "凹", which pronounced "Wa") is a general-purpose programming language based on Go, its semantics is quite similar with Go, but designed for WebAssembly. The frontend of Wa (source code to AST) is modified from Go 1.17, AST to SSA conversion uses the `golang.org/x/tools/go/ssa` package, and we write the backend (SSA to Wasm) from scrath.
12
12
13
13
SSA (Static Single-Assignment) is an intermediate representation of code, where variables are assigned only once. SSA form helps with program analysis and optimization. For more information, see [https://en.wikipedia.org/wiki/Static_single-assignment_form](https://en.wikipedia.org/wiki/Static_single-assignment_form).
14
14
15
-
The `golang.org/x/tools/go/ssa` package is a toolkit provided by Go, which provides functions such as converting Go-AST to Go-SSA. Many Go-based language projects are based on or use it, including TinyGo, Go+, etc., as well as Wa-lang. But it is worth noting that **this package is not used for the Go compiler itself**, but is mainly used for external tools such as code analysis.
15
+
The `golang.org/x/tools/go/ssa` package is a toolkit provided by Go, which provides functions such as converting Go-AST to Go-SSA. Many Go-based language projects are based on or use it, including TinyGo, Go+, etc., as well as Wa. But it is worth noting that **this package is not used for the Go compiler itself**, but is mainly used for external tools such as code analysis.
16
16
17
17
## 2. Problem appears
18
18
19
-
Wa-lang recently supports the semantics of Map. However, when we tried to optimize its implementation using binary search tree, the results did not meet expectations. After a day of investigation, we reduced and located the problem code as follows:
19
+
Wa recently supports the semantics of Map. However, when we tried to optimize its implementation using binary search tree, the results did not meet expectations. After a day of investigation, we reduced and located the problem code as follows:
20
20
21
21

22
22
23
-
The left side of the figure is the Wa-lang code, and the right side is the equivalent Go code.
24
-
According to the program logic, since `root` has been initialized in the `main` function, lines 20 and 24 of the `insert` function should be executed and print the same non-empty value. However, the running results of the above Wa-lang code are as follows:
23
+
The left side of the figure is the Wa code, and the right side is the equivalent Go code.
24
+
According to the program logic, since `root` has been initialized in the `main` function, lines 20 and 24 of the `insert` function should be executed and print the same non-empty value. However, the running results of the above Wa code are as follows:
25
25
26
26
```
27
27
===
@@ -71,7 +71,7 @@ That is, after leaving the loop body, `y` will be incorrectly assigned to nil. W
71
71
72
72
Soon after the issue was opened, Alan Donovan closed it. He said that SSA was fine and suggested that we learn the basics of SSA first.
73
73
74
-
However, we insisted that there was a problem with the `ssa` package. On the one hand, the above SSA code is not long, and its execution logic is not difficult to reason about; more importantly, we found that when the `Interpret()` function of the `ssa/interp` package was used to interpret the above SSA code, `y` was still incorrectly assigned to a nil value, and the printed result was no different from the output of the Wa-lang version! So we submitted these evidence, hoping to reopen the issue.
74
+
However, we insisted that there was a problem with the `ssa` package. On the one hand, the above SSA code is not long, and its execution logic is not difficult to reason about; more importantly, we found that when the `Interpret()` function of the `ssa/interp` package was used to interpret the above SSA code, `y` was still incorrectly assigned to a nil value, and the printed result was no different from the output of the Wa version! So we submitted these evidence, hoping to reopen the issue.
75
75
76
76
## 4. Turning point
77
77
@@ -86,7 +86,7 @@ The problem is here:
86
86
...
87
87
```
88
88
89
-
There are two ϕ-nodes in Block 3. According to the **conventional logic** mentioned earlier, we think the result of the first phi is the input parameter of the second one, and there is a sequence relationship between the execution of the instructions. However, when generating phis, it is based on such an assumption that "**Phis in the same Block are executed in parallel**". That is, `t6` in `phi [0: t1, 1: t6]` should take its value before entering Block 3, rather than the return value of `phi [0: t1, 1: t4]`. According to this assumption, the value of `t7` (i.e. y) is `t6` (i.e. x) of the previous iteration, and the logic is consistent with the intention of the source code. Coincidentally, the Wa-lang compiler and `ssa/interp` made the same mistake - processing phis in serial.
89
+
There are two ϕ-nodes in Block 3. According to the **conventional logic** mentioned earlier, we think the result of the first phi is the input parameter of the second one, and there is a sequence relationship between the execution of the instructions. However, when generating phis, it is based on such an assumption that "**Phis in the same Block are executed in parallel**". That is, `t6` in `phi [0: t1, 1: t6]` should take its value before entering Block 3, rather than the return value of `phi [0: t1, 1: t4]`. According to this assumption, the value of `t7` (i.e. y) is `t6` (i.e. x) of the previous iteration, and the logic is consistent with the intention of the source code. Coincidentally, the Wa compiler and `ssa/interp` made the same mistake - processing phis in serial.
90
90
91
91
In fact, in previous private discussions, we did consider the possibility that "ϕ-nodes should be executed in parallel":
92
92
@@ -100,7 +100,7 @@ But the fact that the `interp` package has problems is beyond our expectation.
100
100
Alan Donovan promptly submitted a fix to the `ssa/interp` package:
We also made a fix to the handling of ϕ-nodes in the Wa-lang: [https://github.com/wa-lang/wa/commit/8138ee420dac88463515328b1edaef99eda43974](https://github.com/wa-lang/wa/commit/8138ee420dac88463515328b1edaef99eda43974).
103
+
We also made a fix to the handling of ϕ-nodes in the Wa: [https://github.com/wa-lang/wa/commit/8138ee420dac88463515328b1edaef99eda43974](https://github.com/wa-lang/wa/commit/8138ee420dac88463515328b1edaef99eda43974).
104
104
105
105
The test results are correct, so this problem is solved.
0 commit comments