From 17c023383b8fbb2c2d2ad17e1d0f74c1eb27ff7a Mon Sep 17 00:00:00 2001 From: Forest Belton Date: Wed, 15 Sep 2021 14:26:43 -0400 Subject: [PATCH] Build interference graph --- lib/data/graph.ts | 6 +++ lib/regalloc.ts | 63 +++++++++++++++++++++++++ test/{live.spec.ts => regalloc.spec.ts} | 18 ++++++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 lib/regalloc.ts rename test/{live.spec.ts => regalloc.spec.ts} (65%) diff --git a/lib/data/graph.ts b/lib/data/graph.ts index 804d1a8..ada175a 100644 --- a/lib/data/graph.ts +++ b/lib/data/graph.ts @@ -18,6 +18,10 @@ export const createGraph = (cons: (v: AddVertex, e: AddEdge) => void): Gra const g: Graph = { numVertices: 0, numEdges: 0, vertices: {}, edges: {} } const addVertex = (name: string, v: V) => { + if (typeof g.vertices[name] !== "undefined") { + return + } + g.vertices[name] = v g.edges[name] = new Set() g.numVertices++ @@ -50,6 +54,8 @@ export const neighbors = (g: Graph, name: string): Set => { export const vertices = (g: Graph): Set => new Set(Object.keys(g.vertices)) +export const edgeConnects = (g: Graph, v1: string, v2: string): boolean => g.edges[v1].has(v2) + export const maxCardinalitySearch = (g: Graph): Array => { const weights: { [s: string]: number } = {} const ordering: Array = [] diff --git a/lib/regalloc.ts b/lib/regalloc.ts new file mode 100644 index 0000000..c108df3 --- /dev/null +++ b/lib/regalloc.ts @@ -0,0 +1,63 @@ +import { createGraph, Graph } from "./data/graph" + +import type { Loc } from "./ir/loc" +import type { SSA } from "./ir/ssa" + +export type LivenessInfo = Array> + +export const liveness = (block: Array): LivenessInfo => { + const info: LivenessInfo = [] + + info[block.length] = new Set() + for (let i = block.length - 1; i >= 0; --i) { + const insn = block[i] + const last = info[i + 1] + + info[i] = new Set() + + if (typeof insn.source !== "number") { + info[i].add(insn.source) + } + + if ("source1" in insn && typeof insn.source1 !== "number") { + info[i].add(insn.source1) + } + + last.forEach(loc => { + if (loc.toString() === insn.dest.toString()) { + return + } + + info[i].add(loc) + }) + } + + return info +} + +export const locations = (block: Array): Set => { + const ls: Set = new Set() + + block.forEach(ssa => { + if ("source1" in ssa && typeof ssa.source1 !== "number") { + ls.add(ssa.source1) + } else if (typeof ssa.source !== "number") { + ls.add(ssa.source) + } + }) + + return ls +} + +export const interference = (block: Array, live: LivenessInfo): Graph => + createGraph((v, e) => { + block.forEach((ssa, i) => + live[i + 1].forEach(u => { + if (ssa.dest.toString() !== u.toString()) { + v(ssa.dest.toString(), ssa.dest) + v(u.toString(), u) + e(ssa.dest.toString(), u.toString()) + } + }) + ) + }) diff --git a/test/live.spec.ts b/test/regalloc.spec.ts similarity index 65% rename from test/live.spec.ts rename to test/regalloc.spec.ts index f998cdc..8e684f1 100644 --- a/test/live.spec.ts +++ b/test/regalloc.spec.ts @@ -1,8 +1,9 @@ import { expect } from "chai" +import { edgeConnects } from "../lib/data/graph" import { Loc } from "../lib/ir/loc" import type { SSA } from "../lib/ir/ssa" -import { liveness } from "../lib/live" +import { interference, liveness } from "../lib/regalloc" describe("liveness", () => { it("computes liveness", () => { @@ -26,3 +27,18 @@ describe("liveness", () => { expect(info[4]).to.deep.equal(new Set([y[0], x[2]])) }) }) + +describe("interference", () => { + it("computes interference", () => { + const block: Array = [ + { dest: Loc.vari("a"), source: 7 }, + { dest: Loc.vari("b"), source: 3 }, + { dest: Loc.vari("x"), source: Loc.vari("a") } + ] + + const info = liveness(block) + const g = interference(block, info) + + expect(edgeConnects(g, "a", "b")).to.be.true + }) +})