Visit terminal operands during alignment

This commit is contained in:
Joe Savona
2023-01-12 09:11:58 -08:00
parent 9e549e9417
commit df8945b684
2 changed files with 36 additions and 19 deletions
@@ -15,8 +15,8 @@ import {
ScopeId,
} from "../HIR/HIR";
import { invariant } from "../Utils/CompilerError";
import { getInstructionScope } from "./BuildReactiveBlocks";
import { eachTerminalBlock } from "./visitors";
import { getInstructionScope, getPlaceScope } from "./BuildReactiveBlocks";
import { eachTerminalBlock, eachTerminalOperand } from "./visitors";
/**
* 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 {
if (id !== null) {
context.visitId(id);
}
// TODO: visit terminal operands!
eachTerminalOperand(stmt.terminal, (operand) => {
const scope = getPlaceScope(id!, operand);
if (scope !== null) {
context.visitScope(scope);
}
});
eachTerminalBlock(
stmt.terminal,
(block) => {
context.enter(() => visitBlock(context, block));
},
(valueBlock) => visitValueBlock(context, valueBlock, id!)
(valueBlock) => {
context.enter(
() => visitValueBlock(context, valueBlock, id!),
"value"
);
}
);
break;
}
@@ -143,8 +153,8 @@ class Context {
// the above data structures they're in, to avoid tracking the same scope twice.
#seenScopes: Set<ScopeId> = new Set();
enter(fn: () => void): void {
this.#blockScopes.push({ kind: "block", scopes: [] });
enter(fn: () => void, kind: "block" | "value" = "block"): void {
this.#blockScopes.push({ kind, scopes: [] });
fn();
const lastScope = this.#blockScopes.pop()!;
for (const scope of lastScope.scopes) {
@@ -9,6 +9,7 @@ import invariant from "invariant";
import {
InstructionId,
makeInstructionId,
Place,
ReactiveBlock,
ReactiveFunction,
ReactiveInstruction,
@@ -100,24 +101,30 @@ export function getInstructionScope({
"Expected lvalues to not be null when assigning scopes. " +
"Pruning lvalues too early can result in missing scope information."
);
if (
lvalue.place.identifier.scope !== null &&
isScopeActive(lvalue.place.identifier.scope, id)
) {
return lvalue.place.identifier.scope;
} else {
for (const operand of eachInstructionValueOperand(value)) {
if (
operand.identifier.scope !== null &&
isScopeActive(operand.identifier.scope, id)
) {
return operand.identifier.scope;
}
const lvalueScope = getPlaceScope(id, lvalue.place);
if (lvalueScope !== null) {
return lvalueScope;
}
for (const operand of eachInstructionValueOperand(value)) {
const operandScope = getPlaceScope(id, operand);
if (operandScope !== null) {
return operandScope;
}
}
return null;
}
export function getPlaceScope(
id: InstructionId,
place: Place
): ReactiveScope | null {
const scope = place.identifier.scope;
if (scope !== null && isScopeActive(scope, id)) {
return scope;
}
return null;
}
function isScopeActive(scope: ReactiveScope, id: InstructionId): boolean {
return id >= scope.range.start && id < scope.range.end;
}