Skip to content

Commit 255700e

Browse files
committed
Increase precision in InferMutableRangesForAlias
Previously, this step just set the mutable range of any alias set including any mutation to the end of the last mutable range of any of the containing identifiers. This change makes it so that the ends are only updated of the ranges that end before the last mutation. Fixes #852
1 parent 748992d commit 255700e

File tree

10 files changed

+220
-138
lines changed

10 files changed

+220
-138
lines changed

compiler/forget/src/HIR/InferMutableRangesForAlias.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,25 @@ export function inferMutableRangesForAlias(aliases: DisjointSet<Identifier>) {
77
for (const aliasSet of aliasSets) {
88
// Update mutableRange.end only if the identifiers have actually been
99
// mutated.
10-
const haveIdentifiersBeenMutated = [...aliasSet].some(
10+
const mutatingIdentifiers = [...aliasSet].filter(
1111
(id) => id.mutableRange.end - id.mutableRange.start > 1
1212
);
1313

14-
if (haveIdentifiersBeenMutated) {
14+
if (mutatingIdentifiers.length > 0) {
1515
// Find final instruction which mutates this alias set.
16-
const mutableRangeEnds = [...aliasSet].map((id) => id.mutableRange.end);
17-
const maxMutableRangeEnd = Math.max(...mutableRangeEnds) as InstructionId;
16+
let lastMutatingInstructionId = 0;
17+
for (const id of mutatingIdentifiers) {
18+
if (id.mutableRange.end > lastMutatingInstructionId) {
19+
lastMutatingInstructionId = id.mutableRange.end;
20+
}
21+
}
1822

19-
// Update mutableRange.end for all aliases in this set.
23+
// Update mutableRange.end for all aliases in this set ending before the
24+
// last mutation.
2025
for (const alias of aliasSet) {
21-
alias.mutableRange.end = maxMutableRangeEnd;
26+
if (alias.mutableRange.end < lastMutatingInstructionId) {
27+
alias.mutableRange.end = lastMutatingInstructionId as InstructionId;
28+
}
2229
}
2330
}
2431
}

compiler/forget/src/__tests__/fixtures/hir/component.expect.md

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function Component(props) {
3737
bb0:
3838
[1] Const mutate items$27_@0 = read props$26.items
3939
[2] Const mutate maxItems$28_@1 = read props$26.maxItems
40-
[3] Const mutate renderedItems$29_@2[3:26] = Array []
40+
[3] Const mutate renderedItems$29_@2[3:22] = Array []
4141
[4] Const mutate seen$30_@3[0:19] = New mutate Set$6_@3()
4242
[5] Const mutate $31_@4 = 0
4343
[6] Const mutate max$32_@5[0:7] = Call mutate [email protected](read $31_@4, read maxItems$28_@1)
@@ -71,23 +71,23 @@ bb4:
7171
[19] Const mutate $43_@7 = "div"
7272
[20] Const mutate $44_@8 = JSX <read $43_@7>{read item$10_@3}</read $43_@7>
7373
[21] Call mutate [email protected](read $44_@8)
74-
[22] Const mutate $49_@2[3:26] = Binary read [email protected] >= read max$32_@5
75-
[23] If (read $49_@2) then:bb2 else:bb10 fallthrough=bb10
74+
[22] Const mutate $49_@9 = Binary read [email protected] >= read max$32_@5
75+
[23] If (read $49_@9) then:bb2 else:bb10 fallthrough=bb10
7676
bb10:
7777
predecessor blocks: bb4
7878
[24] Goto(Continue) bb1
7979
bb2:
8080
predecessor blocks: bb4 bb1
81-
[25] Const mutate count$52_@2[3:26] = read [email protected]
82-
[26] Const mutate $53_@9 = "div"
83-
[27] Const mutate $54_@10 = "\n "
84-
[28] Const mutate $55_@11 = "h1"
85-
[29] Const mutate $56_@12 = " Items"
86-
[30] Const mutate $57_@13 = JSX <read $55_@11>{freeze count$52_@2}{read $56_@12}</read $55_@11>
87-
[31] Const mutate $58_@14 = "\n "
88-
[32] Const mutate $59_@15 = "\n "
89-
[33] Const mutate $60_@16 = JSX <read $53_@9>{read $54_@10}{read $57_@13}{read $58_@14}{freeze renderedItems$29_@2}{read $59_@15}</read $53_@9>
90-
[34] Return read $60_@16
81+
[25] Const mutate count$52_@10 = read [email protected]
82+
[26] Const mutate $53_@11 = "div"
83+
[27] Const mutate $54_@12 = "\n "
84+
[28] Const mutate $55_@13 = "h1"
85+
[29] Const mutate $56_@14 = " Items"
86+
[30] Const mutate $57_@15 = JSX <read $55_@13>{freeze count$52_@10}{read $56_@14}</read $55_@13>
87+
[31] Const mutate $58_@16 = "\n "
88+
[32] Const mutate $59_@17 = "\n "
89+
[33] Const mutate $60_@18 = JSX <read $53_@11>{read $54_@12}{read $57_@15}{read $58_@16}{freeze renderedItems$29_@2}{read $59_@17}</read $53_@11>
90+
[34] Return read $60_@18
9191
scope0 [1:2]:
9292
- read props$26.items
9393
scope1 [2:3]:
@@ -103,7 +103,7 @@ flowchart TB
103103
bb0_instrs["
104104
[1] Const mutate items$27_@0 = read props$26.items
105105
[2] Const mutate maxItems$28_@1 = read props$26.maxItems
106-
[3] Const mutate renderedItems$29_@2[3:26] = Array []
106+
[3] Const mutate renderedItems$29_@2[3:22] = Array []
107107
[4] Const mutate seen$30_@3[0:19] = New mutate Set$6_@3()
108108
[5] Const mutate $31_@4 = 0
109109
[6] Const mutate max$32_@5[0:7] = Call mutate [email protected](read $31_@4, read maxItems$28_@1)
@@ -145,26 +145,26 @@ flowchart TB
145145
[19] Const mutate $43_@7 = 'div'
146146
[20] Const mutate $44_@8 = JSX <read $43_@7>{read item$10_@3}</read $43_@7>
147147
[21] Call mutate [email protected](read $44_@8)
148-
[22] Const mutate $49_@2[3:26] = Binary read [email protected] >= read max$32_@5
148+
[22] Const mutate $49_@9 = Binary read [email protected] >= read max$32_@5
149149
"]
150-
bb4_instrs --> bb4_terminal(["If (read $49_@2)"])
150+
bb4_instrs --> bb4_terminal(["If (read $49_@9)"])
151151
end
152152
subgraph bb10
153153
bb10_terminal(["Goto"])
154154
end
155155
subgraph bb2
156156
bb2_instrs["
157-
[25] Const mutate count$52_@2[3:26] = read [email protected]
158-
[26] Const mutate $53_@9 = 'div'
159-
[27] Const mutate $54_@10 = '\n '
160-
[28] Const mutate $55_@11 = 'h1'
161-
[29] Const mutate $56_@12 = ' Items'
162-
[30] Const mutate $57_@13 = JSX <read $55_@11>{freeze count$52_@2}{read $56_@12}</read $55_@11>
163-
[31] Const mutate $58_@14 = '\n '
164-
[32] Const mutate $59_@15 = '\n '
165-
[33] Const mutate $60_@16 = JSX <read $53_@9>{read $54_@10}{read $57_@13}{read $58_@14}{freeze renderedItems$29_@2}{read $59_@15}</read $53_@9>
157+
[25] Const mutate count$52_@10 = read [email protected]
158+
[26] Const mutate $53_@11 = 'div'
159+
[27] Const mutate $54_@12 = '\n '
160+
[28] Const mutate $55_@13 = 'h1'
161+
[29] Const mutate $56_@14 = ' Items'
162+
[30] Const mutate $57_@15 = JSX <read $55_@13>{freeze count$52_@10}{read $56_@14}</read $55_@13>
163+
[31] Const mutate $58_@16 = '\n '
164+
[32] Const mutate $59_@17 = '\n '
165+
[33] Const mutate $60_@18 = JSX <read $53_@11>{read $54_@12}{read $57_@15}{read $58_@16}{freeze renderedItems$29_@2}{read $59_@17}</read $53_@11>
166166
"]
167-
bb2_instrs --> bb2_terminal(["Return read $60_@16"])
167+
bb2_instrs --> bb2_terminal(["Return read $60_@18"])
168168
end
169169
170170
%% Jumps
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
2+
## Input
3+
4+
```javascript
5+
function Component(c) {
6+
let x = { c };
7+
mutate(x);
8+
let a = x;
9+
let b = a;
10+
}
11+
12+
```
13+
14+
## HIR
15+
16+
```
17+
bb0:
18+
[1] Const mutate x$7_@0[0:3] = Object { c: read c$6 }
19+
[2] Call mutate mutate$3_@0(mutate x$7_@0)
20+
[3] Const mutate a$8_@1 = read x$7_@0
21+
[4] Const mutate b$9_@2 = read a$8_@1
22+
[5] Return
23+
scope1 [3:4]:
24+
- read x$7_@0
25+
scope2 [4:5]:
26+
- read a$8_@1
27+
```
28+
29+
### CFG
30+
31+
```mermaid
32+
flowchart TB
33+
%% Basic Blocks
34+
subgraph bb0
35+
bb0_instrs["
36+
[1] Const mutate x$7_@0[0:3] = Object { c: read c$6 }
37+
[2] Call mutate mutate$3_@0(mutate x$7_@0)
38+
[3] Const mutate a$8_@1 = read x$7_@0
39+
[4] Const mutate b$9_@2 = read a$8_@1
40+
"]
41+
bb0_instrs --> bb0_terminal(["Return"])
42+
end
43+
44+
%% Jumps
45+
%% empty
46+
```
47+
48+
## Code
49+
50+
```javascript
51+
function Component$0(c$6) {
52+
const x$7 = {
53+
c: c$6,
54+
};
55+
mutate$3(x$7);
56+
const a$8 = x$7;
57+
const b$9 = a$8;
58+
}
59+
60+
```
61+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function Component(c) {
2+
let x = { c };
3+
mutate(x);
4+
let a = x;
5+
let b = a;
6+
}

compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ function foo() {
2121

2222
```
2323
bb0:
24-
[1] Let mutate x$7_@0[1:14] = 1
24+
[1] Let mutate x$7_@0[1:13] = 1
2525
[2] Const mutate y$8_@1 = 2
2626
[3] Const mutate $9_@2 = 2
2727
[4] Const mutate $10_@3 = Binary read y$8_@1 === read $9_@2
2828
[5] If (read $10_@3) then:bb2 else:bb1 fallthrough=bb1
2929
bb2:
3030
predecessor blocks: bb0
31-
[6] Reassign mutate x$7_@0[1:14] = 3
31+
[6] Reassign mutate x$7_@0[1:13] = 3
3232
[7] Goto bb1
3333
bb1:
3434
predecessor blocks: bb2 bb0
@@ -37,18 +37,20 @@ bb1:
3737
[10] If (read $14_@5) then:bb4 else:bb3 fallthrough=bb3
3838
bb4:
3939
predecessor blocks: bb1
40-
[11] Reassign mutate x$7_@0[1:14] = 5
40+
[11] Reassign mutate x$7_@0[1:13] = 5
4141
[12] Goto bb3
4242
bb3:
4343
predecessor blocks: bb4 bb1
44-
[13] Const mutate y$18_@0[1:14] = read x$7_@0
44+
[13] Const mutate y$18_@6 = read x$7_@0
4545
[14] Return
4646
scope3 [4:5]:
4747
- read y$8_@1
4848
- read $9_@2
4949
scope5 [9:10]:
5050
- read y$8_@1
5151
- read $12_@4
52+
scope6 [13:14]:
53+
- read x$7_@0
5254
```
5355

5456
### CFG
@@ -58,7 +60,7 @@ flowchart TB
5860
%% Basic Blocks
5961
subgraph bb0
6062
bb0_instrs["
61-
[1] Let mutate x$7_@0[1:14] = 1
63+
[1] Let mutate x$7_@0[1:13] = 1
6264
[2] Const mutate y$8_@1 = 2
6365
[3] Const mutate $9_@2 = 2
6466
[4] Const mutate $10_@3 = Binary read y$8_@1 === read $9_@2
@@ -67,7 +69,7 @@ flowchart TB
6769
end
6870
subgraph bb2
6971
bb2_instrs["
70-
[6] Reassign mutate x$7_@0[1:14] = 3
72+
[6] Reassign mutate x$7_@0[1:13] = 3
7173
"]
7274
bb2_instrs --> bb2_terminal(["Goto"])
7375
end
@@ -80,13 +82,13 @@ flowchart TB
8082
end
8183
subgraph bb4
8284
bb4_instrs["
83-
[11] Reassign mutate x$7_@0[1:14] = 5
85+
[11] Reassign mutate x$7_@0[1:13] = 5
8486
"]
8587
bb4_instrs --> bb4_terminal(["Goto"])
8688
end
8789
subgraph bb3
8890
bb3_instrs["
89-
[13] Const mutate y$18_@0[1:14] = read x$7_@0
91+
[13] Const mutate y$18_@6 = read x$7_@0
9092
"]
9193
bb3_instrs --> bb3_terminal(["Return"])
9294
end

compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,24 @@ function foo() {
1818

1919
```
2020
bb0:
21-
[1] Let mutate x$5_@0[1:9] = 1
21+
[1] Let mutate x$5_@0[1:8] = 1
2222
[2] Const mutate y$6_@1 = 2
2323
[3] Const mutate $7_@2 = 2
2424
[4] Const mutate $8_@3 = Binary read y$6_@1 === read $7_@2
2525
[5] If (read $8_@3) then:bb2 else:bb1 fallthrough=bb1
2626
bb2:
2727
predecessor blocks: bb0
28-
[6] Reassign mutate x$5_@0[1:9] = 3
28+
[6] Reassign mutate x$5_@0[1:8] = 3
2929
[7] Goto bb1
3030
bb1:
3131
predecessor blocks: bb2 bb0
32-
[8] Const mutate y$11_@0[1:9] = read x$5_@0
32+
[8] Const mutate y$11_@4 = read x$5_@0
3333
[9] Return
3434
scope3 [4:5]:
3535
- read y$6_@1
3636
- read $7_@2
37+
scope4 [8:9]:
38+
- read x$5_@0
3739
```
3840

3941
### CFG
@@ -43,7 +45,7 @@ flowchart TB
4345
%% Basic Blocks
4446
subgraph bb0
4547
bb0_instrs["
46-
[1] Let mutate x$5_@0[1:9] = 1
48+
[1] Let mutate x$5_@0[1:8] = 1
4749
[2] Const mutate y$6_@1 = 2
4850
[3] Const mutate $7_@2 = 2
4951
[4] Const mutate $8_@3 = Binary read y$6_@1 === read $7_@2
@@ -52,13 +54,13 @@ flowchart TB
5254
end
5355
subgraph bb2
5456
bb2_instrs["
55-
[6] Reassign mutate x$5_@0[1:9] = 3
57+
[6] Reassign mutate x$5_@0[1:8] = 3
5658
"]
5759
bb2_instrs --> bb2_terminal(["Goto"])
5860
end
5961
subgraph bb1
6062
bb1_instrs["
61-
[8] Const mutate y$11_@0[1:9] = read x$5_@0
63+
[8] Const mutate y$11_@4 = read x$5_@0
6264
"]
6365
bb1_instrs --> bb1_terminal(["Return"])
6466
end

compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,27 @@ bb0:
2323
[1] Const mutate y$5_@0 = 2
2424
[2] Const mutate $6_@1 = 1
2525
[3] Const mutate $7_@2 = Binary read y$5_@0 > read $6_@1
26-
[4] Let mutate y$8_@3[4:10] = undefined
26+
[4] Let mutate y$8_@3[4:9] = undefined
2727
[4] If (read $7_@2) then:bb2 else:bb3 fallthrough=bb1
2828
bb2:
2929
predecessor blocks: bb0
30-
[5] Reassign mutate y$8_@3[4:10] = 1
30+
[5] Reassign mutate y$8_@3[4:9] = 1
3131
[6] Goto bb1
3232
bb3:
3333
predecessor blocks: bb0
34-
[7] Reassign mutate y$8_@3[4:10] = 2
34+
[7] Reassign mutate y$8_@3[4:9] = 2
3535
[8] Goto bb1
3636
bb1:
3737
predecessor blocks: bb2 bb3
38-
[9] Const mutate x$11_@3[4:10] = read y$8_@3
38+
[9] Const mutate x$11_@4 = read y$8_@3
3939
[10] Return
4040
scope2 [3:4]:
4141
- read y$5_@0
4242
- read $6_@1
43-
scope3 [4:10]:
43+
scope3 [4:9]:
4444
- read $7_@2
45+
scope4 [9:10]:
46+
- read y$8_@3
4547
```
4648

4749
### CFG
@@ -54,25 +56,25 @@ flowchart TB
5456
[1] Const mutate y$5_@0 = 2
5557
[2] Const mutate $6_@1 = 1
5658
[3] Const mutate $7_@2 = Binary read y$5_@0 > read $6_@1
57-
[4] Let mutate y$8_@3[4:10] = undefined
59+
[4] Let mutate y$8_@3[4:9] = undefined
5860
"]
5961
bb0_instrs --> bb0_terminal(["If (read $7_@2)"])
6062
end
6163
subgraph bb2
6264
bb2_instrs["
63-
[5] Reassign mutate y$8_@3[4:10] = 1
65+
[5] Reassign mutate y$8_@3[4:9] = 1
6466
"]
6567
bb2_instrs --> bb2_terminal(["Goto"])
6668
end
6769
subgraph bb3
6870
bb3_instrs["
69-
[7] Reassign mutate y$8_@3[4:10] = 2
71+
[7] Reassign mutate y$8_@3[4:9] = 2
7072
"]
7173
bb3_instrs --> bb3_terminal(["Goto"])
7274
end
7375
subgraph bb1
7476
bb1_instrs["
75-
[9] Const mutate x$11_@3[4:10] = read y$8_@3
77+
[9] Const mutate x$11_@4 = read y$8_@3
7678
"]
7779
bb1_instrs --> bb1_terminal(["Return"])
7880
end

0 commit comments

Comments
 (0)