Skip to content

Commit

Permalink
chore(docs): Fix some typos
Browse files Browse the repository at this point in the history
  • Loading branch information
nikeee committed May 28, 2024
1 parent 6f23540 commit ab760d0
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 9 deletions.
8 changes: 4 additions & 4 deletions compiler/docs/DESIGN_GOALS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The idea of React Compiler is to allow developers to use React's familiar declar
The following are explicitly *not* goals for React Compiler:

* Provide perfectly optimal re-rendering with zero unnecessary recomputation. This is a non-goal for several reasons:
* The runtime overhead of the extra tracking involved can outweight the cost of recomputation in many cases.
* The runtime overhead of the extra tracking involved can outweigh the cost of recomputation in many cases.
* In cases with conditional dependencies it may not be possible to avoid recomputing some/all instructions.
* The amount of code may regress startup times, which would conflict with our goal of neutral startup performance.
* Support code that violates React's rules. React's rules exist to help developers build robust, scalable applications and form a contract that allows us to continue improving React without breaking applications. React Compiler depends on these rules to safely transform code, and violations of rules will therefore break React Compiler's optimizations.
Expand All @@ -42,12 +42,12 @@ React Compiler has two primary public interfaces: a Babel plugin for transformin
The core of the compiler is largely decoupled from Babel, using its own intermediate representations. The high-level flow is as follows:

- **Babel Plugin**: Determines which functions in a file should be compiled, based on the plugin options and any local opt-in/opt-out directives. For each component or hook to be compiled, the plugin calls the compiler, passing in the original function and getting back a new AST node which will replace the original.
- **Lowering** (BuildHIR): The first step of the compiler is to convert the Babel AST into React Compiler's primary intermediate representation, HIR (High-level Intermediate Representation). This phase is primarily based on the AST itself, but currently leans on Babel to resolve identifiers. The HIR preserves the precise order-of-evaluation semantics of JavaScript, resolves break/continue to their jump points, etc. The resulting HIR forms a control-flow graph of basic blocks, each of which contains zero or more consecutive instructions followed by a terminal. The basic blocks are stored in reverse postorder, such that forward iteration of the blocks allows predecessors to be visited before successors _unless_ there is a "back edge" (ie a loop).
- **Lowering** (BuildHIR): The first step of the compiler is to convert the Babel AST into React Compiler's primary intermediate representation, HIR (High-level Intermediate Representation). This phase is primarily based on the AST itself, but currently leans on Babel to resolve identifiers. The HIR preserves the precise order-of-evaluation semantics of JavaScript, resolves break/continue to their jump points, etc. The resulting HIR forms a control-flow graph of basic blocks, each of which contains zero or more consecutive instructions followed by a terminal. The basic blocks are stored in reverse post-order, such that forward iteration of the blocks allows predecessors to be visited before successors _unless_ there is a "back edge" (ie a loop).
- **SSA Conversion** (EnterSSA): The HIR is converted to HIR form, such that all Identifiers in the HIR are updated to an SSA-based identifier.
- Validation: We run various validation passes to check that the input is valid React, ie that it does not break the rules. This includes looking for conditional hook calls, unconditional setState calls, etc.
- **Optimization**: Various passes such as dead code elimination and constant propagation can generally improve performance and reduce the amount of instructions to be optimized later.
- **Type Inference** (InferTypes): We run a conservative type inference pass to identify certain key types of data that may appear in the program that are relevant for further analysis, such as which values are hooks, primitives, etc.
- **Inferring Reactive Scopes**: Several passes are involved in determing groups of values that are created/mutated together and the set of instructions involved in creating/mutating those values. We call these groups "reactive scopes", and each can have one or more declarations (or occasionally a reassignment).
- **Type Inference** (InferTypes): We run a conservative type inference pass to identify certain key types of data that may appear in the program that are relevant for further analysis, such as which values are hooks, primitives, etc.
- **Inferring Reactive Scopes**: Several passes are involved in determining groups of values that are created/mutated together and the set of instructions involved in creating/mutating those values. We call these groups "reactive scopes", and each can have one or more declarations (or occasionally a reassignment).
- **Constructing/Optimizing Reactive Scopes**: Once the compiler determines the set of reactive scopes, it then transforms the program to make these scopes explicit in the HIR. The code is later converted to a ReactiveFunction, which is a hybrid of the HIR and an AST. Scopes are further pruned and transformed. For example, the compiler cannot make hook calls conditional, so any reactive scopes that contain a hook call must be pruned. If two consecutive scopes will always invalidate together, we attempt to merge them to reduce overhead, etc.
- **Codegen**: Finally, the ReactiveFunction hybrid HIR/AST is converted back to a raw Babel AST node, and returned to the Babel plugin.
- **Babel Plugin**: The Babel plugin replaces the original node with the new version.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ export function terminalFallthrough(terminal: Terminal): BlockId | null {
/*
* Iterates over the successor block ids of the provided terminal. The function is called
* specifically for the successors that define the standard control flow, and not
* pseduo-successors such as fallthroughs.
* pseudo-successors such as fallthroughs.
*/
export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
switch (terminal.kind) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ function evaluatePhi(phi: Phi, constants: Constants): Constant | null {
let value: Constant | null = null;
for (const [, operand] of phi.operands) {
const operandValue = constants.get(operand.id) ?? null;
// did not find a constant, can't constant propogate
// did not find a constant, can't constant propagate
if (operandValue === null) {
return null;
}
Expand All @@ -182,7 +182,7 @@ function evaluatePhi(phi: Phi, constants: Constants): Constant | null {
continue;
}

// found different kinds of constants, can't constant propogate
// found different kinds of constants, can't constant propagate
if (operandValue.kind !== value.kind) {
return null;
}
Expand All @@ -195,7 +195,7 @@ function evaluatePhi(phi: Phi, constants: Constants): Constant | null {
suggestions: null,
});

// different constant values, can't constant propogate
// different constant values, can't constant propagate
if (operandValue.value !== value.value) {
return null;
}
Expand All @@ -208,7 +208,7 @@ function evaluatePhi(phi: Phi, constants: Constants): Constant | null {
suggestions: null,
});

// different global values, can't constant propogate
// different global values, can't constant propagate
if (operandValue.binding.name !== value.binding.name) {
return null;
}
Expand Down

0 comments on commit ab760d0

Please sign in to comment.