Adds decoration to the verifier errors. (#375)
* Adds decoration to the verifier errors.
example:
function %bad(i32) fast {
ebb0(v0: i32):
brnz.i32 v0, ebb1
return
^~~~~~
verifier inst1: Internal return not allowed with return_at_end=1
ebb1:
trapz.i32 v0, user6
return
}
Fixes #68
This commit is contained in:
committed by
Dan Gohman
parent
c5aad1eb5f
commit
7bed3426a7
@@ -1,11 +1,15 @@
|
|||||||
//! Utility routines for pretty-printing error messages.
|
//! Utility routines for pretty-printing error messages.
|
||||||
|
|
||||||
use ir;
|
use ir;
|
||||||
|
use ir::entities::Inst;
|
||||||
|
use ir::function::Function;
|
||||||
use isa::TargetIsa;
|
use isa::TargetIsa;
|
||||||
use result::CodegenError;
|
use result::CodegenError;
|
||||||
|
use std::fmt;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::string::{String, ToString};
|
use std::string::{String, ToString};
|
||||||
use verifier::VerifierError;
|
use verifier::VerifierError;
|
||||||
|
use write::decorate_function;
|
||||||
|
|
||||||
/// Pretty-print a verifier error.
|
/// Pretty-print a verifier error.
|
||||||
pub fn pretty_verifier_error(
|
pub fn pretty_verifier_error(
|
||||||
@@ -13,15 +17,52 @@ pub fn pretty_verifier_error(
|
|||||||
isa: Option<&TargetIsa>,
|
isa: Option<&TargetIsa>,
|
||||||
err: &VerifierError,
|
err: &VerifierError,
|
||||||
) -> String {
|
) -> String {
|
||||||
let mut msg = err.to_string();
|
let mut w = String::new();
|
||||||
|
decorate_function(
|
||||||
|
&mut |w, func, isa, inst, indent| pretty_function_error(w, func, isa, inst, indent, err),
|
||||||
|
&mut w,
|
||||||
|
func,
|
||||||
|
isa,
|
||||||
|
).unwrap();
|
||||||
|
w
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pretty-print a function verifier error.
|
||||||
|
fn pretty_function_error(
|
||||||
|
w: &mut Write,
|
||||||
|
func: &Function,
|
||||||
|
isa: Option<&TargetIsa>,
|
||||||
|
cur_inst: Inst,
|
||||||
|
indent: usize,
|
||||||
|
err: &VerifierError,
|
||||||
|
) -> fmt::Result {
|
||||||
match err.location {
|
match err.location {
|
||||||
ir::entities::AnyEntity::Inst(inst) => {
|
ir::entities::AnyEntity::Inst(inst) => {
|
||||||
write!(msg, "\n{}: {}\n\n", inst, func.dfg.display_inst(inst, isa)).unwrap()
|
if inst == cur_inst {
|
||||||
|
write!(
|
||||||
|
w,
|
||||||
|
"{1:0$}{2}\n",
|
||||||
|
indent,
|
||||||
|
"",
|
||||||
|
func.dfg.display_inst(cur_inst, isa)
|
||||||
|
)?;
|
||||||
|
write!(w, "{1:0$}{2}", indent, "", "^")?;
|
||||||
|
for _c in cur_inst.to_string().chars() {
|
||||||
|
write!(w, "~")?;
|
||||||
}
|
}
|
||||||
_ => msg.push('\n'),
|
write!(w, "\n\nverifier {}\n\n", err.to_string())
|
||||||
|
} else {
|
||||||
|
write!(
|
||||||
|
w,
|
||||||
|
"{1:0$}{2}\n",
|
||||||
|
indent,
|
||||||
|
"",
|
||||||
|
func.dfg.display_inst(cur_inst, isa)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => write!(w, "{}", "\n"),
|
||||||
}
|
}
|
||||||
write!(msg, "{}", func.display(isa)).unwrap();
|
|
||||||
msg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pretty-print a Cretonne error.
|
/// Pretty-print a Cretonne error.
|
||||||
|
|||||||
@@ -9,9 +9,39 @@ use packed_option::ReservedValue;
|
|||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
|
||||||
|
fn write_function_plain(
|
||||||
|
w: &mut Write,
|
||||||
|
func: &Function,
|
||||||
|
isa: Option<&TargetIsa>,
|
||||||
|
inst: Inst,
|
||||||
|
indent: usize,
|
||||||
|
) -> fmt::Result {
|
||||||
|
write_instruction(w, func, isa, inst, indent)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Write `func` to `w` as equivalent text.
|
/// Write `func` to `w` as equivalent text.
|
||||||
/// Use `isa` to emit ISA-dependent annotations.
|
/// Use `isa` to emit ISA-dependent annotations.
|
||||||
pub fn write_function(w: &mut Write, func: &Function, isa: Option<&TargetIsa>) -> fmt::Result {
|
pub fn write_function(w: &mut Write, func: &Function, isa: Option<&TargetIsa>) -> fmt::Result {
|
||||||
|
decorate_function(
|
||||||
|
&mut |w, func, isa, inst, indent| write_function_plain(w, func, isa, inst, indent),
|
||||||
|
w,
|
||||||
|
func,
|
||||||
|
isa,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes 'func' to 'w' as text.
|
||||||
|
/// write_function_plain is passed as 'closure' to print instructions as text.
|
||||||
|
/// pretty_function_error is passed as 'closure' to add error decoration.
|
||||||
|
pub fn decorate_function<
|
||||||
|
WL: FnMut(&mut Write, &Function, Option<&TargetIsa>, Inst, usize) -> fmt::Result,
|
||||||
|
>(
|
||||||
|
closure: &mut WL,
|
||||||
|
w: &mut Write,
|
||||||
|
func: &Function,
|
||||||
|
isa: Option<&TargetIsa>,
|
||||||
|
) -> fmt::Result {
|
||||||
let regs = isa.map(TargetIsa::register_info);
|
let regs = isa.map(TargetIsa::register_info);
|
||||||
let regs = regs.as_ref();
|
let regs = regs.as_ref();
|
||||||
|
|
||||||
@@ -23,7 +53,7 @@ pub fn write_function(w: &mut Write, func: &Function, isa: Option<&TargetIsa>) -
|
|||||||
if any {
|
if any {
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
}
|
}
|
||||||
write_ebb(w, func, isa, ebb)?;
|
decorate_ebb(closure, w, func, isa, ebb)?;
|
||||||
any = true;
|
any = true;
|
||||||
}
|
}
|
||||||
writeln!(w, "}}")
|
writeln!(w, "}}")
|
||||||
@@ -141,7 +171,15 @@ pub fn write_ebb_header(
|
|||||||
writeln!(w, "):")
|
writeln!(w, "):")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_ebb(w: &mut Write, func: &Function, isa: Option<&TargetIsa>, ebb: Ebb) -> fmt::Result {
|
pub fn decorate_ebb<
|
||||||
|
WL: FnMut(&mut Write, &Function, Option<&TargetIsa>, Inst, usize) -> fmt::Result,
|
||||||
|
>(
|
||||||
|
closure: &mut WL,
|
||||||
|
w: &mut Write,
|
||||||
|
func: &Function,
|
||||||
|
isa: Option<&TargetIsa>,
|
||||||
|
ebb: Ebb,
|
||||||
|
) -> fmt::Result {
|
||||||
// Indent all instructions if any encodings are present.
|
// Indent all instructions if any encodings are present.
|
||||||
let indent = if func.encodings.is_empty() && func.srclocs.is_empty() {
|
let indent = if func.encodings.is_empty() && func.srclocs.is_empty() {
|
||||||
4
|
4
|
||||||
@@ -151,8 +189,9 @@ pub fn write_ebb(w: &mut Write, func: &Function, isa: Option<&TargetIsa>, ebb: E
|
|||||||
|
|
||||||
write_ebb_header(w, func, isa, ebb, indent)?;
|
write_ebb_header(w, func, isa, ebb, indent)?;
|
||||||
for inst in func.layout.ebb_insts(ebb) {
|
for inst in func.layout.ebb_insts(ebb) {
|
||||||
write_instruction(w, func, isa, inst, indent)?;
|
closure(w, func, isa, inst, indent)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user