Use implicit return (undefined)
Making ReturnTerminal.value non-nullable broke our optimization to elide final value-less return statements. We now check if a return value is explicitly `undefined` and elide the value in this case, which then also propagates to allow removing the final `return` statement of a function if the value is missing.
Joe Savona committed
Apr 18, 2023 at 11:12 UTC
de89ed32a2b649ad542a4f3387312aa3c171d3a7
51 files changed
+82
-158
compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+4
@@ -388,6 +388,10 @@ function codegenTerminal(
388
}
389
case "return": {
390
const value = codegenPlace(cx, terminal.value);
391
+ if (value.type === "Identifier" && value.name === "undefined") {
392
+ // Use implicit undefined
393
+ return t.returnStatement();
394
+ }
395
return t.returnStatement(value);
396
}
397
case "switch": {
compiler/forget/src/__tests__/fixtures/compiler/_bug.computed-call-evaluation-order.expect.md
-1
@@ -26,7 +26,6 @@ function Component() {
26
import * as React from "react"; // Should print A, B, arg, original
27
function changeF(o) {
28
o.f = () => console.log("new");
29
- return undefined;
29
}
30
31
function Component() {
compiler/forget/src/__tests__/fixtures/compiler/_bug.property-call-evaluation-order.expect.md
-1
@@ -26,7 +26,6 @@ import * as React from "react"; // Should print A, arg, original
26
27
function changeF(o) {
28
o.f = () => console.log("new");
29
- return undefined;
29
}
30
31
function Component() {
compiler/forget/src/__tests__/fixtures/compiler/alias-while.expect.md
+1
-3
@@ -50,9 +50,7 @@ function foo(cond) {
50
return a;
51
}
52
53
-function mutate(x, y) {
54
- return undefined;
55
-}
53
+function mutate(x, y) {}
54
55
```
56
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/call.expect.md
+1
-3
@@ -19,9 +19,7 @@ function Component(props) {
19
20
```javascript
21
import * as React from "react";
22
-function foo() {
23
- return undefined;
24
-}
22
+function foo() {}
23
24
function Component(props) {
25
const $ = React.unstable_useMemoCache(3);
compiler/forget/src/__tests__/fixtures/compiler/conditional-on-mutable.expect.md
+2
-6
@@ -105,12 +105,8 @@ function ComponentB(props) {
105
return t0;
106
}
107
108
-function Foo() {
109
- return undefined;
110
-}
111
-function mayMutate() {
112
- return undefined;
113
-}
108
+function Foo() {}
109
+function mayMutate() {}
110
111
```
112
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/constructor.expect.md
+1
-3
@@ -19,9 +19,7 @@ function Component(props) {
19
20
```javascript
21
import * as React from "react";
22
-function Foo() {
23
- return undefined;
24
-}
22
+function Foo() {}
23
24
function Component(props) {
25
const $ = React.unstable_useMemoCache(3);
compiler/forget/src/__tests__/fixtures/compiler/early-return.expect.md
+2
-2
@@ -18,9 +18,9 @@ function MyApp(props) {
18
```javascript
19
function MyApp(props) {
20
if (props.cond) {
21
- return undefined;
21
+ return;
22
} else {
23
- return undefined;
23
+ return;
24
}
25
}
26
compiler/forget/src/__tests__/fixtures/compiler/for-return.expect.md
+1
-2
@@ -15,9 +15,8 @@ function Component(props) {
15
```javascript
16
function Component(props) {
17
for (const i = 0; 0 < props.count; ) {
18
- return undefined;
18
+ return;
19
}
20
- return undefined;
20
}
21
22
```
compiler/forget/src/__tests__/fixtures/compiler/frozen-after-alias.expect.md
+2
-6
@@ -35,12 +35,8 @@ function Component() {
35
return b;
36
}
37
38
-function useFreeze() {
39
- return undefined;
40
-}
41
-function foo(x) {
42
- return undefined;
43
-}
38
+function useFreeze() {}
39
+function foo(x) {}
40
41
```
42
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/hook-call.expect.md
+2
-6
@@ -23,12 +23,8 @@ function Component(props) {
23
24
```javascript
25
import * as React from "react";
26
-function useFreeze() {
27
- return undefined;
28
-}
29
-function foo() {
30
- return undefined;
31
-}
26
+function useFreeze() {}
27
+function foo() {}
28
29
function Component(props) {
30
const $ = React.unstable_useMemoCache(3);
compiler/forget/src/__tests__/fixtures/compiler/hooks-freeze-arguments.expect.md
+2
-6
@@ -35,12 +35,8 @@ function Component() {
35
return a;
36
}
37
38
-function useFreeze(x) {
39
- return undefined;
40
-}
41
-function call(x) {
42
- return undefined;
43
-}
38
+function useFreeze(x) {}
39
+function call(x) {}
40
41
```
42
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/hooks-freeze-possibly-mutable-arguments.expect.md
+2
-6
@@ -50,12 +50,8 @@ function Component(props) {
50
return a;
51
}
52
53
-function useFreeze(x) {
54
- return undefined;
55
-}
56
-function call(x) {
57
- return undefined;
58
-}
53
+function useFreeze(x) {}
54
+function call(x) {}
55
56
```
57
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/independent-across-if.expect.md
+4
-12
@@ -37,18 +37,10 @@ function Component(props) {
37
38
```javascript
39
import * as React from "react";
40
-function compute() {
41
- return undefined;
42
-}
43
-function mutate() {
44
- return undefined;
45
-}
46
-function foo() {
47
- return undefined;
48
-}
49
-function Foo() {
50
- return undefined;
51
-}
40
+function compute() {}
41
+function mutate() {}
42
+function foo() {}
43
+function Foo() {}
44
45
/**
46
* Should produce 3 scopes:
compiler/forget/src/__tests__/fixtures/compiler/independent.expect.md
+3
-9
@@ -74,15 +74,9 @@ function Component(props) {
74
return t2;
75
}
76
77
-function compute() {
78
- return undefined;
79
-}
80
-function foo() {
81
- return undefined;
82
-}
83
-function Foo() {
84
- return undefined;
85
-}
77
+function compute() {}
78
+function foo() {}
79
+function Foo() {}
80
81
```
82
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/interdependent-across-if.expect.md
+3
-9
@@ -31,15 +31,9 @@ function Component(props) {
31
32
```javascript
33
import * as React from "react";
34
-function compute() {
35
- return undefined;
36
-}
37
-function foo() {
38
- return undefined;
39
-}
40
-function Foo() {
41
- return undefined;
42
-}
34
+function compute() {}
35
+function foo() {}
36
+function Foo() {}
37
38
/**
39
* Should produce 1 scope:
compiler/forget/src/__tests__/fixtures/compiler/interdependent.expect.md
+3
-9
@@ -69,15 +69,9 @@ function Component(props) {
69
return t0;
70
}
71
72
-function compute() {
73
- return undefined;
74
-}
75
-function foo() {
76
- return undefined;
77
-}
78
-function Foo() {
79
- return undefined;
80
-}
72
+function compute() {}
73
+function foo() {}
74
+function Foo() {}
75
76
```
77
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/issue852.expect.md
-1
@@ -17,7 +17,6 @@ function Component(c) {
17
function Component(c) {
18
const x = { c };
19
mutate(x);
20
- return undefined;
20
}
21
22
```
compiler/forget/src/__tests__/fixtures/compiler/mutable-lifetime-loops.expect.md
+2
-7
@@ -42,12 +42,8 @@ function Component(props) {
42
## Code
43
44
```javascript
45
-function mutate(x, y) {
46
- return undefined;
47
-}
48
-function cond(x) {
49
- return undefined;
50
-}
45
+function mutate(x, y) {}
46
+function cond(x) {}
47
48
function Component(props) {
49
let a = {};
@@ -75,7 +71,6 @@ function Component(props) {
71
}
72
73
mutate(d, null);
78
- return undefined;
74
}
75
76
```
compiler/forget/src/__tests__/fixtures/compiler/mutable-lifetime-with-aliasing.expect.md
+1
-4
@@ -38,9 +38,7 @@ function Component(props) {
38
## Code
39
40
```javascript
41
-function mutate(x, y) {
42
- return undefined;
43
-}
41
+function mutate(x, y) {}
42
43
function Component(props) {
44
const a = {};
@@ -63,7 +61,6 @@ function Component(props) {
61
}
62
63
mutate(x, null);
66
- return undefined;
64
}
65
66
```
compiler/forget/src/__tests__/fixtures/compiler/mutable-liverange-loop.expect.md
+2
-7
@@ -37,12 +37,8 @@ function Component(props) {
37
## Code
38
39
```javascript
40
-function mutate() {
41
- return undefined;
42
-}
43
-function cond() {
44
- return undefined;
45
-}
40
+function mutate() {}
41
+function cond() {}
42
43
function Component(props) {
44
const a = {};
@@ -65,7 +61,6 @@ function Component(props) {
61
}
62
63
mutate(d, null);
68
- return undefined;
64
}
65
66
```
compiler/forget/src/__tests__/fixtures/compiler/object-computed-access-assignment.expect.md
-1
@@ -15,7 +15,6 @@ function foo(a, b, c) {
15
function foo(a, b, c) {
16
a[b] = c[b];
17
a[3] = c[b * 4];
18
- return undefined;
18
}
19
20
```
compiler/forget/src/__tests__/fixtures/compiler/object-properties.expect.md
-1
@@ -19,7 +19,6 @@ function foo(a, b, c) {
19
const y = b.c.d;
20
y.z = c.d.e;
21
foo(a.b.c);
22
- return undefined;
22
}
23
24
```
compiler/forget/src/__tests__/fixtures/compiler/overlapping-scopes-interleaved-by-terminal.expect.md
-1
@@ -26,7 +26,6 @@ function foo(a, b, c) {
26
27
y.push(a);
28
x.push(b);
29
- return undefined;
29
}
30
31
```
compiler/forget/src/__tests__/fixtures/compiler/overlapping-scopes-interleaved.expect.md
-1
@@ -19,7 +19,6 @@ function foo(a, b) {
19
const y = [];
20
x.push(a);
21
y.push(b);
22
- return undefined;
22
}
23
24
```
compiler/forget/src/__tests__/fixtures/compiler/overlapping-scopes-shadowed.expect.md
-1
@@ -19,7 +19,6 @@ function foo(a, b) {
19
const y = [];
20
y.push(b);
21
x.push(a);
22
- return undefined;
22
}
23
24
```
compiler/forget/src/__tests__/fixtures/compiler/overlapping-scopes-while.expect.md
-1
@@ -23,7 +23,6 @@ function foo(a, b, c) {
23
y.push(b);
24
x.push(a);
25
}
26
- return undefined;
26
}
27
28
```
compiler/forget/src/__tests__/fixtures/compiler/return-undefined.expect.md
new
+25
@@ -0,0 +1,25 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+function Component(props) {
6
+ if (props.cond) {
7
+ return undefined;
8
+ }
9
+ return props.value;
10
+}
11
+
12
+```
13
+
14
+## Code
15
+
16
+```javascript
17
+function Component(props) {
18
+ if (props.cond) {
19
+ return;
20
+ }
21
+ return props.value;
22
+}
23
+
24
+```
25
+
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/return-undefined.js
new
+6
@@ -0,0 +1,6 @@
1
+function Component(props) {
2
+ if (props.cond) {
3
+ return undefined;
4
+ }
5
+ return props.value;
6
+}
compiler/forget/src/__tests__/fixtures/compiler/reverse-postorder.expect.md
-1
@@ -54,7 +54,6 @@ function Component(props) {
54
} else {
55
}
56
}
57
- return undefined;
57
}
58
59
```
compiler/forget/src/__tests__/fixtures/compiler/sequence-expression.expect.md
+1
-3
@@ -42,9 +42,7 @@ function sequence(props) {
42
return x;
43
}
44
45
-function foo() {
46
- return undefined;
47
-}
45
+function foo() {}
46
47
```
48
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/simple-alias.expect.md
+1
-3
@@ -20,9 +20,7 @@ function foo() {
20
21
```javascript
22
import * as React from "react";
23
-function mutate() {
24
- return undefined;
25
-}
23
+function mutate() {}
24
function foo() {
25
const $ = React.unstable_useMemoCache(1);
26
let c;
compiler/forget/src/__tests__/fixtures/compiler/ssa-call-jsx-2.expect.md
+1
-3
@@ -22,9 +22,7 @@ function Component(props) {
22
23
```javascript
24
import * as React from "react"; // @Pass runMutableRangeAnalysis
25
-function foo() {
26
- return undefined;
27
-}
25
+function foo() {}
26
27
function Component(props) {
28
const $ = React.unstable_useMemoCache(3);
compiler/forget/src/__tests__/fixtures/compiler/ssa-call-jsx.expect.md
+1
-3
@@ -19,9 +19,7 @@ function Component(props) {
19
20
```javascript
21
import * as React from "react";
22
-function foo() {
23
- return undefined;
24
-}
22
+function foo() {}
23
24
function Component(props) {
25
const $ = React.unstable_useMemoCache(3);
compiler/forget/src/__tests__/fixtures/compiler/ssa-complex-multiple-if.expect.md
+1
-3
@@ -20,9 +20,7 @@ function foo() {
20
## Code
21
22
```javascript
23
-function foo() {
24
- return undefined;
25
-}
23
+function foo() {}
24
25
```
26
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/ssa-complex-single-if.expect.md
+1
-3
@@ -17,9 +17,7 @@ function foo() {
17
## Code
18
19
```javascript
20
-function foo() {
21
- return undefined;
22
-}
20
+function foo() {}
21
22
```
23
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/ssa-if-else.expect.md
+1
-3
@@ -18,9 +18,7 @@ function foo() {
18
## Code
19
20
```javascript
21
-function foo() {
22
- return undefined;
23
-}
21
+function foo() {}
22
23
```
24
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/ssa-nested-partial-phi.expect.md
-1
@@ -26,7 +26,6 @@ function foo(a, b, c) {
26
}
27
return x;
28
}
29
- return undefined;
29
}
30
31
```
compiler/forget/src/__tests__/fixtures/compiler/ssa-newexpression.expect.md
+1
-3
@@ -17,9 +17,7 @@ function Component(props) {
17
18
```javascript
19
import * as React from "react";
20
-function Foo() {
21
- return undefined;
22
-}
20
+function Foo() {}
21
22
function Component(props) {
23
const $ = React.unstable_useMemoCache(1);
compiler/forget/src/__tests__/fixtures/compiler/ssa-shadowing.expect.md
+1
-4
@@ -20,9 +20,7 @@ function Foo(cond) {
20
## Code
21
22
```javascript
23
-function log() {
24
- return undefined;
25
-}
23
+function log() {}
24
25
function Foo(cond) {
26
let str = "";
@@ -33,7 +31,6 @@ function Foo(cond) {
31
}
32
33
log(str);
36
- return undefined;
34
}
35
36
```
compiler/forget/src/__tests__/fixtures/compiler/ssa-sibling-phis.expect.md
+1
-3
@@ -27,9 +27,7 @@ function foo(a, b, c, d) {
27
## Code
28
29
```javascript
30
-function foo(a, b, c, d) {
31
- return undefined;
32
-}
30
+function foo(a, b, c, d) {}
31
32
```
33
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/ssa-simple-phi.expect.md
+1
-3
@@ -19,9 +19,7 @@ function foo() {
19
## Code
20
21
```javascript
22
-function foo() {
23
- return undefined;
24
-}
22
+function foo() {}
23
24
```
25
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/ssa-simple.expect.md
+1
-3
@@ -12,9 +12,7 @@ function foo() {
12
## Code
13
14
```javascript
15
-function foo() {
16
- return undefined;
17
-}
15
+function foo() {}
16
17
```
18
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/ssa-single-if.expect.md
+1
-3
@@ -16,9 +16,7 @@ function foo() {
16
## Code
17
18
```javascript
19
-function foo() {
20
- return undefined;
21
-}
19
+function foo() {}
20
21
```
22
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/ssa-switch.expect.md
-1
@@ -38,7 +38,6 @@ function foo() {
38
default: {
39
}
40
}
41
- return undefined;
41
}
42
43
```
compiler/forget/src/__tests__/fixtures/compiler/switch-with-fallthrough.expect.md
-1
@@ -55,7 +55,6 @@ function foo(x) {
55
default: {
56
}
57
}
58
- return undefined;
58
}
59
60
```
compiler/forget/src/__tests__/fixtures/compiler/transitive-alias-fields.expect.md
-1
@@ -31,7 +31,6 @@ function component() {
31
q.y = p.y;
32
33
mutate(q);
34
- return undefined;
34
}
35
36
```
compiler/forget/src/__tests__/fixtures/compiler/type-args-test-binary-operator.expect.md
-1
@@ -16,7 +16,6 @@ function component(a, b) {
16
function component(a, b) {
17
if (a > b) {
18
}
19
- return undefined;
19
}
20
21
```
compiler/forget/src/__tests__/fixtures/compiler/type-binary-operator.expect.md
-1
@@ -20,7 +20,6 @@ function component() {
20
const b = someOther();
21
if (a > b) {
22
}
23
- return undefined;
23
}
24
25
```
compiler/forget/src/__tests__/fixtures/compiler/useMemo-return-empty.expect.md
-1
@@ -18,7 +18,6 @@ function component(a) {
18
// @inlineUseMemo
19
function component(a) {
20
mutate(a);
21
- return undefined;
21
}
22
23
```
compiler/forget/src/__tests__/fixtures/compiler/while-conditional-continue.expect.md
-1
@@ -28,7 +28,6 @@ function foo(a, b, c, d) {
28
}
29
30
d();
31
- return undefined;
31
}
32
33
```