Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
markInstructionIds,
markPredecessors,
mergeConsecutiveBlocks,
promoteTemporaryJsxTag,
reversePostorderBlocks,
} from '../HIR';
import {
Expand Down Expand Up @@ -62,7 +63,12 @@ export function constantPropagation(fn: HIRFunction): void {

function constantPropagationImpl(fn: HIRFunction, constants: Constants): void {
while (true) {
const haveTerminalsChanged = applyConstantPropagation(fn, constants);
const jsxTagIdentifiers = collectJsxTagIdentifiers(fn);
const haveTerminalsChanged = applyConstantPropagation(
fn,
constants,
jsxTagIdentifiers,
);
if (!haveTerminalsChanged) {
break;
}
Expand Down Expand Up @@ -106,6 +112,7 @@ function constantPropagationImpl(fn: HIRFunction, constants: Constants): void {
function applyConstantPropagation(
fn: HIRFunction,
constants: Constants,
jsxTagIdentifiers: Set<IdentifierId>,
): boolean {
let hasChanges = false;
for (const [, block] of fn.body.blocks) {
Expand All @@ -130,7 +137,7 @@ function applyConstantPropagation(
continue;
}
const instr = block.instructions[i]!;
const value = evaluateInstruction(constants, instr);
const value = evaluateInstruction(constants, instr, jsxTagIdentifiers);
if (value !== null) {
constants.set(instr.lvalue.identifier.id, value);
}
Expand Down Expand Up @@ -239,6 +246,7 @@ function evaluatePhi(phi: Phi, constants: Constants): Constant | null {
function evaluateInstruction(
constants: Constants,
instr: Instruction,
jsxTagIdentifiers: Set<IdentifierId>,
): Constant | null {
const value = instr.value;
switch (value.kind) {
Expand Down Expand Up @@ -593,6 +601,14 @@ function evaluateInstruction(
case 'LoadLocal': {
const placeValue = read(constants, value.place);
if (placeValue !== null) {
if (
instr.lvalue != null &&
jsxTagIdentifiers.has(instr.lvalue.identifier.id) &&
placeValue.kind === 'LoadGlobal' &&
instr.lvalue.identifier.name == null
) {
promoteTemporaryJsxTag(instr.lvalue.identifier);
}
instr.value = placeValue;
}
return placeValue;
Expand Down Expand Up @@ -639,3 +655,19 @@ function read(constants: Constants, place: Place): Constant | null {

type Constant = Primitive | LoadGlobal;
type Constants = Map<IdentifierId, Constant>;

function collectJsxTagIdentifiers(fn: HIRFunction): Set<IdentifierId> {
const identifiers = new Set<IdentifierId>();

for (const [, block] of fn.body.blocks) {
for (const instr of block.instructions) {
if (
instr.value.kind === 'JsxExpression' &&
instr.value.tag.kind === 'Identifier'
) {
identifiers.add(instr.value.tag.identifier.id);
}
}
}
return identifiers;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ function useFoo() {
return t0;
}
function _temp() {
return <Stringify value={4} />;
const T0 = Stringify;
return <T0 value={4} />;
}

export const FIXTURE_ENTRYPOINT = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,23 @@ import { StaticText1, StaticText2 } from "shared-runtime";
function Component(props) {
const $ = _c(3);

const T0 = StaticText1;
const t0 = props.value;
const T1 = StaticText2;
let t1;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t1 = <StaticText2 />;
t1 = <T1 />;
$[0] = t1;
} else {
t1 = $[0];
}
let t2;
if ($[1] !== t0) {
t2 = (
<StaticText1>
<T0>
{t0}
{t1}
</StaticText1>
</T0>
);
$[1] = t0;
$[2] = t2;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

## Input

```javascript
import React from 'react';

const base = 'div';

const TestComponent: React.FC = () => {
const Comp = base;
return <Comp />;
};

export default function Home() {
return <TestComponent />;
}

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime";
import React from "react";

const base = "div";

const TestComponent: React.FC = () => {
const $ = _c(1);

const T0 = base;
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <T0 />;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
};

export default function Home() {
const $ = _c(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <TestComponent />;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
}

```

### Eval output
(kind: exception) Fixture not implemented
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';

const base = 'div';

const TestComponent: React.FC = () => {
const Comp = base;
return <Comp />;
};

export default function Home() {
return <TestComponent />;
}