| 1 | /** |
| 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
| 3 | * |
| 4 | * This source code is licensed under the MIT license found in the |
| 5 | * LICENSE file in the root directory of this source tree. |
| 6 | */ |
| 7 | |
| 8 | import { |
| 9 | DeclarationId, |
| 10 | InstructionId, |
| 11 | Place, |
| 12 | ReactiveFunction, |
| 13 | ReactiveInstruction, |
| 14 | } from '../HIR/HIR'; |
| 15 | import {ReactiveFunctionVisitor, visitReactiveFunction} from './visitors'; |
| 16 | |
| 17 | /* |
| 18 | * Nulls out lvalues for temporary variables that are never accessed later. This only |
| 19 | * nulls out the lvalue itself, it does not remove the corresponding instructions. |
| 20 | */ |
| 21 | export function pruneUnusedLValues(fn: ReactiveFunction): void { |
| 22 | const lvalues = new Map<DeclarationId, ReactiveInstruction>(); |
| 23 | visitReactiveFunction(fn, new Visitor(), lvalues); |
| 24 | for (const [, instr] of lvalues) { |
| 25 | instr.lvalue = null; |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * This pass uses DeclarationIds because the lvalue IdentifierId of a compound expression |
| 31 | * (ternary, logical, optional) in ReactiveFunction may not be the same as the IdentifierId |
| 32 | * of the phi, and which is referenced later. Keying by DeclarationId ensures we don't |
| 33 | * delete lvalues for identifiers that are used. |
| 34 | * |
| 35 | * TODO LeaveSSA: once we use HIR everywhere, this can likely move back to using IdentifierId |
| 36 | */ |
| 37 | type LValues = Map<DeclarationId, ReactiveInstruction>; |
| 38 | |
| 39 | class Visitor extends ReactiveFunctionVisitor<LValues> { |
| 40 | override visitPlace(id: InstructionId, place: Place, state: LValues): void { |
| 41 | state.delete(place.identifier.declarationId); |
| 42 | } |
| 43 | override visitInstruction( |
| 44 | instruction: ReactiveInstruction, |
| 45 | state: LValues, |
| 46 | ): void { |
| 47 | this.traverseInstruction(instruction, state); |
| 48 | if ( |
| 49 | instruction.lvalue !== null && |
| 50 | instruction.lvalue.identifier.name === null |
| 51 | ) { |
| 52 | state.set(instruction.lvalue.identifier.declarationId, instruction); |
| 53 | } |
| 54 | } |
| 55 | } |