import { HIRFunction, Identifier } from "../HIR/HIR";
import { inferAliases } from "./InferAlias";
import { inferAliasForPhis } from "./InferAliasForPhis";
import { inferAliasForStores } from "./InferAliasForStores";
import { inferMutableLifetimes } from "./InferMutableLifetimes";
import { inferMutableRangesForAlias } from "./InferMutableRangesForAlias";
import { inferTryCatchAliases } from "./InferTryCatchAliases";
export function inferMutableRanges(ir: HIRFunction): void {
inferMutableLifetimes(ir, false);
const aliases = inferAliases(ir);
inferTryCatchAliases(ir, aliases);
let prevAliases: Map<Identifier, Identifier> = aliases.canonicalize();
while (true) {
inferMutableRangesForAlias(ir, aliases);
inferAliasForStores(ir, aliases);
inferAliasForPhis(ir, aliases);
const nextAliases = aliases.canonicalize();
if (areEqualMaps(prevAliases, nextAliases)) {
break;
}
prevAliases = nextAliases;
}
inferMutableLifetimes(ir, true);
inferMutableRangesForAlias(ir, aliases);
}
function areEqualMaps<T>(a: Map<T, T>, b: Map<T, T>): boolean {
if (a.size !== b.size) {
return false;
}
for (const [key, value] of a) {
if (!b.has(key)) {
return false;
}
if (b.get(key) !== value) {
return false;
}
}
return true;
}