mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
More precise handling of const/reassign in ssa form
Addressed a TODO from the previous PR. When we enter SSA form, when we rewrite variable reassignments we currently change the identifier but leave the kind of the lvalue alone; technically we should convert from Reassign to Const. After doing that, it's easier to correctly update when we leave SSA form, we can convert just a subset back into let/reassign (but leave most things alone as const).
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
HIRFunction,
|
||||
Identifier,
|
||||
IdentifierId,
|
||||
InstructionKind,
|
||||
makeInstructionId,
|
||||
makeType,
|
||||
Phi,
|
||||
@@ -202,6 +203,7 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
|
||||
newPlace = builder.getPlace(oldPlace);
|
||||
} else {
|
||||
newPlace = builder.definePlace(oldPlace);
|
||||
instr.lvalue.kind = InstructionKind.Const;
|
||||
}
|
||||
instr.lvalue.place = newPlace;
|
||||
}
|
||||
|
||||
@@ -291,23 +291,22 @@ export function leaveSSA(fn: HIRFunction) {
|
||||
// Finally, iterate the instructions and perform any rewrites as well as converting
|
||||
// SSA variables to `const` where possible
|
||||
for (const instr of block.instructions) {
|
||||
const { lvalue, value } = instr;
|
||||
const { lvalue } = instr;
|
||||
if (lvalue !== null) {
|
||||
rewritePlace(lvalue.place, rewrites);
|
||||
if (
|
||||
lvalue.kind !== InstructionKind.Const &&
|
||||
lvalue.kind === InstructionKind.Const &&
|
||||
lvalue.place.memberPath === null &&
|
||||
!rewrites.has(lvalue.place.identifier) &&
|
||||
(!reassignments.has(lvalue.place.identifier) ||
|
||||
reassignments.get(lvalue.place.identifier) !==
|
||||
lvalue.place.identifier)
|
||||
rewrites.has(lvalue.place.identifier)
|
||||
) {
|
||||
// Convert individual SSA reassignments into const declarations
|
||||
// otherwise the code would be invalid, since the SSA identifiers
|
||||
// aren't otherwise declared.
|
||||
// TODO @josephsavona: do this in EnterSSA instead?
|
||||
lvalue.kind = InstructionKind.Const;
|
||||
// For rewrites, the declaration of the canonical identifier has to be `let`,
|
||||
// all other assignments are reassignments (which we annotate for codegen
|
||||
// purposes).
|
||||
lvalue.kind =
|
||||
rewrites.get(lvalue.place.identifier) === lvalue.place.identifier
|
||||
? InstructionKind.Let
|
||||
: InstructionKind.Reassign;
|
||||
}
|
||||
rewritePlace(lvalue.place, rewrites);
|
||||
}
|
||||
for (const operand of eachInstructionValueOperand(instr.value)) {
|
||||
rewritePlace(operand, rewrites);
|
||||
|
||||
Reference in New Issue
Block a user