Add an ISA argument to dfg.display_inst().
Include ISA-specific annotations in tracing and error messages.
This commit is contained in:
@@ -127,7 +127,7 @@ impl SubTest for TestBinEmit {
|
||||
AnyEntity::Inst(inst) => {
|
||||
if let Some(prev) = bins.insert(inst, want) {
|
||||
return Err(format!("multiple 'bin:' directives on {}: '{}' and '{}'",
|
||||
func.dfg.display_inst(inst),
|
||||
func.dfg.display_inst(inst, isa),
|
||||
prev,
|
||||
want));
|
||||
}
|
||||
@@ -166,7 +166,7 @@ impl SubTest for TestBinEmit {
|
||||
encinfo.bytes(enc),
|
||||
"Inconsistent size for [{}] {}",
|
||||
encinfo.display(enc),
|
||||
func.dfg.display_inst(inst));
|
||||
func.dfg.display_inst(inst, isa));
|
||||
}
|
||||
|
||||
// Check against bin: directives.
|
||||
@@ -174,13 +174,13 @@ impl SubTest for TestBinEmit {
|
||||
if !enc.is_legal() {
|
||||
return Err(format!("{} can't be encoded: {}",
|
||||
inst,
|
||||
func.dfg.display_inst(inst)));
|
||||
func.dfg.display_inst(inst, isa)));
|
||||
}
|
||||
let have = sink.text.trim();
|
||||
if have != want {
|
||||
return Err(format!("Bad machine code for {}: {}\nWant: {}\nGot: {}",
|
||||
inst,
|
||||
func.dfg.display_inst(inst),
|
||||
func.dfg.display_inst(inst, isa),
|
||||
want,
|
||||
have));
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ pub fn pretty_verifier_error(func: &ir::Function,
|
||||
let mut msg = err.to_string();
|
||||
match err.location {
|
||||
AnyEntity::Inst(inst) => {
|
||||
write!(msg, "\n{}: {}\n\n", inst, func.dfg.display_inst(inst)).unwrap()
|
||||
write!(msg, "\n{}: {}\n\n", inst, func.dfg.display_inst(inst, isa)).unwrap()
|
||||
}
|
||||
_ => msg.push('\n'),
|
||||
}
|
||||
|
||||
@@ -53,5 +53,5 @@ pub trait CodeSink {
|
||||
pub fn bad_encoding(func: &Function, inst: Inst) -> ! {
|
||||
panic!("Bad encoding {} for {}",
|
||||
func.encodings[inst],
|
||||
func.dfg.display_inst(inst));
|
||||
func.dfg.display_inst(inst, None));
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ fn relax_branch(dfg: &mut DataFlowGraph,
|
||||
let inst = pos.current_inst().unwrap();
|
||||
dbg!("Relaxing [{}] {} for {:#x}-{:#x} range",
|
||||
encinfo.display(encodings[inst]),
|
||||
dfg.display_inst(inst),
|
||||
dfg.display_inst(inst, None),
|
||||
offset,
|
||||
dest_offset);
|
||||
unimplemented!();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Data flow graph tracking Instructions, Values, and EBBs.
|
||||
|
||||
use entity_map::{EntityMap, PrimaryEntityData};
|
||||
use isa::TargetIsa;
|
||||
use ir::builder::{InsertBuilder, ReplaceBuilder};
|
||||
use ir::extfunc::ExtFuncData;
|
||||
use ir::instructions::{Opcode, InstructionData, CallInfo};
|
||||
@@ -162,7 +163,7 @@ impl DataFlowGraph {
|
||||
self.results[inst].get(num as usize, &self.value_lists),
|
||||
"Dangling result value {}: {}",
|
||||
v,
|
||||
self.display_inst(inst));
|
||||
self.display_inst(inst, None));
|
||||
ValueDef::Res(inst, num as usize)
|
||||
}
|
||||
ValueData::Arg { ebb, num, .. } => {
|
||||
@@ -376,8 +377,11 @@ impl DataFlowGraph {
|
||||
}
|
||||
|
||||
/// Returns an object that displays `inst`.
|
||||
pub fn display_inst(&self, inst: Inst) -> DisplayInst {
|
||||
DisplayInst(self, inst)
|
||||
pub fn display_inst<'a, I: Into<Option<&'a TargetIsa>>>(&'a self,
|
||||
inst: Inst,
|
||||
isa: I)
|
||||
-> DisplayInst<'a> {
|
||||
DisplayInst(self, isa.into(), inst)
|
||||
}
|
||||
|
||||
/// Get all value arguments on `inst` as a slice.
|
||||
@@ -552,7 +556,7 @@ impl DataFlowGraph {
|
||||
old_value,
|
||||
"{} wasn't detached from {}",
|
||||
old_value,
|
||||
self.display_inst(inst));
|
||||
self.display_inst(inst, None));
|
||||
new_value
|
||||
}
|
||||
|
||||
@@ -830,14 +834,15 @@ impl EbbData {
|
||||
}
|
||||
|
||||
/// Object that can display an instruction.
|
||||
pub struct DisplayInst<'a>(&'a DataFlowGraph, Inst);
|
||||
pub struct DisplayInst<'a>(&'a DataFlowGraph, Option<&'a TargetIsa>, Inst);
|
||||
|
||||
impl<'a> fmt::Display for DisplayInst<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let dfg = self.0;
|
||||
let inst = &dfg[self.1];
|
||||
let isa = self.1;
|
||||
let inst = self.2;
|
||||
|
||||
if let Some((first, rest)) = dfg.inst_results(self.1).split_first() {
|
||||
if let Some((first, rest)) = dfg.inst_results(inst).split_first() {
|
||||
write!(f, "{}", first)?;
|
||||
for v in rest {
|
||||
write!(f, ", {}", v)?;
|
||||
@@ -846,13 +851,13 @@ impl<'a> fmt::Display for DisplayInst<'a> {
|
||||
}
|
||||
|
||||
|
||||
let typevar = dfg.ctrl_typevar(self.1);
|
||||
let typevar = dfg.ctrl_typevar(inst);
|
||||
if typevar.is_void() {
|
||||
write!(f, "{}", inst.opcode())?;
|
||||
write!(f, "{}", dfg[inst].opcode())?;
|
||||
} else {
|
||||
write!(f, "{}.{}", inst.opcode(), typevar)?;
|
||||
write!(f, "{}.{}", dfg[inst].opcode(), typevar)?;
|
||||
}
|
||||
write_operands(f, dfg, None, self.1)
|
||||
write_operands(f, dfg, isa, inst)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,7 +875,7 @@ mod tests {
|
||||
let inst = dfg.make_inst(idata);
|
||||
dfg.make_inst_results(inst, types::I32);
|
||||
assert_eq!(inst.to_string(), "inst0");
|
||||
assert_eq!(dfg.display_inst(inst).to_string(), "v0 = iconst.i32");
|
||||
assert_eq!(dfg.display_inst(inst, None).to_string(), "v0 = iconst.i32");
|
||||
|
||||
// Immutable reference resolution.
|
||||
{
|
||||
@@ -902,7 +907,7 @@ mod tests {
|
||||
|
||||
let idata = InstructionData::Nullary { opcode: Opcode::Trap };
|
||||
let inst = dfg.make_inst(idata);
|
||||
assert_eq!(dfg.display_inst(inst).to_string(), "trap");
|
||||
assert_eq!(dfg.display_inst(inst, None).to_string(), "trap");
|
||||
|
||||
// Result slice should be empty.
|
||||
assert_eq!(dfg.inst_results(inst), &[]);
|
||||
|
||||
@@ -474,7 +474,7 @@ pub fn handle_call_abi(dfg: &mut DataFlowGraph, cfg: &ControlFlowGraph, pos: &mu
|
||||
|
||||
debug_assert!(check_call_signature(dfg, inst).is_ok(),
|
||||
"Signature still wrong: {}, {}{}",
|
||||
dfg.display_inst(inst),
|
||||
dfg.display_inst(inst, None),
|
||||
sig_ref,
|
||||
dfg.signatures[sig_ref]);
|
||||
|
||||
@@ -523,7 +523,7 @@ pub fn handle_return_abi(dfg: &mut DataFlowGraph,
|
||||
if special_args > 0 {
|
||||
dbg!("Adding {} special-purpose arguments to {}",
|
||||
special_args,
|
||||
dfg.display_inst(inst));
|
||||
dfg.display_inst(inst, None));
|
||||
let mut vlist = dfg[inst].take_value_list().unwrap();
|
||||
for arg in &sig.return_types[abi_args..] {
|
||||
match arg.purpose {
|
||||
@@ -550,7 +550,7 @@ pub fn handle_return_abi(dfg: &mut DataFlowGraph,
|
||||
|
||||
debug_assert!(check_return_signature(dfg, inst, sig),
|
||||
"Signature still wrong: {} / signature {}",
|
||||
dfg.display_inst(inst),
|
||||
dfg.display_inst(inst, None),
|
||||
sig);
|
||||
|
||||
// Yes, we changed stuff.
|
||||
|
||||
@@ -123,7 +123,7 @@ fn split_any(dfg: &mut DataFlowGraph,
|
||||
let branch_opc = dfg[inst].opcode();
|
||||
assert!(branch_opc.is_branch(),
|
||||
"Predecessor not a branch: {}",
|
||||
dfg.display_inst(inst));
|
||||
dfg.display_inst(inst, None));
|
||||
let fixed_args = branch_opc.constraints().fixed_value_arguments();
|
||||
let mut args = dfg[inst]
|
||||
.take_value_list()
|
||||
|
||||
@@ -399,7 +399,7 @@ impl<'a> Context<'a> {
|
||||
dbg!("Checking {}: {}: {}",
|
||||
pred_val,
|
||||
pred_ebb,
|
||||
self.func.dfg.display_inst(pred_inst));
|
||||
self.func.dfg.display_inst(pred_inst, self.isa));
|
||||
|
||||
// Never coalesce incoming function arguments on the stack. These arguments are
|
||||
// pre-spilled, and the rest of the virtual register would be forced to spill to the
|
||||
@@ -474,9 +474,9 @@ impl<'a> Context<'a> {
|
||||
let ty = self.func.dfg.value_type(copy);
|
||||
|
||||
dbg!("Inserted {}, before {}: {}",
|
||||
self.func.dfg.display_inst(inst),
|
||||
self.func.dfg.display_inst(inst, self.isa),
|
||||
pred_ebb,
|
||||
self.func.dfg.display_inst(pred_inst));
|
||||
self.func.dfg.display_inst(pred_inst, self.isa));
|
||||
|
||||
// Give it an encoding.
|
||||
let encoding = self.isa
|
||||
@@ -519,7 +519,7 @@ impl<'a> Context<'a> {
|
||||
self.liveness.move_def_locally(succ_val, inst);
|
||||
|
||||
dbg!("Inserted {}, following {}({}: {})",
|
||||
self.func.dfg.display_inst(inst),
|
||||
self.func.dfg.display_inst(inst, self.isa),
|
||||
ebb,
|
||||
new_val,
|
||||
ty);
|
||||
|
||||
@@ -73,6 +73,7 @@ pub struct Coloring {
|
||||
/// Immutable context information and mutable references that don't need to be borrowed across
|
||||
/// method calls should go in this struct.
|
||||
struct Context<'a> {
|
||||
isa: &'a TargetIsa,
|
||||
// Cached ISA information.
|
||||
// We save it here to avoid frequent virtual function calls on the `TargetIsa` trait object.
|
||||
reginfo: RegInfo,
|
||||
@@ -111,6 +112,7 @@ impl Coloring {
|
||||
tracker: &mut LiveValueTracker) {
|
||||
dbg!("Coloring for:\n{}", func.display(isa));
|
||||
let mut ctx = Context {
|
||||
isa,
|
||||
reginfo: isa.register_info(),
|
||||
encinfo: isa.encoding_info(),
|
||||
domtree,
|
||||
@@ -279,7 +281,7 @@ impl<'a> Context<'a> {
|
||||
locations: &mut ValueLocations,
|
||||
func_signature: &Signature) {
|
||||
dbg!("Coloring {}\n {}",
|
||||
dfg.display_inst(inst),
|
||||
dfg.display_inst(inst, self.isa),
|
||||
regs.display(&self.reginfo));
|
||||
|
||||
// EBB whose arguments should be colored to match the current branch instruction's
|
||||
@@ -308,7 +310,7 @@ impl<'a> Context<'a> {
|
||||
assert_eq!(dfg.inst_variable_args(inst).len(),
|
||||
0,
|
||||
"Can't handle EBB arguments: {}",
|
||||
dfg.display_inst(inst));
|
||||
dfg.display_inst(inst, self.isa));
|
||||
self.undivert_regs(|lr| !lr.is_local());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +246,9 @@ impl<'a> Context<'a> {
|
||||
pos: &mut Cursor,
|
||||
dfg: &mut DataFlowGraph,
|
||||
tracker: &mut LiveValueTracker) {
|
||||
dbg!("Inst {}, {}", dfg.display_inst(inst), self.pressure);
|
||||
dbg!("Inst {}, {}",
|
||||
dfg.display_inst(inst, self.isa),
|
||||
self.pressure);
|
||||
|
||||
// We may need to resolve register constraints if there are any noteworthy uses.
|
||||
assert!(self.reg_uses.is_empty());
|
||||
@@ -292,7 +294,7 @@ impl<'a> Context<'a> {
|
||||
None => {
|
||||
panic!("Ran out of {} registers for {}",
|
||||
op.regclass,
|
||||
dfg.display_inst(inst))
|
||||
dfg.display_inst(inst, self.isa))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,7 +431,7 @@ impl<'a> Context<'a> {
|
||||
None => {
|
||||
panic!("Ran out of {} registers when inserting copy before {}",
|
||||
rc,
|
||||
dfg.display_inst(inst))
|
||||
dfg.display_inst(inst, self.isa))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user