Visit terminal operands during alignment
Joe Savona committed
Jan 12, 2023 at 09:11 UTC
df8945b684cf7b6ba6205fee07fad19947ef7ad9
2 files changed
+36
-19
compiler/forget/src/ReactiveScopes/AlignReactiveScopesToBlockScopes.ts
+16
-6
@@ -15,8 +15,8 @@ import {
15
ScopeId,
16
} from "../HIR/HIR";
17
import { invariant } from "../Utils/CompilerError";
18
-import { getInstructionScope } from "./BuildReactiveBlocks";
19
-import { eachTerminalBlock } from "./visitors";
18
+import { getInstructionScope, getPlaceScope } from "./BuildReactiveBlocks";
19
+import { eachTerminalBlock, eachTerminalOperand } from "./visitors";
20
21
/**
22
* Note: this is the 2nd of 3 passes that determine how to break a function into discrete
@@ -81,13 +81,23 @@ function visitBlock(context: Context, block: ReactiveBlock): void {
81
if (id !== null) {
82
context.visitId(id);
83
}
84
- // TODO: visit terminal operands!
84
+ eachTerminalOperand(stmt.terminal, (operand) => {
85
+ const scope = getPlaceScope(id!, operand);
86
+ if (scope !== null) {
87
+ context.visitScope(scope);
88
+ }
89
+ });
90
eachTerminalBlock(
91
stmt.terminal,
92
(block) => {
93
context.enter(() => visitBlock(context, block));
94
},
90
- (valueBlock) => visitValueBlock(context, valueBlock, id!)
95
+ (valueBlock) => {
96
+ context.enter(
97
+ () => visitValueBlock(context, valueBlock, id!),
98
+ "value"
99
+ );
100
+ }
101
);
102
break;
103
}
@@ -143,8 +153,8 @@ class Context {
153
// the above data structures they're in, to avoid tracking the same scope twice.
154
#seenScopes: Set<ScopeId> = new Set();
155
146
- enter(fn: () => void): void {
147
- this.#blockScopes.push({ kind: "block", scopes: [] });
156
+ enter(fn: () => void, kind: "block" | "value" = "block"): void {
157
+ this.#blockScopes.push({ kind, scopes: [] });
158
fn();
159
const lastScope = this.#blockScopes.pop()!;
160
for (const scope of lastScope.scopes) {
compiler/forget/src/ReactiveScopes/BuildReactiveBlocks.ts
+20
-13
@@ -9,6 +9,7 @@ import invariant from "invariant";
9
import {
10
InstructionId,
11
makeInstructionId,
12
+ Place,
13
ReactiveBlock,
14
ReactiveFunction,
15
ReactiveInstruction,
@@ -100,24 +101,30 @@ export function getInstructionScope({
101
"Expected lvalues to not be null when assigning scopes. " +
102
"Pruning lvalues too early can result in missing scope information."
103
);
103
- if (
104
- lvalue.place.identifier.scope !== null &&
105
- isScopeActive(lvalue.place.identifier.scope, id)
106
- ) {
107
- return lvalue.place.identifier.scope;
108
- } else {
109
- for (const operand of eachInstructionValueOperand(value)) {
110
- if (
111
- operand.identifier.scope !== null &&
112
- isScopeActive(operand.identifier.scope, id)
113
- ) {
114
- return operand.identifier.scope;
115
- }
104
+ const lvalueScope = getPlaceScope(id, lvalue.place);
105
+ if (lvalueScope !== null) {
106
+ return lvalueScope;
107
+ }
108
+ for (const operand of eachInstructionValueOperand(value)) {
109
+ const operandScope = getPlaceScope(id, operand);
110
+ if (operandScope !== null) {
111
+ return operandScope;
112
}
113
}
114
return null;
115
}
116
117
+export function getPlaceScope(
118
+ id: InstructionId,
119
+ place: Place
120
+): ReactiveScope | null {
121
+ const scope = place.identifier.scope;
122
+ if (scope !== null && isScopeActive(scope, id)) {
123
+ return scope;
124
+ }
125
+ return null;
126
+}
127
+
128
function isScopeActive(scope: ReactiveScope, id: InstructionId): boolean {
129
return id >= scope.range.start && id < scope.range.end;
130
}