Browse Source

Build interference graph

master
Forest Belton 2 years ago
parent
commit
17c023383b
3 changed files with 86 additions and 1 deletions
  1. +6
    -0
      lib/data/graph.ts
  2. +63
    -0
      lib/regalloc.ts
  3. +17
    -1
      test/regalloc.spec.ts

+ 6
- 0
lib/data/graph.ts View File

@ -18,6 +18,10 @@ export const createGraph = (cons: (v: AddVertex, e: AddEdge) => void): Gra
const g: Graph<V> = { 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 = <V>(g: Graph<V>): Set<string> => new Set(Object.keys(g.vertices))
export const edgeConnects = <V>(g: Graph<V>, v1: string, v2: string): boolean => g.edges[v1].has(v2)
export const maxCardinalitySearch = <V>(g: Graph<V>): Array<string> => {
const weights: { [s: string]: number } = {}
const ordering: Array<string> = []

+ 63
- 0
lib/regalloc.ts View File

@ -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<Set<Loc>>
export const liveness = (block: Array<SSA>): 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<SSA>): Set<Loc> => {
const ls: Set<Loc> = 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<SSA>, live: LivenessInfo): Graph<Loc> =>
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())
}
})
)
})

test/live.spec.ts → test/regalloc.spec.ts View File

@ -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<SSA> = [
{ 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
})
})

Loading…
Cancel
Save