diff --git a/cranelift/src/filetest/binemit.rs b/cranelift/src/filetest/binemit.rs index 2f695bff1e..15f5b0a982 100644 --- a/cranelift/src/filetest/binemit.rs +++ b/cranelift/src/filetest/binemit.rs @@ -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)); } diff --git a/cranelift/src/utils.rs b/cranelift/src/utils.rs index f620f5f316..3bc8e7b1df 100644 --- a/cranelift/src/utils.rs +++ b/cranelift/src/utils.rs @@ -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'), } diff --git a/lib/cretonne/src/binemit/mod.rs b/lib/cretonne/src/binemit/mod.rs index 33cce8d2b0..eaa721d510 100644 --- a/lib/cretonne/src/binemit/mod.rs +++ b/lib/cretonne/src/binemit/mod.rs @@ -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)); } diff --git a/lib/cretonne/src/binemit/relaxation.rs b/lib/cretonne/src/binemit/relaxation.rs index 53b7fd0112..d80d17d7bb 100644 --- a/lib/cretonne/src/binemit/relaxation.rs +++ b/lib/cretonne/src/binemit/relaxation.rs @@ -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!(); diff --git a/lib/cretonne/src/ir/dfg.rs b/lib/cretonne/src/ir/dfg.rs index 85e971a9fc..ad67f7722b 100644 --- a/lib/cretonne/src/ir/dfg.rs +++ b/lib/cretonne/src/ir/dfg.rs @@ -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>>(&'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), &[]); diff --git a/lib/cretonne/src/legalizer/boundary.rs b/lib/cretonne/src/legalizer/boundary.rs index b65eea0984..3f22694eb8 100644 --- a/lib/cretonne/src/legalizer/boundary.rs +++ b/lib/cretonne/src/legalizer/boundary.rs @@ -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. diff --git a/lib/cretonne/src/legalizer/split.rs b/lib/cretonne/src/legalizer/split.rs index cbca25c9c2..3e3a36f619 100644 --- a/lib/cretonne/src/legalizer/split.rs +++ b/lib/cretonne/src/legalizer/split.rs @@ -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() diff --git a/lib/cretonne/src/regalloc/coalescing.rs b/lib/cretonne/src/regalloc/coalescing.rs index 634f0c0a32..08ecf12589 100644 --- a/lib/cretonne/src/regalloc/coalescing.rs +++ b/lib/cretonne/src/regalloc/coalescing.rs @@ -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); diff --git a/lib/cretonne/src/regalloc/coloring.rs b/lib/cretonne/src/regalloc/coloring.rs index f61e88e9b7..85911efd0b 100644 --- a/lib/cretonne/src/regalloc/coloring.rs +++ b/lib/cretonne/src/regalloc/coloring.rs @@ -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()); } } diff --git a/lib/cretonne/src/regalloc/spilling.rs b/lib/cretonne/src/regalloc/spilling.rs index 465efa7856..5733f6e80f 100644 --- a/lib/cretonne/src/regalloc/spilling.rs +++ b/lib/cretonne/src/regalloc/spilling.rs @@ -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)) } } }