mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[hir] Handle simple aliases when inferring mutable lifetimes (#794)
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
|
||||
import invariant from "invariant";
|
||||
import { assertExhaustive } from "../Common/utils";
|
||||
import { Effect, HIRFunction, Instruction, Place } from "./HIR";
|
||||
import DisjointSet from "./DisjointSet";
|
||||
import { Effect, HIRFunction, Identifier, Instruction, Place } from "./HIR";
|
||||
import { printInstruction, printPlace } from "./PrintHIR";
|
||||
import { eachInstructionOperand } from "./visitors";
|
||||
|
||||
@@ -76,6 +77,8 @@ function inferPlace(place: Place, instr: Instruction) {
|
||||
}
|
||||
|
||||
export function inferMutableRanges(func: HIRFunction) {
|
||||
const aliases = new DisjointSet<Identifier>();
|
||||
|
||||
for (const [_, block] of func.body.blocks) {
|
||||
for (const phi of block.phis) {
|
||||
let start = Number.MAX_SAFE_INTEGER;
|
||||
@@ -100,6 +103,20 @@ export function inferMutableRanges(func: HIRFunction) {
|
||||
}
|
||||
|
||||
if (instr.lvalue !== null) {
|
||||
if (instr.value.kind === "Identifier") {
|
||||
// TODO(gsn): Handle complex aliasing.
|
||||
if (
|
||||
instr.value.memberPath === null &&
|
||||
instr.lvalue.place.memberPath === null
|
||||
) {
|
||||
// direct aliasing: `a = b`;
|
||||
aliases.union([
|
||||
instr.lvalue.place.identifier,
|
||||
instr.value.identifier,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (instr.lvalue.place.memberPath === null) {
|
||||
const lvalueId = instr.lvalue.place.identifier;
|
||||
|
||||
@@ -116,4 +133,45 @@ export function inferMutableRanges(func: HIRFunction) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const aliasIds: Map<Identifier, number> = new Map();
|
||||
// Store the mutable range and set of identifiers for each scope
|
||||
const aliasIndentifiers: Map<
|
||||
number,
|
||||
{ end: number; identifiers: Set<Identifier> }
|
||||
> = new Map();
|
||||
|
||||
aliases.forEach((identifier, groupIdentifier) => {
|
||||
let aliasId = aliasIds.get(groupIdentifier);
|
||||
if (aliasId == null) {
|
||||
aliasId = aliasIds.size;
|
||||
aliasIds.set(groupIdentifier, aliasId);
|
||||
}
|
||||
|
||||
let alias = aliasIndentifiers.get(aliasId);
|
||||
if (alias === undefined) {
|
||||
alias = {
|
||||
end: identifier.mutableRange.end,
|
||||
identifiers: new Set(),
|
||||
};
|
||||
aliasIndentifiers.set(aliasId, alias);
|
||||
} else {
|
||||
alias.end = Math.max(alias.end, identifier.mutableRange.end);
|
||||
}
|
||||
alias.identifiers.add(identifier);
|
||||
});
|
||||
|
||||
for (const [_, alias] of aliasIndentifiers) {
|
||||
// Update mutableRange.end only if the identifiers have actually been
|
||||
// mutated.
|
||||
const haveIdentifiersBeenMutated = [...alias.identifiers].some(
|
||||
(id) => id.mutableRange.end > id.mutableRange.start
|
||||
);
|
||||
|
||||
if (haveIdentifiersBeenMutated) {
|
||||
for (const identifier of alias.identifiers) {
|
||||
identifier.mutableRange.end = alias.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function foo(cond) {
|
||||
let a = {};
|
||||
let b = {};
|
||||
let c = {};
|
||||
while (cond) {
|
||||
let z = a;
|
||||
a = b;
|
||||
b = c;
|
||||
c = z;
|
||||
mutate(a, b);
|
||||
}
|
||||
a;
|
||||
b;
|
||||
c;
|
||||
return a;
|
||||
}
|
||||
|
||||
function mutate(x, y) {}
|
||||
|
||||
```
|
||||
|
||||
## HIR
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate a$2_@0[0:8] = Object { }
|
||||
[2] Let mutate b$3_@0[0:8] = Object { }
|
||||
[3] Let mutate c$4_@0[0:8] = Object { }
|
||||
While test=bb1 loop=bb3 fallthrough=bb2
|
||||
bb1:
|
||||
predecessor blocks: bb0 bb3
|
||||
If (read cond$1) then:bb3 else:bb2
|
||||
bb3:
|
||||
predecessor blocks: bb1
|
||||
[4] Let mutate z$5_@0[0:8] = read a$2_@0
|
||||
[5] Reassign mutate a$2_@0[0:8] = read b$3_@0
|
||||
[6] Reassign mutate b$3_@0[0:8] = read c$4_@0
|
||||
[7] Reassign mutate c$4_@0[0:8] = read z$5_@0
|
||||
[8] Call mutate mutate$6_@0(mutate a$2_@0, mutate b$3_@0)
|
||||
Goto(Continue) bb1
|
||||
bb2:
|
||||
predecessor blocks: bb1
|
||||
[9] read a$2_@0
|
||||
[10] read b$3_@0
|
||||
[11] read c$4_@0
|
||||
Return freeze a$2_@0
|
||||
```
|
||||
|
||||
### CFG
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate a$2_@0[0:8] = Object { }
|
||||
[2] Let mutate b$3_@0[0:8] = Object { }
|
||||
[3] Let mutate c$4_@0[0:8] = Object { }
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["While"])
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_terminal(["If (read cond$1)"])
|
||||
end
|
||||
subgraph bb3
|
||||
bb3_instrs["
|
||||
[4] Let mutate z$5_@0[0:8] = read a$2_@0
|
||||
[5] Reassign mutate a$2_@0[0:8] = read b$3_@0
|
||||
[6] Reassign mutate b$3_@0[0:8] = read c$4_@0
|
||||
[7] Reassign mutate c$4_@0[0:8] = read z$5_@0
|
||||
[8] Call mutate mutate$6_@0(mutate a$2_@0, mutate b$3_@0)
|
||||
"]
|
||||
bb3_instrs --> bb3_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb2
|
||||
bb2_instrs["
|
||||
[9] read a$2_@0
|
||||
[10] read b$3_@0
|
||||
[11] read c$4_@0
|
||||
"]
|
||||
bb2_instrs --> bb2_terminal(["Return freeze a$2_@0"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
bb0_terminal -- "test" --> bb1
|
||||
bb0_terminal -- "loop" --> bb3
|
||||
bb0_terminal -- "fallthrough" --> bb2
|
||||
bb1_terminal -- "then" --> bb3
|
||||
bb1_terminal -- "else" --> bb2
|
||||
bb3_terminal --> bb1
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function foo$0(cond$1) {
|
||||
let a$2 = {};
|
||||
let b$3 = {};
|
||||
let c$4 = {};
|
||||
bb2: while (cond$1) {
|
||||
let z$5 = a$2;
|
||||
a$2 = b$3;
|
||||
b$3 = c$4;
|
||||
c$4 = z$5;
|
||||
mutate$6(a$2, b$3);
|
||||
}
|
||||
|
||||
a$2;
|
||||
b$3;
|
||||
c$4;
|
||||
return a$2;
|
||||
}
|
||||
|
||||
```
|
||||
## HIR
|
||||
|
||||
```
|
||||
bb0:
|
||||
Return
|
||||
```
|
||||
|
||||
### CFG
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_terminal(["Return"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
%% empty
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function mutate$0(x$1, y$2) {
|
||||
return;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
function foo(cond) {
|
||||
let a = {};
|
||||
let b = {};
|
||||
let c = {};
|
||||
while (cond) {
|
||||
let z = a;
|
||||
a = b;
|
||||
b = c;
|
||||
c = z;
|
||||
mutate(a, b);
|
||||
}
|
||||
a;
|
||||
b;
|
||||
c;
|
||||
return a;
|
||||
}
|
||||
|
||||
function mutate(x, y) {}
|
||||
@@ -101,20 +101,20 @@ function cond$0(x$1) {
|
||||
bb0:
|
||||
[1] Let mutate a$2_@0[0:14] = Object { }
|
||||
[2] Let mutate b$3_@0[0:14] = Object { }
|
||||
[3] Let mutate c$4_@1[0:9] = Object { }
|
||||
[3] Let mutate c$4_@0[0:14] = Object { }
|
||||
[4] Let mutate d$5_@0[0:14] = Object { }
|
||||
While test=bb1 loop=bb3 fallthrough=bb2
|
||||
bb1:
|
||||
predecessor blocks: bb0 bb4
|
||||
[5] Const mutate $10_@2 = true
|
||||
If (read $10_@2) then:bb3 else:bb2
|
||||
[5] Const mutate $10_@1 = true
|
||||
If (read $10_@1) then:bb3 else:bb2
|
||||
bb3:
|
||||
predecessor blocks: bb1
|
||||
[6] Let mutate z$6_@3 = read a$2_@0
|
||||
[6] Let mutate z$6_@0[0:14] = read a$2_@0
|
||||
[7] Reassign mutate a$2_@0[0:14] = read b$3_@0
|
||||
[8] Reassign mutate b$3_@0[0:14] = read c$4_@1
|
||||
[9] Reassign mutate c$4_@1[0:9] = read d$5_@0
|
||||
[10] Reassign mutate d$5_@0[0:14] = read z$6_@3
|
||||
[8] Reassign mutate b$3_@0[0:14] = read c$4_@0
|
||||
[9] Reassign mutate c$4_@0[0:14] = read d$5_@0
|
||||
[10] Reassign mutate d$5_@0[0:14] = read z$6_@0
|
||||
[11] Call mutate mutate$7_@0(mutate a$2_@0, mutate b$3_@0)
|
||||
[12] Const mutate $9_@0[0:14] = Call mutate cond$8_@0(mutate a$2_@0)
|
||||
If (read $9_@0) then:bb2 else:bb4
|
||||
@@ -129,14 +129,14 @@ bb7:
|
||||
If (read b$3_@0) then:bb9 else:bb9
|
||||
bb9:
|
||||
predecessor blocks: bb7
|
||||
If (read c$4_@1) then:bb11 else:bb11
|
||||
If (read c$4_@0) then:bb11 else:bb11
|
||||
bb11:
|
||||
predecessor blocks: bb9
|
||||
If (read d$5_@0) then:bb13 else:bb13
|
||||
bb13:
|
||||
predecessor blocks: bb11
|
||||
[13] Const mutate $11_@4 = null
|
||||
[14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@4)
|
||||
[13] Const mutate $11_@2 = null
|
||||
[14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@2)
|
||||
Return
|
||||
```
|
||||
|
||||
@@ -149,24 +149,24 @@ flowchart TB
|
||||
bb0_instrs["
|
||||
[1] Let mutate a$2_@0[0:14] = Object { }
|
||||
[2] Let mutate b$3_@0[0:14] = Object { }
|
||||
[3] Let mutate c$4_@1[0:9] = Object { }
|
||||
[3] Let mutate c$4_@0[0:14] = Object { }
|
||||
[4] Let mutate d$5_@0[0:14] = Object { }
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["While"])
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[5] Const mutate $10_@2 = true
|
||||
[5] Const mutate $10_@1 = true
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["If (read $10_@2)"])
|
||||
bb1_instrs --> bb1_terminal(["If (read $10_@1)"])
|
||||
end
|
||||
subgraph bb3
|
||||
bb3_instrs["
|
||||
[6] Let mutate z$6_@3 = read a$2_@0
|
||||
[6] Let mutate z$6_@0[0:14] = read a$2_@0
|
||||
[7] Reassign mutate a$2_@0[0:14] = read b$3_@0
|
||||
[8] Reassign mutate b$3_@0[0:14] = read c$4_@1
|
||||
[9] Reassign mutate c$4_@1[0:9] = read d$5_@0
|
||||
[10] Reassign mutate d$5_@0[0:14] = read z$6_@3
|
||||
[8] Reassign mutate b$3_@0[0:14] = read c$4_@0
|
||||
[9] Reassign mutate c$4_@0[0:14] = read d$5_@0
|
||||
[10] Reassign mutate d$5_@0[0:14] = read z$6_@0
|
||||
[11] Call mutate mutate$7_@0(mutate a$2_@0, mutate b$3_@0)
|
||||
[12] Const mutate $9_@0[0:14] = Call mutate cond$8_@0(mutate a$2_@0)
|
||||
"]
|
||||
@@ -182,15 +182,15 @@ flowchart TB
|
||||
bb7_terminal(["If (read b$3_@0)"])
|
||||
end
|
||||
subgraph bb9
|
||||
bb9_terminal(["If (read c$4_@1)"])
|
||||
bb9_terminal(["If (read c$4_@0)"])
|
||||
end
|
||||
subgraph bb11
|
||||
bb11_terminal(["If (read d$5_@0)"])
|
||||
end
|
||||
subgraph bb13
|
||||
bb13_instrs["
|
||||
[13] Const mutate $11_@4 = null
|
||||
[14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@4)
|
||||
[13] Const mutate $11_@2 = null
|
||||
[14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@2)
|
||||
"]
|
||||
bb13_instrs --> bb13_terminal(["Return"])
|
||||
end
|
||||
|
||||
@@ -25,7 +25,7 @@ function Component(props) {
|
||||
bb0:
|
||||
[1] Let mutate x$2_@0[1:4] = Array []
|
||||
[2] Call mutate x$2_@0.push(read props$1.p0)
|
||||
[3] Let mutate y$3_@1 = read x$2_@0
|
||||
[3] Let mutate y$3_@0[1:4] = read x$2_@0
|
||||
If (read props$1.p1) then:bb2 else:bb1
|
||||
bb2:
|
||||
predecessor blocks: bb0
|
||||
@@ -33,10 +33,10 @@ bb2:
|
||||
Goto bb1
|
||||
bb1:
|
||||
predecessor blocks: bb2 bb0
|
||||
[5] Let mutate _$4_@2 = JSX <read Component$0 x={freeze x$2_@0} ></read Component$0>
|
||||
[6] Call read y$3_@1.push(read props$1.p2)
|
||||
[7] Const mutate $5_@3 = JSX <read Component$0 x={read x$2_@0} y={read y$3_@1} ></read Component$0>
|
||||
Return read $5_@3
|
||||
[5] Let mutate _$4_@1 = JSX <read Component$0 x={freeze x$2_@0} ></read Component$0>
|
||||
[6] Call read y$3_@0.push(read props$1.p2)
|
||||
[7] Const mutate $5_@2 = JSX <read Component$0 x={read x$2_@0} y={read y$3_@0} ></read Component$0>
|
||||
Return read $5_@2
|
||||
```
|
||||
|
||||
### CFG
|
||||
@@ -48,7 +48,7 @@ flowchart TB
|
||||
bb0_instrs["
|
||||
[1] Let mutate x$2_@0[1:4] = Array []
|
||||
[2] Call mutate x$2_@0.push(read props$1.p0)
|
||||
[3] Let mutate y$3_@1 = read x$2_@0
|
||||
[3] Let mutate y$3_@0[1:4] = read x$2_@0
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["If (read props$1.p1)"])
|
||||
end
|
||||
@@ -60,11 +60,11 @@ flowchart TB
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[5] Let mutate _$4_@2 = JSX <read Component$0 x={freeze x$2_@0} ></read Component$0>
|
||||
[6] Call read y$3_@1.push(read props$1.p2)
|
||||
[7] Const mutate $5_@3 = JSX <read Component$0 x={read x$2_@0} y={read y$3_@1} ></read Component$0>
|
||||
[5] Let mutate _$4_@1 = JSX <read Component$0 x={freeze x$2_@0} ></read Component$0>
|
||||
[6] Call read y$3_@0.push(read props$1.p2)
|
||||
[7] Const mutate $5_@2 = JSX <read Component$0 x={read x$2_@0} y={read y$3_@0} ></read Component$0>
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["Return read $5_@3"])
|
||||
bb1_instrs --> bb1_terminal(["Return read $5_@2"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
|
||||
@@ -21,14 +21,14 @@ function Component(props) {
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate x$2_@0[1:2] = Array []
|
||||
[1] Let mutate x$2_@0[1:6] = Array []
|
||||
[2] Call mutate x$2_@0.push(read props$1.p0)
|
||||
[3] Let mutate y$3_@1[3:6] = read x$2_@0
|
||||
[4] Reassign mutate x$2_@2 = Array []
|
||||
[5] Let mutate _$4_@3 = JSX <read Component$0 x={freeze x$2_@2} ></read Component$0>
|
||||
[6] Call mutate y$3_@1.push(read props$1.p1)
|
||||
[7] Const mutate $5_@4 = JSX <read Component$0 x={read x$2_@2} y={freeze y$3_@1} ></read Component$0>
|
||||
Return read $5_@4
|
||||
[3] Let mutate y$3_@0[1:6] = read x$2_@0
|
||||
[4] Reassign mutate x$2_@1 = Array []
|
||||
[5] Let mutate _$4_@2 = JSX <read Component$0 x={freeze x$2_@1} ></read Component$0>
|
||||
[6] Call mutate y$3_@0.push(read props$1.p1)
|
||||
[7] Const mutate $5_@3 = JSX <read Component$0 x={read x$2_@1} y={freeze y$3_@0} ></read Component$0>
|
||||
Return read $5_@3
|
||||
```
|
||||
|
||||
### CFG
|
||||
@@ -38,15 +38,15 @@ flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate x$2_@0[1:2] = Array []
|
||||
[1] Let mutate x$2_@0[1:6] = Array []
|
||||
[2] Call mutate x$2_@0.push(read props$1.p0)
|
||||
[3] Let mutate y$3_@1[3:6] = read x$2_@0
|
||||
[4] Reassign mutate x$2_@2 = Array []
|
||||
[5] Let mutate _$4_@3 = JSX <read Component$0 x={freeze x$2_@2} ></read Component$0>
|
||||
[6] Call mutate y$3_@1.push(read props$1.p1)
|
||||
[7] Const mutate $5_@4 = JSX <read Component$0 x={read x$2_@2} y={freeze y$3_@1} ></read Component$0>
|
||||
[3] Let mutate y$3_@0[1:6] = read x$2_@0
|
||||
[4] Reassign mutate x$2_@1 = Array []
|
||||
[5] Let mutate _$4_@2 = JSX <read Component$0 x={freeze x$2_@1} ></read Component$0>
|
||||
[6] Call mutate y$3_@0.push(read props$1.p1)
|
||||
[7] Const mutate $5_@3 = JSX <read Component$0 x={read x$2_@1} y={freeze y$3_@0} ></read Component$0>
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["Return read $5_@4"])
|
||||
bb0_instrs --> bb0_terminal(["Return read $5_@3"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function mutate() {}
|
||||
function foo() {
|
||||
let a = {};
|
||||
let b = {};
|
||||
let c = {};
|
||||
a = b;
|
||||
b = c;
|
||||
c = a;
|
||||
mutate(a, b);
|
||||
return c;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## HIR
|
||||
|
||||
```
|
||||
bb0:
|
||||
Return
|
||||
```
|
||||
|
||||
### CFG
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_terminal(["Return"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
%% empty
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function mutate$0() {
|
||||
return;
|
||||
}
|
||||
|
||||
```
|
||||
## HIR
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate a$1_@0 = Object { }
|
||||
[2] Let mutate b$2_@1[0:7] = Object { }
|
||||
[3] Let mutate c$3_@1[0:7] = Object { }
|
||||
[4] Reassign mutate a$1_@1[0:7] = read b$2_@1
|
||||
[5] Reassign mutate b$2_@1[0:7] = read c$3_@1
|
||||
[6] Reassign mutate c$3_@1[0:7] = read a$1_@1
|
||||
[7] Call mutate mutate$4_@1(mutate a$1_@1, mutate b$2_@1)
|
||||
Return freeze c$3_@1
|
||||
```
|
||||
|
||||
### CFG
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate a$1_@0 = Object { }
|
||||
[2] Let mutate b$2_@1[0:7] = Object { }
|
||||
[3] Let mutate c$3_@1[0:7] = Object { }
|
||||
[4] Reassign mutate a$1_@1[0:7] = read b$2_@1
|
||||
[5] Reassign mutate b$2_@1[0:7] = read c$3_@1
|
||||
[6] Reassign mutate c$3_@1[0:7] = read a$1_@1
|
||||
[7] Call mutate mutate$4_@1(mutate a$1_@1, mutate b$2_@1)
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["Return freeze c$3_@1"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
%% empty
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function foo$0() {
|
||||
let a$1 = {};
|
||||
let b$2 = {};
|
||||
let c$3 = {};
|
||||
a$1 = b$2;
|
||||
b$2 = c$3;
|
||||
c$3 = a$1;
|
||||
mutate$4(a$1, b$2);
|
||||
return c$3;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
function mutate() {}
|
||||
function foo() {
|
||||
let a = {};
|
||||
let b = {};
|
||||
let c = {};
|
||||
a = b;
|
||||
b = c;
|
||||
c = a;
|
||||
mutate(a, b);
|
||||
return c;
|
||||
}
|
||||
@@ -21,14 +21,14 @@ function foo() {
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate x$1_@0[1:8] = 1
|
||||
[1] Let mutate x$1_@0[1:9] = 1
|
||||
[2] Let mutate y$2_@1 = 2
|
||||
[3] Const mutate $3_@2 = 2
|
||||
[4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2
|
||||
If (read $4_@3) then:bb2 else:bb1
|
||||
bb2:
|
||||
predecessor blocks: bb0
|
||||
[5] Reassign mutate x$1_@0[1:8] = 3
|
||||
[5] Reassign mutate x$1_@0[1:9] = 3
|
||||
Goto bb1
|
||||
bb1:
|
||||
predecessor blocks: bb2 bb0
|
||||
@@ -37,11 +37,11 @@ bb1:
|
||||
If (read $6_@5) then:bb4 else:bb3
|
||||
bb4:
|
||||
predecessor blocks: bb1
|
||||
[8] Reassign mutate x$1_@0[1:8] = 5
|
||||
[8] Reassign mutate x$1_@0[1:9] = 5
|
||||
Goto bb3
|
||||
bb3:
|
||||
predecessor blocks: bb4 bb1
|
||||
[9] Reassign mutate y$2_@6 = read x$1_@0
|
||||
[9] Reassign mutate y$2_@0[1:9] = read x$1_@0
|
||||
Return
|
||||
```
|
||||
|
||||
@@ -52,7 +52,7 @@ flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate x$1_@0[1:8] = 1
|
||||
[1] Let mutate x$1_@0[1:9] = 1
|
||||
[2] Let mutate y$2_@1 = 2
|
||||
[3] Const mutate $3_@2 = 2
|
||||
[4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2
|
||||
@@ -61,7 +61,7 @@ flowchart TB
|
||||
end
|
||||
subgraph bb2
|
||||
bb2_instrs["
|
||||
[5] Reassign mutate x$1_@0[1:8] = 3
|
||||
[5] Reassign mutate x$1_@0[1:9] = 3
|
||||
"]
|
||||
bb2_instrs --> bb2_terminal(["Goto"])
|
||||
end
|
||||
@@ -74,13 +74,13 @@ flowchart TB
|
||||
end
|
||||
subgraph bb4
|
||||
bb4_instrs["
|
||||
[8] Reassign mutate x$1_@0[1:8] = 5
|
||||
[8] Reassign mutate x$1_@0[1:9] = 5
|
||||
"]
|
||||
bb4_instrs --> bb4_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb3
|
||||
bb3_instrs["
|
||||
[9] Reassign mutate y$2_@6 = read x$1_@0
|
||||
[9] Reassign mutate y$2_@0[1:9] = read x$1_@0
|
||||
"]
|
||||
bb3_instrs --> bb3_terminal(["Return"])
|
||||
end
|
||||
|
||||
@@ -18,18 +18,18 @@ function foo() {
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate x$1_@0[1:5] = 1
|
||||
[1] Let mutate x$1_@0[1:6] = 1
|
||||
[2] Let mutate y$2_@1 = 2
|
||||
[3] Const mutate $3_@2 = 2
|
||||
[4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2
|
||||
If (read $4_@3) then:bb2 else:bb1
|
||||
bb2:
|
||||
predecessor blocks: bb0
|
||||
[5] Reassign mutate x$1_@0[1:5] = 3
|
||||
[5] Reassign mutate x$1_@0[1:6] = 3
|
||||
Goto bb1
|
||||
bb1:
|
||||
predecessor blocks: bb2 bb0
|
||||
[6] Reassign mutate y$2_@4 = read x$1_@0
|
||||
[6] Reassign mutate y$2_@0[1:6] = read x$1_@0
|
||||
Return
|
||||
```
|
||||
|
||||
@@ -40,7 +40,7 @@ flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate x$1_@0[1:5] = 1
|
||||
[1] Let mutate x$1_@0[1:6] = 1
|
||||
[2] Let mutate y$2_@1 = 2
|
||||
[3] Const mutate $3_@2 = 2
|
||||
[4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2
|
||||
@@ -49,13 +49,13 @@ flowchart TB
|
||||
end
|
||||
subgraph bb2
|
||||
bb2_instrs["
|
||||
[5] Reassign mutate x$1_@0[1:5] = 3
|
||||
[5] Reassign mutate x$1_@0[1:6] = 3
|
||||
"]
|
||||
bb2_instrs --> bb2_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[6] Reassign mutate y$2_@4 = read x$1_@0
|
||||
[6] Reassign mutate y$2_@0[1:6] = read x$1_@0
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["Return"])
|
||||
end
|
||||
|
||||
@@ -26,15 +26,15 @@ bb0:
|
||||
If (read $3_@2) then:bb2 else:bb3
|
||||
bb2:
|
||||
predecessor blocks: bb0
|
||||
[4] Reassign mutate y$1_@3[4:5] = 1
|
||||
[4] Reassign mutate y$1_@3[4:6] = 1
|
||||
Goto bb1
|
||||
bb3:
|
||||
predecessor blocks: bb0
|
||||
[5] Reassign mutate y$1_@3[4:5] = 2
|
||||
[5] Reassign mutate y$1_@3[4:6] = 2
|
||||
Goto bb1
|
||||
bb1:
|
||||
predecessor blocks: bb2 bb3
|
||||
[6] Let mutate x$4_@4 = read y$1_@3
|
||||
[6] Let mutate x$4_@3[4:6] = read y$1_@3
|
||||
Return
|
||||
```
|
||||
|
||||
@@ -53,19 +53,19 @@ flowchart TB
|
||||
end
|
||||
subgraph bb2
|
||||
bb2_instrs["
|
||||
[4] Reassign mutate y$1_@3[4:5] = 1
|
||||
[4] Reassign mutate y$1_@3[4:6] = 1
|
||||
"]
|
||||
bb2_instrs --> bb2_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb3
|
||||
bb3_instrs["
|
||||
[5] Reassign mutate y$1_@3[4:5] = 2
|
||||
[5] Reassign mutate y$1_@3[4:6] = 2
|
||||
"]
|
||||
bb3_instrs --> bb3_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[6] Let mutate x$4_@4 = read y$1_@3
|
||||
[6] Let mutate x$4_@3[4:6] = read y$1_@3
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["Return"])
|
||||
end
|
||||
|
||||
@@ -40,21 +40,21 @@ bb0:
|
||||
bb5:
|
||||
predecessor blocks: bb0
|
||||
[6] Const mutate $6_@5 = 1
|
||||
[7] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $6_@5
|
||||
[7] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $6_@5
|
||||
Goto bb1
|
||||
bb3:
|
||||
predecessor blocks: bb0
|
||||
[8] Const mutate $3_@7 = 2
|
||||
[9] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $3_@7
|
||||
[9] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $3_@7
|
||||
Goto bb1
|
||||
bb2:
|
||||
predecessor blocks: bb0
|
||||
[10] Const mutate $2_@8 = 3
|
||||
[11] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $2_@8
|
||||
[11] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $2_@8
|
||||
Goto bb1
|
||||
bb1:
|
||||
predecessor blocks: bb5 bb3 bb2
|
||||
[12] Let mutate y$9_@9 = read x$1_@6
|
||||
[12] Let mutate y$9_@6[7:12] = read x$1_@6
|
||||
Return
|
||||
```
|
||||
|
||||
@@ -76,27 +76,27 @@ flowchart TB
|
||||
subgraph bb5
|
||||
bb5_instrs["
|
||||
[6] Const mutate $6_@5 = 1
|
||||
[7] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $6_@5
|
||||
[7] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $6_@5
|
||||
"]
|
||||
bb5_instrs --> bb5_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb3
|
||||
bb3_instrs["
|
||||
[8] Const mutate $3_@7 = 2
|
||||
[9] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $3_@7
|
||||
[9] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $3_@7
|
||||
"]
|
||||
bb3_instrs --> bb3_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb2
|
||||
bb2_instrs["
|
||||
[10] Const mutate $2_@8 = 3
|
||||
[11] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $2_@8
|
||||
[11] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $2_@8
|
||||
"]
|
||||
bb2_instrs --> bb2_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[12] Let mutate y$9_@9 = read x$1_@6
|
||||
[12] Let mutate y$9_@6[7:12] = read x$1_@6
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["Return"])
|
||||
end
|
||||
|
||||
@@ -32,31 +32,31 @@ function Component(props) {
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate x$2_@0[1:6] = Array []
|
||||
[2] Let mutate y$3_@1[2:8] = undefined
|
||||
[3] Const mutate $4_@2 = false
|
||||
[4] Const mutate $5_@3 = true
|
||||
[5] Const mutate $6_@4 = 1
|
||||
[1] Let mutate x$2_@0[1:8] = Array []
|
||||
[2] Let mutate y$3_@0[1:8] = undefined
|
||||
[3] Const mutate $4_@1 = false
|
||||
[4] Const mutate $5_@2 = true
|
||||
[5] Const mutate $6_@3 = 1
|
||||
Switch (read props$1.p0)
|
||||
Case read $6_@4: bb1
|
||||
Case read $5_@3: bb6
|
||||
Case read $6_@3: bb1
|
||||
Case read $5_@2: bb6
|
||||
Default: bb1
|
||||
Case read $4_@2: bb2
|
||||
Case read $4_@1: bb2
|
||||
bb6:
|
||||
predecessor blocks: bb0
|
||||
[6] Call mutate x$2_@0.push(read props$1.p2)
|
||||
[7] Reassign mutate y$3_@1[2:8] = Array []
|
||||
[7] Reassign mutate y$3_@0[1:8] = Array []
|
||||
Goto bb1
|
||||
bb2:
|
||||
predecessor blocks: bb0
|
||||
[8] Reassign mutate y$3_@1[2:8] = read x$2_@0
|
||||
[8] Reassign mutate y$3_@0[1:8] = read x$2_@0
|
||||
Goto bb1
|
||||
bb1:
|
||||
predecessor blocks: bb0 bb6 bb2
|
||||
[9] Const mutate child$7_@5 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
|
||||
[10] Call read y$3_@1.push(read props$1.p4)
|
||||
[11] Const mutate $8_@6 = JSX <read Component$0 data={freeze y$3_@1} >{read child$7_@5}</read Component$0>
|
||||
Return read $8_@6
|
||||
[9] Const mutate child$7_@4 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
|
||||
[10] Call read y$3_@0.push(read props$1.p4)
|
||||
[11] Const mutate $8_@5 = JSX <read Component$0 data={freeze y$3_@0} >{read child$7_@4}</read Component$0>
|
||||
Return read $8_@5
|
||||
```
|
||||
|
||||
### CFG
|
||||
@@ -66,41 +66,41 @@ flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate x$2_@0[1:6] = Array []
|
||||
[2] Let mutate y$3_@1[2:8] = undefined
|
||||
[3] Const mutate $4_@2 = false
|
||||
[4] Const mutate $5_@3 = true
|
||||
[5] Const mutate $6_@4 = 1
|
||||
[1] Let mutate x$2_@0[1:8] = Array []
|
||||
[2] Let mutate y$3_@0[1:8] = undefined
|
||||
[3] Const mutate $4_@1 = false
|
||||
[4] Const mutate $5_@2 = true
|
||||
[5] Const mutate $6_@3 = 1
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["Switch (read props$1.p0)"])
|
||||
end
|
||||
subgraph bb6
|
||||
bb6_instrs["
|
||||
[6] Call mutate x$2_@0.push(read props$1.p2)
|
||||
[7] Reassign mutate y$3_@1[2:8] = Array []
|
||||
[7] Reassign mutate y$3_@0[1:8] = Array []
|
||||
"]
|
||||
bb6_instrs --> bb6_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb2
|
||||
bb2_instrs["
|
||||
[8] Reassign mutate y$3_@1[2:8] = read x$2_@0
|
||||
[8] Reassign mutate y$3_@0[1:8] = read x$2_@0
|
||||
"]
|
||||
bb2_instrs --> bb2_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[9] Const mutate child$7_@5 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
|
||||
[10] Call read y$3_@1.push(read props$1.p4)
|
||||
[11] Const mutate $8_@6 = JSX <read Component$0 data={freeze y$3_@1} >{read child$7_@5}</read Component$0>
|
||||
[9] Const mutate child$7_@4 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
|
||||
[10] Call read y$3_@0.push(read props$1.p4)
|
||||
[11] Const mutate $8_@5 = JSX <read Component$0 data={freeze y$3_@0} >{read child$7_@4}</read Component$0>
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["Return read $8_@6"])
|
||||
bb1_instrs --> bb1_terminal(["Return read $8_@5"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
bb0_terminal -- "read $6_@4" --> bb1
|
||||
bb0_terminal -- "read $5_@3" --> bb6
|
||||
bb0_terminal -- "read $6_@3" --> bb1
|
||||
bb0_terminal -- "read $5_@2" --> bb6
|
||||
bb0_terminal -- "default" --> bb1
|
||||
bb0_terminal -- "read $4_@2" --> bb2
|
||||
bb0_terminal -- "read $4_@1" --> bb2
|
||||
bb0_terminal -- "fallthrough" --> bb1
|
||||
bb6_terminal --> bb1
|
||||
bb2_terminal --> bb1
|
||||
|
||||
@@ -28,30 +28,30 @@ function Component(props) {
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate x$2_@0[1:6] = Array []
|
||||
[2] Let mutate y$3_@1[2:8] = undefined
|
||||
[3] Const mutate $4_@2 = false
|
||||
[4] Const mutate $5_@3 = true
|
||||
[1] Let mutate x$2_@0[1:8] = Array []
|
||||
[2] Let mutate y$3_@0[1:8] = undefined
|
||||
[3] Const mutate $4_@1 = false
|
||||
[4] Const mutate $5_@2 = true
|
||||
Switch (read props$1.p0)
|
||||
Case read $5_@3: bb4
|
||||
Case read $4_@2: bb2
|
||||
Case read $5_@2: bb4
|
||||
Case read $4_@1: bb2
|
||||
Default: bb1
|
||||
bb4:
|
||||
predecessor blocks: bb0
|
||||
[5] Call mutate x$2_@0.push(read props$1.p2)
|
||||
[6] Call mutate x$2_@0.push(read props$1.p3)
|
||||
[7] Reassign mutate y$3_@4 = Array []
|
||||
[7] Reassign mutate y$3_@3 = Array []
|
||||
Goto bb2
|
||||
bb2:
|
||||
predecessor blocks: bb4 bb0
|
||||
[8] Reassign mutate y$3_@1[2:8] = read x$2_@0
|
||||
[8] Reassign mutate y$3_@0[1:8] = read x$2_@0
|
||||
Goto bb1
|
||||
bb1:
|
||||
predecessor blocks: bb2 bb0
|
||||
[9] Const mutate child$6_@5 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
|
||||
[10] Call read y$3_@1.push(read props$1.p4)
|
||||
[11] Const mutate $7_@6 = JSX <read Component$0 data={read y$3_@1} >{read child$6_@5}</read Component$0>
|
||||
Return read $7_@6
|
||||
[9] Const mutate child$6_@4 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
|
||||
[10] Call read y$3_@0.push(read props$1.p4)
|
||||
[11] Const mutate $7_@5 = JSX <read Component$0 data={read y$3_@0} >{read child$6_@4}</read Component$0>
|
||||
Return read $7_@5
|
||||
```
|
||||
|
||||
### CFG
|
||||
@@ -61,10 +61,10 @@ flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate x$2_@0[1:6] = Array []
|
||||
[2] Let mutate y$3_@1[2:8] = undefined
|
||||
[3] Const mutate $4_@2 = false
|
||||
[4] Const mutate $5_@3 = true
|
||||
[1] Let mutate x$2_@0[1:8] = Array []
|
||||
[2] Let mutate y$3_@0[1:8] = undefined
|
||||
[3] Const mutate $4_@1 = false
|
||||
[4] Const mutate $5_@2 = true
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["Switch (read props$1.p0)"])
|
||||
end
|
||||
@@ -72,28 +72,28 @@ flowchart TB
|
||||
bb4_instrs["
|
||||
[5] Call mutate x$2_@0.push(read props$1.p2)
|
||||
[6] Call mutate x$2_@0.push(read props$1.p3)
|
||||
[7] Reassign mutate y$3_@4 = Array []
|
||||
[7] Reassign mutate y$3_@3 = Array []
|
||||
"]
|
||||
bb4_instrs --> bb4_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb2
|
||||
bb2_instrs["
|
||||
[8] Reassign mutate y$3_@1[2:8] = read x$2_@0
|
||||
[8] Reassign mutate y$3_@0[1:8] = read x$2_@0
|
||||
"]
|
||||
bb2_instrs --> bb2_terminal(["Goto"])
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[9] Const mutate child$6_@5 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
|
||||
[10] Call read y$3_@1.push(read props$1.p4)
|
||||
[11] Const mutate $7_@6 = JSX <read Component$0 data={read y$3_@1} >{read child$6_@5}</read Component$0>
|
||||
[9] Const mutate child$6_@4 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
|
||||
[10] Call read y$3_@0.push(read props$1.p4)
|
||||
[11] Const mutate $7_@5 = JSX <read Component$0 data={read y$3_@0} >{read child$6_@4}</read Component$0>
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["Return read $7_@6"])
|
||||
bb1_instrs --> bb1_terminal(["Return read $7_@5"])
|
||||
end
|
||||
|
||||
%% Jumps
|
||||
bb0_terminal -- "read $5_@3" --> bb4
|
||||
bb0_terminal -- "read $4_@2" --> bb2
|
||||
bb0_terminal -- "read $5_@2" --> bb4
|
||||
bb0_terminal -- "read $4_@1" --> bb2
|
||||
bb0_terminal -- "default" --> bb1
|
||||
bb0_terminal -- "fallthrough" --> bb1
|
||||
bb4_terminal --> bb2
|
||||
|
||||
Reference in New Issue
Block a user