@samitouri / QOS-React-2 / commits / df8945b684

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 }