mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[be][dependencies] Remove control flow info from PropertyLoad sidemap
--- We don't need to store whether a `PropertyLoad` happens within a conditional (within its reactive scope). In fact, the PropertyLoad producing a rval often is in a different ReactiveScope from where the rval is used. We only need to add `#inConditionalWithinScope` when we actually visit a reactive dependency.
This commit is contained in:
@@ -3,10 +3,6 @@ import { Identifier, ReactiveScopeDependency } from "../HIR";
|
||||
import { printIdentifier } from "../HIR/PrintHIR";
|
||||
import { assertExhaustive } from "../Utils/utils";
|
||||
|
||||
export type ReactiveScopeDependencyInfo = ReactiveScopeDependency & {
|
||||
cond: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalizes a set of ReactiveScopeDependencies to produce a set of minimal unconditional
|
||||
* dependencies, preserving granular accesses when possible.
|
||||
@@ -46,14 +42,14 @@ export class ReactiveScopeDependencyTree {
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
add(dep: ReactiveScopeDependencyInfo): void {
|
||||
add(dep: ReactiveScopeDependency, inConditional: boolean): void {
|
||||
const path = dep.path ?? [];
|
||||
let currNode = this.#getOrCreateRoot(dep.identifier);
|
||||
|
||||
const accessType = dep.cond
|
||||
const accessType = inConditional
|
||||
? PropertyAccessType.ConditionalAccess
|
||||
: PropertyAccessType.UnconditionalAccess;
|
||||
const depType = dep.cond
|
||||
const depType = inConditional
|
||||
? PropertyAccessType.ConditionalDependency
|
||||
: PropertyAccessType.UnconditionalDependency;
|
||||
|
||||
|
||||
@@ -24,10 +24,7 @@ import {
|
||||
eachPatternOperand,
|
||||
} from "../HIR/visitors";
|
||||
import { assertExhaustive } from "../Utils/utils";
|
||||
import {
|
||||
ReactiveScopeDependencyInfo,
|
||||
ReactiveScopeDependencyTree,
|
||||
} from "./DeriveMinimalDependencies";
|
||||
import { ReactiveScopeDependencyTree } from "./DeriveMinimalDependencies";
|
||||
|
||||
/**
|
||||
* Infers the dependencies of each scope to include variables whose values
|
||||
@@ -66,7 +63,12 @@ class Context {
|
||||
// Reactive dependencies used in the current reactive scope.
|
||||
#dependencies: ReactiveScopeDependencyTree =
|
||||
new ReactiveScopeDependencyTree();
|
||||
#properties: Map<Identifier, ReactiveScopeDependencyInfo> = new Map();
|
||||
// We keep a sidemap for temporaries created by PropertyLoads, and do
|
||||
// not store any control flow (i.e. #inConditionalWithinScope) here.
|
||||
// - a ReactiveScope (A) containing a PropertyLoad may differ from the
|
||||
// ReactiveScope (B) that uses the produced temporary.
|
||||
// - codegen will inline these PropertyLoads back into scope (B)
|
||||
#properties: Map<Identifier, ReactiveScopeDependency> = new Map();
|
||||
#temporaries: Map<Identifier, Place> = new Map();
|
||||
#inConditionalWithinScope: boolean = false;
|
||||
// Reactive dependencies used unconditionally in the current conditional.
|
||||
@@ -187,18 +189,16 @@ class Context {
|
||||
declareProperty(lvalue: Place, object: Place, property: string): void {
|
||||
const resolvedObject = this.#temporaries.get(object.identifier) ?? object;
|
||||
const objectDependency = this.#properties.get(resolvedObject.identifier);
|
||||
let nextDependency: ReactiveScopeDependencyInfo;
|
||||
let nextDependency: ReactiveScopeDependency;
|
||||
if (objectDependency === undefined) {
|
||||
nextDependency = {
|
||||
identifier: resolvedObject.identifier,
|
||||
path: [property],
|
||||
cond: this.#inConditionalWithinScope,
|
||||
};
|
||||
} else {
|
||||
nextDependency = {
|
||||
identifier: objectDependency.identifier,
|
||||
path: [...(objectDependency.path ?? []), property],
|
||||
cond: this.#inConditionalWithinScope,
|
||||
};
|
||||
}
|
||||
this.#properties.set(lvalue.identifier, nextDependency);
|
||||
@@ -234,32 +234,29 @@ class Context {
|
||||
this.visitDependency({
|
||||
identifier: resolved.identifier,
|
||||
path: null,
|
||||
cond: this.#inConditionalWithinScope,
|
||||
});
|
||||
}
|
||||
|
||||
visitProperty(object: Place, property: string): void {
|
||||
const resolvedObject = this.#temporaries.get(object.identifier) ?? object;
|
||||
const objectDependency = this.#properties.get(resolvedObject.identifier);
|
||||
let nextDependency: ReactiveScopeDependencyInfo;
|
||||
let nextDependency: ReactiveScopeDependency;
|
||||
if (objectDependency === undefined) {
|
||||
nextDependency = {
|
||||
identifier: resolvedObject.identifier,
|
||||
path: [property],
|
||||
cond: this.#inConditionalWithinScope,
|
||||
};
|
||||
} else {
|
||||
nextDependency = {
|
||||
identifier: objectDependency.identifier,
|
||||
path: [...(objectDependency.path ?? []), property],
|
||||
cond: this.#inConditionalWithinScope,
|
||||
};
|
||||
}
|
||||
this.visitDependency(nextDependency);
|
||||
}
|
||||
|
||||
visitDependency(dependency: ReactiveScopeDependencyInfo): void {
|
||||
let maybeDependency: ReactiveScopeDependencyInfo;
|
||||
visitDependency(dependency: ReactiveScopeDependency): void {
|
||||
let maybeDependency: ReactiveScopeDependency;
|
||||
if (dependency.path !== null) {
|
||||
// Operands may have memberPaths when propagating depenencies of an inner scope upward
|
||||
// In this case we use the dependency as-is
|
||||
@@ -269,7 +266,7 @@ class Context {
|
||||
// the expanded Place. Fall back to using the operand as-is.
|
||||
let propDep = this.#properties.get(dependency.identifier);
|
||||
if (dependency.identifier.name === null && propDep !== undefined) {
|
||||
maybeDependency = { ...propDep, cond: dependency.cond };
|
||||
maybeDependency = { ...propDep };
|
||||
} else {
|
||||
maybeDependency = dependency;
|
||||
}
|
||||
@@ -297,13 +294,10 @@ class Context {
|
||||
}
|
||||
|
||||
if (this.#checkValidDependencyId(maybeDependency.identifier)) {
|
||||
this.#depsInCurrentConditional.add({
|
||||
...maybeDependency,
|
||||
cond: true,
|
||||
});
|
||||
this.#depsInCurrentConditional.add(maybeDependency, true);
|
||||
// Add info about this dependency to the existing tree
|
||||
// We do not try to join/reduce dependencies here due to missing info
|
||||
this.#dependencies.add(maybeDependency);
|
||||
this.#dependencies.add(maybeDependency, this.#inConditionalWithinScope);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user