From 4e74d85056bd7df4478cbc5d1e7d2f4a6bee3b57 Mon Sep 17 00:00:00 2001 From: Morgan Phillips Date: Thu, 14 Jul 2016 12:22:08 -0700 Subject: [PATCH 1/2] Id CFG graphs by function name --- cranelift/src/tools/print_cfg.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cranelift/src/tools/print_cfg.rs b/cranelift/src/tools/print_cfg.rs index e55033832a..fc85cbebec 100644 --- a/cranelift/src/tools/print_cfg.rs +++ b/cranelift/src/tools/print_cfg.rs @@ -35,7 +35,7 @@ impl CFGPrinter { pub fn print(&mut self, func: &Function) -> Result<(), String> { self.level = 0; - self.header(); + self.header(func); self.push_indent(); self.ebb_subgraphs(func); let cfg = ControlFlowGraph::new(&func); @@ -87,8 +87,8 @@ impl CFGPrinter { self.append("\n"); } - fn header(&mut self) { - self.append("digraph "); + fn header(&mut self, func: &Function) { + self.append(&format!("digraph {} ", func.name)); self.open_paren(); self.newline(); self.push_indent(); From 41d4cdba46855bd11c441c55dad59173bc5bd75c Mon Sep 17 00:00:00 2001 From: Morgan Phillips Date: Thu, 14 Jul 2016 13:43:11 -0700 Subject: [PATCH 2/2] Add print-cfg tests --- cranelift/test-all.sh | 3 ++- cranelift/tests/cfg/README.rst | 14 ++++++++++ cranelift/tests/cfg/loop.cton | 30 ++++++++++++++++++++++ cranelift/tests/cfg/run.sh | 38 ++++++++++++++++++++++++++++ cranelift/tests/cfg/traps_early.cton | 18 +++++++++++++ cranelift/tests/cfg/unused_node.cton | 16 ++++++++++++ 6 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 cranelift/tests/cfg/README.rst create mode 100644 cranelift/tests/cfg/loop.cton create mode 100755 cranelift/tests/cfg/run.sh create mode 100644 cranelift/tests/cfg/traps_early.cton create mode 100644 cranelift/tests/cfg/unused_node.cton diff --git a/cranelift/test-all.sh b/cranelift/test-all.sh index 502966e55d..31638a6db3 100755 --- a/cranelift/test-all.sh +++ b/cranelift/test-all.sh @@ -7,7 +7,7 @@ # - Make a debug build of all crates. # - Make a release build of cton-util. # - Run file-level tests with the release build of cton-util. -# +# # All tests run by this script should be passing at all times. # Exit immediately on errors. @@ -35,5 +35,6 @@ export CTONUTIL="$topdir/src/tools/target/release/cton-util" echo ====== Parser tests ====== cd "$topdir/tests" parser/run.sh +cfg/run.sh echo ====== OK ====== diff --git a/cranelift/tests/cfg/README.rst b/cranelift/tests/cfg/README.rst new file mode 100644 index 0000000000..c1ee4b1fa3 --- /dev/null +++ b/cranelift/tests/cfg/README.rst @@ -0,0 +1,14 @@ +CFG tests +============ + +This directory contains test cases for the Cretonne cfg printer. + +Each test case consists of a `foo.cton` input file annotated with its expected connections. +Annotations are comments of the form: `ebbx:insty -> ebbz` where ebbx is connected to ebbz via +a branch or jump instruction at line y. Instructions are labeled by line number starting from zero: `inst0` .. `instn`. + + +Each input file is run through the `cton-util print-cfg` command and the +output is compared against the specially formatted comments to ensure that +expected connections exist. This scheme allows for changes to graph style +without the need to update tests. diff --git a/cranelift/tests/cfg/loop.cton b/cranelift/tests/cfg/loop.cton new file mode 100644 index 0000000000..73ad1c4b6a --- /dev/null +++ b/cranelift/tests/cfg/loop.cton @@ -0,0 +1,30 @@ +; For testing cfg generation. This code is nonsense. + +function nonsense(i32, i32) -> f32 { + +ebb0(v1: i32, v2: i32): + v3 = f64const 0x0.0 + brz v2, ebb2 ;;;; ebb0:inst1 -> ebb2 + v4 = iconst.i32 0 + jump ebb1(v4) ;;;; ebb0:inst3 -> ebb1 + +ebb1(v5: i32): + v6 = imul_imm v5, 4 + v7 = iadd v1, v6 + v8 = f32const 0.0 + v9 = f32const 0.0 + v10 = f32const 0.0 + v11 = fadd v9, v10 + v12 = iadd_imm v5, 1 + v13 = icmp ult, v12, v2 + brnz v13, ebb1(v12) ;;;; ebb1:inst12 -> ebb1 + v14 = f64const 0.0 + v15 = f64const 0.0 + v16 = fdiv v14, v15 + v17 = f32const 0.0 + return v17 + +ebb2: + v100 = f32const 0.0 + return v100 +} diff --git a/cranelift/tests/cfg/run.sh b/cranelift/tests/cfg/run.sh new file mode 100755 index 0000000000..2230d4c1ca --- /dev/null +++ b/cranelift/tests/cfg/run.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Go to tests directory. +cd $(dirname "$0")/.. + +# The path to cton-util should be in $CTONUTIL. +if [ -z "$CTONUTIL" ]; then + CTONUTIL=../src/tools/target/debug/cton-util +fi + +if [ ! -x "$CTONUTIL" ]; then + echo "Can't fund executable cton-util: $CTONUTIL" 1>&2 + exit 1 +fi + +declare -a fails + +for testcase in $(find cfg -name '*.cton'); do + annotations=$(cat $testcase | awk /';;;;'/ | awk -F ";;;;" '{print $2}' | sort) + connections=$("${CTONUTIL}" print-cfg "$testcase" | awk /"->"/ | sort) + if diff -u <(echo $annotations) <(echo $connections); then + echo OK $testcase + else + fails=(${fails[@]} "$testcase") + echo FAIL $testcase + fi +done + +if [ ${#fails[@]} -ne 0 ]; then + echo + echo Failures: + for f in "${fails[@]}"; do + echo " $f" + done + exit 1 +else + echo "All passed" +fi diff --git a/cranelift/tests/cfg/traps_early.cton b/cranelift/tests/cfg/traps_early.cton new file mode 100644 index 0000000000..6993cc128e --- /dev/null +++ b/cranelift/tests/cfg/traps_early.cton @@ -0,0 +1,18 @@ +; For testing cfg generation. This code explores the implications of encountering +; a terminating instruction before any connections have been made. + +function nonsense(i32) { + +ebb0(v1: i32): + trap + brnz v1, ebb2 ;;;; ebb0:inst1 -> ebb2 + jump ebb1 ;;;; ebb0:inst2 -> ebb1 + +ebb1: + v2 = iconst.i32 0 + v3 = iadd v1, v3 + jump ebb0(v3) ;;;; ebb1:inst5 -> ebb0 + +ebb2: + return v1 +} diff --git a/cranelift/tests/cfg/unused_node.cton b/cranelift/tests/cfg/unused_node.cton new file mode 100644 index 0000000000..3120ffbe68 --- /dev/null +++ b/cranelift/tests/cfg/unused_node.cton @@ -0,0 +1,16 @@ +; For testing cfg generation where some block is never reached. + +function not_reached(i32) -> i32 { + +ebb0(v0: i32): + brnz v0, ebb2 ;;;; ebb0:inst0 -> ebb2 + trap + +ebb1: + v1 = iconst.i32 1 + v2 = iadd v0, v1 + jump ebb0(v2) ;;;; ebb1:inst4 -> ebb0 + +ebb2: + return v0 +}