Scaffolding for ExpressionStatement instruction kind
Adds an `ExpressionStatement` instruction variant to model values that are otherwise "unused" but which we don't want to remove. The next diff changes BuildHIR to use this where appropriate.
Joe Savona committed
Apr 26, 2023 at 11:27 UTC
2cb1c723051378a3e94bec445f135a457d93f04f
9 files changed
+35
-2
compiler/forget/src/HIR/HIR.ts
+8
@@ -702,6 +702,14 @@ export type InstructionValue =
702
value: Place; // the collection
703
loc: SourceLocation;
704
}
705
+ // Represents a value that is unused but which we want to ensure is not dropped
706
+ // Examples include logical or ternary expressions that appear as expression statements,
707
+ // that appear only for their side effects
708
+ | {
709
+ kind: "ExpressionStatement";
710
+ value: Place;
711
+ loc: SourceLocation;
712
+ }
713
/**
714
* Catch-all for statements such as type imports, nested class declarations, etc
715
* which are not directly represented, but included for completeness and to allow
compiler/forget/src/HIR/PrintHIR.ts
+4
@@ -474,6 +474,10 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
474
value = `NextIterableOf ${printPlace(instrValue.value)}`;
475
break;
476
}
477
+ case "ExpressionStatement": {
478
+ value = `ExpressionStatement ${printPlace(instrValue.value)}`;
479
+ break;
480
+ }
481
default: {
482
assertExhaustive(
483
instrValue,
compiler/forget/src/HIR/visitors.ts
+8
@@ -180,6 +180,10 @@ export function* eachInstructionValueOperand(
180
yield instrValue.value;
181
break;
182
}
183
+ case "ExpressionStatement": {
184
+ yield instrValue.value;
185
+ break;
186
+ }
187
case "RegExpLiteral":
188
case "LoadGlobal":
189
case "UnsupportedNode":
@@ -443,6 +447,10 @@ export function mapInstructionOperands(
447
instrValue.value = fn(instrValue.value);
448
break;
449
}
450
+ case "ExpressionStatement": {
451
+ instrValue.value = fn(instrValue.value);
452
+ break;
453
+ }
454
case "RegExpLiteral":
455
case "LoadGlobal":
456
case "UnsupportedNode":
compiler/forget/src/Inference/InferReferenceEffects.ts
+1
@@ -807,6 +807,7 @@ function inferBlock(
807
state.alias(lvalue, instrValue.value);
808
continue;
809
}
810
+ case "ExpressionStatement":
811
case "TypeCastExpression": {
812
// A type cast expression has no effect at runtime, so it's equivalent to a raw
813
// identifier:
compiler/forget/src/Optimization/DeadCodeElimination.ts
+5
@@ -190,6 +190,11 @@ function pruneableValue(value: InstructionValue, state: State): boolean {
190
}
191
return true;
192
}
193
+ case "ExpressionStatement": {
194
+ // We create ExpressionStatements specifically for expressions that would otherwise
195
+ // be dropped but which we don't want to eliminate.
196
+ return false;
197
+ }
198
case "Await":
199
case "CallExpression":
200
case "ComputedDelete":
compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+4
@@ -996,6 +996,10 @@ function codegenInstructionValue(
996
value = codegenPlace(cx, instrValue.value);
997
break;
998
}
999
+ case "ExpressionStatement": {
1000
+ value = codegenPlace(cx, instrValue.value);
1001
+ break;
1002
+ }
1003
case "DeclareLocal":
1004
case "Destructure":
1005
case "StoreLocal": {
compiler/forget/src/ReactiveScopes/InferReactiveScopeVariables.ts
+2
-1
@@ -234,7 +234,8 @@ function mayAllocate(value: InstructionValue): boolean {
234
case "UnaryExpression":
235
case "TemplateLiteral":
236
case "Primitive":
237
- case "NextIterableOf": {
237
+ case "NextIterableOf":
238
+ case "ExpressionStatement": {
239
return false;
240
}
241
case "RegExpLiteral":
compiler/forget/src/ReactiveScopes/PruneNonEscapingScopes.ts
+2
-1
@@ -436,7 +436,8 @@ function computeMemoizationInputs(
436
}
437
case "Await":
438
case "TypeCastExpression":
439
- case "NextIterableOf": {
439
+ case "NextIterableOf":
440
+ case "ExpressionStatement": {
441
return {
442
// Indirection for the inner value, memoized if the value is
443
lvalues:
compiler/forget/src/TypeInference/InferTypes.ts
+1
@@ -210,6 +210,7 @@ function* generateInstructionTypes(
210
case "TemplateLiteral":
211
case "Await":
212
case "NextIterableOf":
213
+ case "ExpressionStatement":
214
case "UnsupportedNode":
215
break;
216
default: