Skip to content

Commit

Permalink
[test] Refactor SsaBlockOrderTest to use lib/test and remove OldUnitTest
Browse files Browse the repository at this point in the history
  • Loading branch information
titzer committed Sep 5, 2024
1 parent 829a842 commit bb727a0
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 180 deletions.
158 changes: 80 additions & 78 deletions aeneas/test/SsaBlockOrderTest.v3
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
def TEST = UnitTest.new("SsaBlockOrder", testBlockOrder);
def T = UnitTests.register;
def X_ = void(
T("order:test", test_order),
()
);

var graph: SsaGraph = SsaGraph.new(null, null);
def testBlockOrder() {
def test_order(t: Tester) {
def test = SsaBlockOrderTester.new(t).test;
var n = SsaBlock.new;
var n0 = graph.startBlock,n1=n(),n2=n(),n3=n(),n4=n(),n5=n(),n6=n(),n7=n(),n8=n(),n9=n();
var n10=n(),n11=n(),n12=n(),n13=n(),n14=n(),n15=n(),n16=n(),n17=n(),n18=n(),n19=n();
Expand Down Expand Up @@ -473,91 +479,87 @@ test([(n0,n6),(n0,n1),(n1,n3),(n1,n2),(n2,n3),(n3,n4),(n3,n5),(n4,n5),(n5,n6),(n
// -- end test graphs ---------------
}

def test(g: Array<(SsaBlock, SsaBlock)>) {
// build the graph by adding all the edges
build(g);
var order = SsaBlockOrder.new(graph);
var blocks = order.order;
for (i = 0; i < blocks.length; i++) {
var s = blocks[i].block, edges = s.succs();
for (j = 0; j < edges.length; j++) {
var d = edges[j].dest;
if (s.mark > d.mark) {
var di = blocks[d.mark];
if (di.loop == null) error(g, order, "blocks are not topologically ordered");
class SsaBlockOrderTester(t: Tester) {
def test(g: Array<(SsaBlock, SsaBlock)>) {
// build the graph by adding all the edges
build(g);
var order = SsaBlockOrder.new(graph);
var blocks = order.order;
for (i = 0; i < blocks.length; i++) {
var s = blocks[i].block, edges = s.succs();
for (j = 0; j < edges.length; j++) {
var d = edges[j].dest;
if (s.mark > d.mark) {
var di = blocks[d.mark];
if (di.loop == null) error(g, order, "blocks are not topologically ordered");
}
}
}
}
if (order.loops != null) {
for (i = 0; i < order.loops.length; i++) {
var l = order.loops[i];
for (e = l.exits; e != null; e = e.tail) {
if (order.isInLoop(e.head.dest, l.index)) error(g, order, "loop exit is within loop");
if (order.loops != null) {
for (i = 0; i < order.loops.length; i++) {
var l = order.loops[i];
for (e = l.exits; e != null; e = e.tail) {
if (order.isInLoop(e.head.dest, l.index)) error(g, order, "loop exit is within loop");
}
}
}
clear(g);
}
clear(g);
}

def error(g: Array<(SsaBlock, SsaBlock)>, order: SsaBlockOrder, msg: string) {
order.print();
TEST.print("digraph {\n");
for (i = 0; i < g.length; i++) {
TEST.print(Strings.format2("\"#%d\" -> \"#%d\"\n", g[i].0.uid, g[i].1.uid));
}
TEST.print("}\n");
TEST.error(msg);
}

def testGraph(g: Array<(SsaBlock, SsaBlock)>, r: Array<SsaBlock>) {
build(g);
var order = SsaBlockOrder.new(graph);
var blocks = order.order;
// check the order matches the expected order
if (blocks.length != r.length) emitError(order, r);
for (i = 0; i < blocks.length; i++) {
if (blocks[i].block != r[i]) emitError(order, r);
def error(g: Array<(SsaBlock, SsaBlock)>, order: SsaBlockOrder, msg: string) {
order.print();
System.puts("digraph {\n");
for (i = 0; i < g.length; i++) {
System.puts(Strings.format2("\"#%d\" -> \"#%d\"\n", g[i].0.uid, g[i].1.uid));
}
System.puts("}\n");
t.fail(msg);
}
clear(g);
}

def emitError(order: SsaBlockOrder, r: Array<SsaBlock>) {
for (i = 0; i < r.length; i++) {
if (i > 0) TEST.print(", ");
Terminal.putd(r[i].uid);
def testGraph(g: Array<(SsaBlock, SsaBlock)>, r: Array<SsaBlock>) {
build(g);
var order = SsaBlockOrder.new(graph);
var blocks = order.order;
// check the order matches the expected order
if (blocks.length != r.length) emitError(order, r);
for (i = 0; i < blocks.length; i++) {
if (blocks[i].block != r[i]) emitError(order, r);
}
clear(g);
}
var blocks = order.order;
for (i = 0; i < blocks.length; i++) {
if (i > 0) TEST.print(", ");
Terminal.putd(blocks[i].block.uid);
def emitError(order: SsaBlockOrder, r: Array<SsaBlock>) {
for (i = 0; i < r.length; i++) {
if (i > 0) System.puts(", ");
Terminal.putd(r[i].uid);
}
var blocks = order.order;
for (i = 0; i < blocks.length; i++) {
if (i > 0) System.puts(", ");
Terminal.putd(blocks[i].block.uid);
}
t.fail("incorrect block order");
}
TEST.error("incorrect block order");
}

def build(g: Array<(SsaBlock, SsaBlock)>) {
// build the graph by adding all the edges
for (i = 0; i < g.length; i++) {
var x = g[i].0, y = g[i].1;
var xe = x.end();
if (xe == null) {
xe = SsaThrow.new(null, V3Exception.Unimplemented);
x.append(xe);
def build(g: Array<(SsaBlock, SsaBlock)>) {
// build the graph by adding all the edges
for (i = 0; i < g.length; i++) {
var x = g[i].0, y = g[i].1;
var xe = x.end();
if (xe == null) {
xe = SsaThrow.new(null, V3Exception.Unimplemented);
x.append(xe);
}
xe.succs = Arrays.prepend(SsaCfEdge.new(xe, y), xe.succs);
x.mark = y.mark = -1;
}
xe.succs = Arrays.prepend(SsaCfEdge.new(xe, y), xe.succs);
x.mark = y.mark = -1;
}
}

def clear(g: Array<(SsaBlock, SsaBlock)>) {
// clear all edges in the graph
for (i = 0; i < g.length; i++) {
var x = g[i].0, y = g[i].1;
x.preds = Ssa.NO_CF_EDGES;
y.preds = Ssa.NO_CF_EDGES;
if (x.end() != null) x.end().succs = Ssa.NO_CF_EDGES;
if (y.end() != null) y.end().succs = Ssa.NO_CF_EDGES;
x.mark = -1;
y.mark = -1;
def clear(g: Array<(SsaBlock, SsaBlock)>) {
// clear all edges in the graph
for (i = 0; i < g.length; i++) {
var x = g[i].0, y = g[i].1;
x.preds = Ssa.NO_CF_EDGES;
y.preds = Ssa.NO_CF_EDGES;
if (x.end() != null) x.end().succs = Ssa.NO_CF_EDGES;
if (y.end() != null) y.end().succs = Ssa.NO_CF_EDGES;
x.mark = -1;
y.mark = -1;
}
}
}

109 changes: 7 additions & 102 deletions aeneas/test/UnitTest.v3
Original file line number Diff line number Diff line change
@@ -1,104 +1,9 @@
class UnitTest(name: string, run: void -> void) {
var output = StringBuilder.new();
new() {
OldUnitTests.register(this);
}
def print(msg: string) {
output.puts(msg);
output.ln();
}
def eq<T>(expected: T, result: T) {
var fail = expected != result;
if (fail && string.?(expected)) {
fail = !Strings.equal(string.!(expected), string.!(result));
}
if (fail) {
var buf = StringBuilder.new().puts("expected ");
put1(buf, expected);
buf.puts(", result = ");
put1(buf, result);
error(buf.toString());
}
}
def put1<T>(buf: StringBuilder, t: T) -> StringBuilder {
match (t) {
x: bool => buf.putz(x);
x: long => buf.putd(x);
x: u64 => buf.putd(x);
x: string => buf.puts(x);
x: (StringBuilder -> StringBuilder) => return x(buf);
_ => buf.puts("<unknown value type>");
}
return buf;
}
def eqArray<T>(expected: Array<T>, result: Array<T>) {
if (result == expected) return;
if (result == null) return failArray(expected, result);
if (result.length != expected.length) return failArray(expected, result);
for (i < expected.length) if (expected[i] != result[i]) failArray(expected, result);
}
def failArray<T>(expected: Array<T>, result: Array<T>) {
var buf = StringBuilder.new();
buf.puts("expected [");
var prev = false;
for (e in expected) {
if (prev) buf.csp();
put1(buf, e);
}
buf.puts("], result = ");
if (result == null) {
buf.puts("null");
} else {
buf.puts("[");
var prev = false;
for (e in result) {
if (prev) buf.csp();
put1(buf, e);
}
buf.puts("]");
}
error(buf.toString());
}
def nonnull<T>(val: T) {
var n: T;
if (val == n) error("expected nonnull value");
}
def error(msg: string) {
System.error(Strings.format1("%sTest error", name), msg);
}
def error1<T>(msg: string, param: T) {
error(Strings.format1(msg, param));
}
def error2<T, U>(msg: string, param1: T, param2: U) {
error(Strings.format2(msg, param1, param2));
}
def error3<T, U, V>(msg: string, param1: T, param2: U, param3: V) {
error(Strings.format3(msg, param1, param2, param3));
}
}
component OldUnitTests {
var tests: List<UnitTest>;
var count = 0;
new() {
Aeneas.startup = run;
}
def register(x: UnitTest) {
tests = List.new(x, tests);
count++;
}
def run() {
UnitTests.run([]);
var progress = ProgressPrinter.new(count);
for (l = Lists.reverse(tests); l != null; l = l.tail) {
progress.begin(l.head.name);
l.head.run();
l.head.output.reset();
progress.pass();
}
if (progress.passed == count) {
Terminal.put("Unit tests ");
Terminal.green("passed", ());
Terminal.put(".\n");
}
def X_ = Aeneas.startup = run;
def run() {
var result = UnitTests.run([]);
if (result == 0) {
Terminal.put("Unit tests ");
Terminal.green("passed", ());
Terminal.put(".\n");
}
}

0 comments on commit bb727a0

Please sign in to comment.