main
ts 55 lines 1.78 KB
Raw
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 }