[hir] Run mutable range analysis for aliases to fix point
Sathya Gunasekaran committed
Dec 12, 2022 at 20:35 UTC
3c976a24b3eb25557e69448416015486dd75c0b8
8 files changed
+245
-7
compiler/forget/src/HIR/DisjointSet.ts
+4
@@ -83,4 +83,8 @@ export default class DisjointSet<T> {
83
fn(item, group);
84
}
85
}
86
+
87
+ get size(): number {
88
+ return this.#entries.size;
89
+ }
90
}
compiler/forget/src/HIR/InferMutableRanges.ts
+10
-7
@@ -5,17 +5,20 @@ import { inferMutableLifetimes } from "./InferMutableLifetimes";
5
import { inferMutableRangesForAlias } from "./InferMutableRangesForAlias";
6
7
export function inferMutableRanges(ir: HIRFunction) {
8
- // Calculate aliases
9
- const aliases = inferAliases(ir);
10
-
8
// Infer mutable ranges for non fields
9
inferMutableLifetimes(ir, false);
10
14
- // Infer mutable ranges for aliases that are not fields
15
- inferMutableRangesForAlias(aliases);
11
+ // Calculate aliases
12
+ const aliases = inferAliases(ir);
13
+ let size = aliases.size;
14
+ do {
15
+ size = aliases.size;
16
+ // Infer mutable ranges for aliases that are not fields
17
+ inferMutableRangesForAlias(aliases);
18
17
- // Update aliasing information of fields
18
- inferAliasForFields(ir, aliases);
19
+ // Update aliasing information of fields
20
+ inferAliasForFields(ir, aliases);
21
+ } while (aliases.size > size);
22
23
// Re-infer mutable ranges for all values
24
inferMutableLifetimes(ir, true);
compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path-mutate.expect.md
new
+64
@@ -0,0 +1,64 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+function component() {
6
+ let z = [];
7
+ let y = {};
8
+ y.z = z;
9
+ let x = {};
10
+ x.y = y;
11
+ mutate(x.y.z);
12
+}
13
+
14
+```
15
+
16
+## HIR
17
+
18
+```
19
+bb0:
20
+ [1] Const mutate z$5_@0[0:7] = Array []
21
+ [2] Const mutate y$6_@0[0:7] = Object { }
22
+ [3] Reassign mutate y$6_@0.z[0:7] = read z$5_@0
23
+ [4] Const mutate x$7_@0[0:7] = Object { }
24
+ [5] Reassign mutate x$7_@0.y[0:7] = read y$6_@0
25
+ [6] Call mutate mutate$4_@0(mutate x$7_@0.y.z)
26
+ [7] Return
27
+
28
+```
29
+
30
+### CFG
31
+
32
+```mermaid
33
+flowchart TB
34
+ %% Basic Blocks
35
+ subgraph bb0
36
+ bb0_instrs["
37
+ [1] Const mutate z$5_@0[0:7] = Array []
38
+ [2] Const mutate y$6_@0[0:7] = Object { }
39
+ [3] Reassign mutate y$6_@0.z[0:7] = read z$5_@0
40
+ [4] Const mutate x$7_@0[0:7] = Object { }
41
+ [5] Reassign mutate x$7_@0.y[0:7] = read y$6_@0
42
+ [6] Call mutate mutate$4_@0(mutate x$7_@0.y.z)
43
+ "]
44
+ bb0_instrs --> bb0_terminal(["Return"])
45
+ end
46
+
47
+ %% Jumps
48
+ %% empty
49
+```
50
+
51
+## Code
52
+
53
+```javascript
54
+function component$0() {
55
+ const z$5 = [];
56
+ const y$6 = {};
57
+ y$6.z = z$5;
58
+ const x$7 = {};
59
+ x$7.y = y$6;
60
+ mutate$4(x$7.y.z);
61
+}
62
+
63
+```
64
+
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path-mutate.js
new
+8
@@ -0,0 +1,8 @@
1
+function component() {
2
+ let z = [];
3
+ let y = {};
4
+ y.z = z;
5
+ let x = {};
6
+ x.y = y;
7
+ mutate(x.y.z);
8
+}
compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md
new
+65
@@ -0,0 +1,65 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+function component() {
6
+ let z = [];
7
+ let y = {};
8
+ y.z = z;
9
+ let x = {};
10
+ x.y = y;
11
+ return x;
12
+}
13
+
14
+```
15
+
16
+## HIR
17
+
18
+```
19
+bb0:
20
+ [1] Const mutate z$4_@0 = Array []
21
+ [2] Const mutate y$5_@1[2:4] = Object { }
22
+ [3] Reassign mutate y$5_@1.z[2:4] = read z$4_@0
23
+ [4] Const mutate x$6_@2[4:6] = Object { }
24
+ [5] Reassign mutate x$6_@2.y[4:6] = read y$5_@1
25
+ [6] Return freeze x$6_@2
26
+scope1 [2:4]:
27
+ - dependency: read z$4_@0
28
+scope2 [4:6]:
29
+ - dependency: read y$5_@1
30
+```
31
+
32
+### CFG
33
+
34
+```mermaid
35
+flowchart TB
36
+ %% Basic Blocks
37
+ subgraph bb0
38
+ bb0_instrs["
39
+ [1] Const mutate z$4_@0 = Array []
40
+ [2] Const mutate y$5_@1[2:4] = Object { }
41
+ [3] Reassign mutate y$5_@1.z[2:4] = read z$4_@0
42
+ [4] Const mutate x$6_@2[4:6] = Object { }
43
+ [5] Reassign mutate x$6_@2.y[4:6] = read y$5_@1
44
+ "]
45
+ bb0_instrs --> bb0_terminal(["Return freeze x$6_@2"])
46
+ end
47
+
48
+ %% Jumps
49
+ %% empty
50
+```
51
+
52
+## Code
53
+
54
+```javascript
55
+function component$0() {
56
+ const z$4 = [];
57
+ const y$5 = {};
58
+ y$5.z = z$4;
59
+ const x$6 = {};
60
+ x$6.y = y$5;
61
+ return x$6;
62
+}
63
+
64
+```
65
+
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.js
new
+8
@@ -0,0 +1,8 @@
1
+function component() {
2
+ let z = [];
3
+ let y = {};
4
+ y.z = z;
5
+ let x = {};
6
+ x.y = y;
7
+ return x;
8
+}
compiler/forget/src/__tests__/fixtures/hir/transitive-alias-fields.expect.md
new
+74
@@ -0,0 +1,74 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+function component() {
6
+ let x = {};
7
+ let p = {};
8
+ let q = {};
9
+ let y = {};
10
+
11
+ x.y = y;
12
+ p.y = x.y;
13
+ q.y = p.y;
14
+
15
+ mutate(q);
16
+}
17
+
18
+```
19
+
20
+## HIR
21
+
22
+```
23
+bb0:
24
+ [1] Const mutate x$6_@0[0:9] = Object { }
25
+ [2] Const mutate p$7_@0[0:9] = Object { }
26
+ [3] Const mutate q$8_@0[0:9] = Object { }
27
+ [4] Const mutate y$9_@0[0:9] = Object { }
28
+ [5] Reassign mutate x$6_@0.y[0:9] = read y$9_@0
29
+ [6] Reassign mutate p$7_@0.y[0:9] = read x$6_@0.y
30
+ [7] Reassign mutate q$8_@0.y[0:9] = read p$7_@0.y
31
+ [8] Call mutate mutate$5_@0(mutate q$8_@0)
32
+ [9] Return
33
+
34
+```
35
+
36
+### CFG
37
+
38
+```mermaid
39
+flowchart TB
40
+ %% Basic Blocks
41
+ subgraph bb0
42
+ bb0_instrs["
43
+ [1] Const mutate x$6_@0[0:9] = Object { }
44
+ [2] Const mutate p$7_@0[0:9] = Object { }
45
+ [3] Const mutate q$8_@0[0:9] = Object { }
46
+ [4] Const mutate y$9_@0[0:9] = Object { }
47
+ [5] Reassign mutate x$6_@0.y[0:9] = read y$9_@0
48
+ [6] Reassign mutate p$7_@0.y[0:9] = read x$6_@0.y
49
+ [7] Reassign mutate q$8_@0.y[0:9] = read p$7_@0.y
50
+ [8] Call mutate mutate$5_@0(mutate q$8_@0)
51
+ "]
52
+ bb0_instrs --> bb0_terminal(["Return"])
53
+ end
54
+
55
+ %% Jumps
56
+ %% empty
57
+```
58
+
59
+## Code
60
+
61
+```javascript
62
+function component$0() {
63
+ const x$6 = {};
64
+ const p$7 = {};
65
+ const q$8 = {};
66
+ const y$9 = {};
67
+ x$6.y = y$9;
68
+ p$7.y = x$6.y;
69
+ q$8.y = p$7.y;
70
+ mutate$5(q$8);
71
+}
72
+
73
+```
74
+
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/transitive-alias-fields.js
new
+12
@@ -0,0 +1,12 @@
1
+function component() {
2
+ let x = {};
3
+ let p = {};
4
+ let q = {};
5
+ let y = {};
6
+
7
+ x.y = y;
8
+ p.y = x.y;
9
+ q.y = p.y;
10
+
11
+ mutate(q);
12
+}