Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
[ghstack-poisoned]
  • Loading branch information
poteto committed Oct 1, 2024
2 parents 50a5c09 + b28748f commit 267c194
Show file tree
Hide file tree
Showing 52 changed files with 2,522 additions and 1,040 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ const ENABLE_DEBUG_INVARIANTS = true;
export class ReactiveScopeDependencyTreeHIR {
#roots: Map<Identifier, DependencyNode> = new Map();

#getOrCreateRoot(identifier: Identifier, isNonNull: boolean): DependencyNode {
#getOrCreateRoot(
identifier: Identifier,
accessType: PropertyAccessType,
): DependencyNode {
// roots can always be accessed unconditionally in JS
let rootNode = this.#roots.get(identifier);

if (rootNode === undefined) {
rootNode = {
properties: new Map(),
accessType: isNonNull
? PropertyAccessType.NonNullAccess
: PropertyAccessType.Access,
accessType,
};
this.#roots.set(identifier, rootNode);
}
Expand All @@ -37,16 +38,19 @@ export class ReactiveScopeDependencyTreeHIR {

addDependency(dep: ReactiveScopePropertyDependency): void {
const {path} = dep;
let currNode = this.#getOrCreateRoot(dep.identifier, false);
let currNode = this.#getOrCreateRoot(dep.identifier, MIN_ACCESS_TYPE);

const accessType = PropertyAccessType.Access;

currNode.accessType = merge(currNode.accessType, accessType);

for (const property of path) {
// all properties read 'on the way' to a dependency are marked as 'access'
let currChild = getOrMakeProperty(currNode, property.property);
currChild.accessType = merge(currChild.accessType, accessType);
let currChild = makeOrMergeProperty(
currNode,
property.property,
accessType,
);
currNode = currChild;
}

Expand Down Expand Up @@ -251,17 +255,20 @@ function printSubtree(
return results;
}

function getOrMakeProperty(
function makeOrMergeProperty(
node: DependencyNode,
property: string,
accessType: PropertyAccessType,
): DependencyNode {
let child = node.properties.get(property);
if (child == null) {
child = {
properties: new Map(),
accessType: MIN_ACCESS_TYPE,
accessType,
};
node.properties.set(property, child);
} else {
child.accessType = merge(child.accessType, accessType);
}
return child;
}
18 changes: 10 additions & 8 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -874,13 +874,7 @@ export type InstructionValue =
};
loc: SourceLocation;
}
| {
kind: 'StoreLocal';
lvalue: LValue;
value: Place;
type: t.FlowType | t.TSType | null;
loc: SourceLocation;
}
| StoreLocal
| {
kind: 'StoreContext';
lvalue: {
Expand Down Expand Up @@ -1123,6 +1117,13 @@ export type Primitive = {

export type JSXText = {kind: 'JSXText'; value: string; loc: SourceLocation};

export type StoreLocal = {
kind: 'StoreLocal';
lvalue: LValue;
value: Place;
type: t.FlowType | t.TSType | null;
loc: SourceLocation;
};
export type PropertyLoad = {
kind: 'PropertyLoad';
object: Place;
Expand Down Expand Up @@ -1496,7 +1497,8 @@ export type ReactiveScopeDeclaration = {
scope: ReactiveScope; // the scope in which the variable was originally declared
};

export type DependencyPath = Array<{property: string; optional: boolean}>;
export type DependencyPathEntry = {property: string; optional: boolean};
export type DependencyPath = Array<DependencyPathEntry>;
export type ReactiveScopeDependency = {
identifier: Identifier;
path: DependencyPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
import {
BlockInfo,
collectHoistablePropertyLoads,
getProperty,
} from './CollectHoistablePropertyLoads';
import {
ScopeBlockTraversal,
Expand Down Expand Up @@ -220,6 +219,54 @@ function collectTemporariesSidemap(
return temporaries;
}

function getProperty(
object: Place,
propertyName: string,
temporaries: ReadonlyMap<IdentifierId, ReactiveScopeDependency>,
): ReactiveScopeDependency {
/*
* (1) Get the base object either from the temporary sidemap (e.g. a LoadLocal)
* or a deep copy of an existing property dependency.
* Example 1:
* $0 = LoadLocal x
* $1 = PropertyLoad $0.y
* getProperty($0, ...) -> resolvedObject = x, resolvedDependency = null
*
* Example 2:
* $0 = LoadLocal x
* $1 = PropertyLoad $0.y
* $2 = PropertyLoad $1.z
* getProperty($1, ...) -> resolvedObject = null, resolvedDependency = x.y
*
* Example 3:
* $0 = Call(...)
* $1 = PropertyLoad $0.y
* getProperty($0, ...) -> resolvedObject = null, resolvedDependency = null
*/
const resolvedDependency = temporaries.get(object.identifier.id);

/**
* (2) Push the last PropertyLoad
* TODO(mofeiZ): understand optional chaining
*/
let property: ReactiveScopeDependency;
if (resolvedDependency == null) {
property = {
identifier: object.identifier,
path: [{property: propertyName, optional: false}],
};
} else {
property = {
identifier: resolvedDependency.identifier,
path: [
...resolvedDependency.path,
{property: propertyName, optional: false},
],
};
}
return property;
}

type Decl = {
id: InstructionId;
scope: Stack<ReactiveScope>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

## Input

```javascript
// @enablePropagateDepsInHIR
/**
* props.b *does* influence `a`
*/
function Component(props) {
const a = [];
a.push(props.a);
label: {
if (props.b) {
break label;
}
a.push(props.c);
}
a.push(props.d);
return a;
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: ['TodoAdd'],
isComponent: 'TodoAdd',
};

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR
/**
* props.b *does* influence `a`
*/
function Component(props) {
const $ = _c(5);
let a;
if (
$[0] !== props.a ||
$[1] !== props.b ||
$[2] !== props.c ||
$[3] !== props.d
) {
a = [];
a.push(props.a);
bb0: {
if (props.b) {
break bb0;
}

a.push(props.c);
}

a.push(props.d);
$[0] = props.a;
$[1] = props.b;
$[2] = props.c;
$[3] = props.d;
$[4] = a;
} else {
a = $[4];
}
return a;
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: ["TodoAdd"],
isComponent: "TodoAdd",
};

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @enablePropagateDepsInHIR
/**
* props.b *does* influence `a`
*/
function Component(props) {
const a = [];
a.push(props.a);
label: {
if (props.b) {
break label;
}
a.push(props.c);
}
a.push(props.d);
return a;
}

export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: ['TodoAdd'],
isComponent: 'TodoAdd',
};
Loading

0 comments on commit 267c194

Please sign in to comment.