Add and use mapInstructionOperands()
Joe Savona committed
Nov 8, 2022 at 14:46 UTC
22d1481125f948b051de7a0e4a2f105b2ba7e089
2 files changed
+70
-74
compiler/forget/src/HIR/EnterSSA.ts
+7
-74
@@ -1,16 +1,12 @@
1
-import { assertExhaustive } from "../Common/utils";
1
import { invariant } from "../CompilerError";
3
-import {
4
- BasicBlock,
5
- HIRFunction,
6
- Identifier,
7
- Instruction,
8
- Phi,
9
- Place,
10
-} from "./HIR";
2
+import { BasicBlock, HIRFunction, Identifier, Phi, Place } from "./HIR";
3
import { Environment } from "./HIRBuilder";
4
import { printIdentifier } from "./PrintHIR";
13
-import { eachTerminalSuccessor, mapTerminalOperands } from "./visitors";
5
+import {
6
+ eachTerminalSuccessor,
7
+ mapInstructionOperands,
8
+ mapTerminalOperands,
9
+} from "./visitors";
10
11
type IncompletePhi = {
12
oldId: Identifier;
@@ -186,7 +182,7 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
182
}
183
184
for (const instr of block.instructions) {
189
- rewriteInstructionUses(instr, builder);
185
+ mapInstructionOperands(instr, (place) => builder.getPlace(place));
186
187
if (instr.lvalue != null) {
188
const oldPlace = instr.lvalue.place;
@@ -217,66 +213,3 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
213
}
214
}
215
}
220
-
221
-function rewriteInstructionUses(instr: Instruction, builder: SSABuilder) {
222
- const instrValue = instr.value;
223
-
224
- switch (instrValue.kind) {
225
- case "BinaryExpression": {
226
- instrValue.left = builder.getPlace(instrValue.left);
227
- instrValue.right = builder.getPlace(instrValue.right);
228
- break;
229
- }
230
- case "Identifier": {
231
- instr.value = builder.getPlace(instrValue);
232
- break;
233
- }
234
- case "NewExpression":
235
- case "CallExpression": {
236
- instrValue.callee = builder.getPlace(instrValue.callee);
237
- instrValue.args = instrValue.args.map((arg) => builder.getPlace(arg));
238
- break;
239
- }
240
- case "UnaryExpression": {
241
- instrValue.value = builder.getPlace(instrValue.value);
242
- break;
243
- }
244
- case "JsxExpression": {
245
- instrValue.tag = builder.getPlace(instrValue.tag);
246
- for (const [prop, place] of instrValue.props) {
247
- instrValue.props.set(prop, builder.getPlace(place));
248
- }
249
- if (instrValue.children) {
250
- instrValue.children = instrValue.children.map((p) =>
251
- builder.getPlace(p)
252
- );
253
- }
254
- break;
255
- }
256
- case "ObjectExpression": {
257
- if (instrValue.properties !== null) {
258
- const props = instrValue.properties;
259
- for (const [prop, place] of props) {
260
- props.set(prop, builder.getPlace(place));
261
- }
262
- }
263
- break;
264
- }
265
- case "ArrayExpression": {
266
- instrValue.elements = instrValue.elements.map((e) => builder.getPlace(e));
267
- break;
268
- }
269
- case "JsxFragment": {
270
- instrValue.children = instrValue.children.map((e) => builder.getPlace(e));
271
- break;
272
- }
273
- case "OtherStatement":
274
- case "Primitive":
275
- case "JSXText": {
276
- break;
277
- }
278
- default: {
279
- assertExhaustive(instrValue, "Unexpected instruction kind");
280
- }
281
- }
282
-}
compiler/forget/src/HIR/visitors.ts
+63
@@ -66,6 +66,69 @@ export function* eachInstructionOperand(instr: Instruction): Iterable<Place> {
66
}
67
}
68
69
+export function mapInstructionOperands(
70
+ instr: Instruction,
71
+ fn: (place: Place) => Place
72
+): void {
73
+ const instrValue = instr.value;
74
+ switch (instrValue.kind) {
75
+ case "BinaryExpression": {
76
+ instrValue.left = fn(instrValue.left);
77
+ instrValue.right = fn(instrValue.right);
78
+ break;
79
+ }
80
+ case "Identifier": {
81
+ instr.value = fn(instrValue);
82
+ break;
83
+ }
84
+ case "NewExpression":
85
+ case "CallExpression": {
86
+ instrValue.callee = fn(instrValue.callee);
87
+ instrValue.args = instrValue.args.map((arg) => fn(arg));
88
+ break;
89
+ }
90
+ case "UnaryExpression": {
91
+ instrValue.value = fn(instrValue.value);
92
+ break;
93
+ }
94
+ case "JsxExpression": {
95
+ instrValue.tag = fn(instrValue.tag);
96
+ for (const [prop, place] of instrValue.props) {
97
+ instrValue.props.set(prop, fn(place));
98
+ }
99
+ if (instrValue.children) {
100
+ instrValue.children = instrValue.children.map((p) => fn(p));
101
+ }
102
+ break;
103
+ }
104
+ case "ObjectExpression": {
105
+ if (instrValue.properties !== null) {
106
+ const props = instrValue.properties;
107
+ for (const [prop, place] of props) {
108
+ props.set(prop, fn(place));
109
+ }
110
+ }
111
+ break;
112
+ }
113
+ case "ArrayExpression": {
114
+ instrValue.elements = instrValue.elements.map((e) => fn(e));
115
+ break;
116
+ }
117
+ case "JsxFragment": {
118
+ instrValue.children = instrValue.children.map((e) => fn(e));
119
+ break;
120
+ }
121
+ case "OtherStatement":
122
+ case "Primitive":
123
+ case "JSXText": {
124
+ break;
125
+ }
126
+ default: {
127
+ assertExhaustive(instrValue, "Unexpected instruction kind");
128
+ }
129
+ }
130
+}
131
+
132
/**
133
* Maps a terminal node's block assignments using the provided function.
134
*/