diff --git a/cranelift/codegen/meta/src/shared/formats.rs b/cranelift/codegen/meta/src/shared/formats.rs index 3d081951a5..f1d0a1826d 100644 --- a/cranelift/codegen/meta/src/shared/formats.rs +++ b/cranelift/codegen/meta/src/shared/formats.rs @@ -18,8 +18,6 @@ pub(crate) struct Formats { pub(crate) call: Rc, pub(crate) call_indirect: Rc, pub(crate) cond_trap: Rc, - pub(crate) copy_special: Rc, - pub(crate) copy_to_ssa: Rc, pub(crate) float_compare: Rc, pub(crate) float_cond: Rc, pub(crate) float_cond_trap: Rc, @@ -37,9 +35,6 @@ pub(crate) struct Formats { pub(crate) load_no_offset: Rc, pub(crate) multiary: Rc, pub(crate) nullary: Rc, - pub(crate) reg_fill: Rc, - pub(crate) reg_move: Rc, - pub(crate) reg_spill: Rc, pub(crate) shuffle: Rc, pub(crate) stack_load: Rc, pub(crate) stack_store: Rc, @@ -283,33 +278,6 @@ impl Formats { .imm(&imm.offset32) .build(), - reg_move: Builder::new("RegMove") - .value() - .imm_with_name("src", &imm.regunit) - .imm_with_name("dst", &imm.regunit) - .build(), - - copy_special: Builder::new("CopySpecial") - .imm_with_name("src", &imm.regunit) - .imm_with_name("dst", &imm.regunit) - .build(), - - copy_to_ssa: Builder::new("CopyToSsa") - .imm_with_name("src", &imm.regunit) - .build(), - - reg_spill: Builder::new("RegSpill") - .value() - .imm_with_name("src", &imm.regunit) - .imm_with_name("dst", &entities.stack_slot) - .build(), - - reg_fill: Builder::new("RegFill") - .value() - .imm_with_name("src", &entities.stack_slot) - .imm_with_name("dst", &imm.regunit) - .build(), - trap: Builder::new("Trap").imm(&imm.trapcode).build(), cond_trap: Builder::new("CondTrap").value().imm(&imm.trapcode).build(), diff --git a/cranelift/codegen/meta/src/shared/immediates.rs b/cranelift/codegen/meta/src/shared/immediates.rs index 9811dcc0ca..12a93d81e6 100644 --- a/cranelift/codegen/meta/src/shared/immediates.rs +++ b/cranelift/codegen/meta/src/shared/immediates.rs @@ -64,9 +64,6 @@ pub(crate) struct Immediates { /// Flags for memory operations like `load` and `store`. pub memflags: OperandKind, - /// A register unit in the current target ISA. - pub regunit: OperandKind, - /// A trap code indicating the reason for trapping. /// /// The Rust enum type also has a `User(u16)` variant for user-provided trap codes. @@ -149,8 +146,6 @@ impl Immediates { }, memflags: new_imm("flags", "ir::MemFlags").with_doc("Memory operation flags"), - regunit: new_imm("regunit", "isa::RegUnit") - .with_doc("A register unit in the target ISA"), trapcode: { let mut trapcode_values = HashMap::new(); trapcode_values.insert("stk_ovf", "StackOverflow"); diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index d869f8629c..81ac8c6f98 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -1954,65 +1954,6 @@ pub(crate) fn define( .operands_out(vec![sarg_t]), ); - let src = &Operand::new("src", &imm.regunit); - let dst = &Operand::new("dst", &imm.regunit); - - ig.push( - Inst::new( - "regmove", - r#" - Temporarily divert ``x`` from ``src`` to ``dst``. - - This instruction moves the location of a value from one register to - another without creating a new SSA value. It is used by the register - allocator to temporarily rearrange register assignments in order to - satisfy instruction constraints. - - The register diversions created by this instruction must be undone - before the value leaves the block. At the entry to a new block, all live - values must be in their originally assigned registers. - "#, - &formats.reg_move, - ) - .operands_in(vec![x, src, dst]) - .other_side_effects(true), - ); - - ig.push( - Inst::new( - "copy_special", - r#" - Copies the contents of ''src'' register to ''dst'' register. - - This instructions copies the contents of one register to another - register without involving any SSA values. This is used for copying - special registers, e.g. copying the stack register to the frame - register in a function prologue. - "#, - &formats.copy_special, - ) - .operands_in(vec![src, dst]) - .other_side_effects(true), - ); - - ig.push( - Inst::new( - "copy_to_ssa", - r#" - Copies the contents of ''src'' register to ''a'' SSA name. - - This instruction copies the contents of one register, regardless of its SSA name, to - another register, creating a new SSA name. In that sense it is a one-sided version - of ''copy_special''. This instruction is internal and should not be created by - Cranelift users. - "#, - &formats.copy_to_ssa, - ) - .operands_in(vec![src]) - .operands_out(vec![a]) - .other_side_effects(true), - ); - ig.push( Inst::new( "copy_nop", @@ -2098,44 +2039,6 @@ pub(crate) fn define( .operands_out(vec![f]), ); - ig.push( - Inst::new( - "regspill", - r#" - Temporarily divert ``x`` from ``src`` to ``SS``. - - This instruction moves the location of a value from a register to a - stack slot without creating a new SSA value. It is used by the register - allocator to temporarily rearrange register assignments in order to - satisfy instruction constraints. - - See also `regmove`. - "#, - &formats.reg_spill, - ) - .operands_in(vec![x, src, SS]) - .other_side_effects(true), - ); - - ig.push( - Inst::new( - "regfill", - r#" - Temporarily divert ``x`` from ``SS`` to ``dst``. - - This instruction moves the location of a value from a stack slot to a - register without creating a new SSA value. It is used by the register - allocator to temporarily rearrange register assignments in order to - satisfy instruction constraints. - - See also `regmove`. - "#, - &formats.reg_fill, - ) - .operands_in(vec![x, SS, dst]) - .other_side_effects(true), - ); - let N = &Operand::new("args", &entities.varargs).with_doc("Variable number of args for StackMap"); @@ -2302,10 +2205,9 @@ pub(crate) fn define( | of | * | Overflow | | nof | * | No Overflow | - \* The unsigned version of overflow conditions have ISA-specific - semantics and thus have been kept as methods on the TargetIsa trait as - [unsigned_add_overflow_condition][isa::TargetIsa::unsigned_add_overflow_condition] and - [unsigned_sub_overflow_condition][isa::TargetIsa::unsigned_sub_overflow_condition]. + \* The unsigned version of overflow condition for add has ISA-specific semantics and thus + has been kept as a method on the TargetIsa trait as + [unsigned_add_overflow_condition][crate::isa::TargetIsa::unsigned_add_overflow_condition]. When this instruction compares integer vectors, it returns a boolean vector of lane-wise comparisons. diff --git a/cranelift/codegen/src/binemit/memorysink.rs b/cranelift/codegen/src/binemit/memorysink.rs index d50d1c10eb..eb1d72e8eb 100644 --- a/cranelift/codegen/src/binemit/memorysink.rs +++ b/cranelift/codegen/src/binemit/memorysink.rs @@ -15,9 +15,7 @@ //! `CodeSink::put*` methods, so the performance impact of the virtual callbacks is less severe. use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc}; use crate::binemit::stack_map::StackMap; -use crate::ir::entities::Value; -use crate::ir::{ConstantOffset, ExternalName, Function, JumpTable, Opcode, SourceLoc, TrapCode}; -use crate::isa::TargetIsa; +use crate::ir::{ConstantOffset, ExternalName, JumpTable, Opcode, SourceLoc, TrapCode}; use core::ptr::write_unaligned; /// A `CodeSink` that writes binary machine code directly into memory. @@ -38,7 +36,6 @@ pub struct MemoryCodeSink<'a> { offset: isize, relocs: &'a mut dyn RelocSink, traps: &'a mut dyn TrapSink, - stack_maps: &'a mut dyn StackMapSink, /// Information about the generated code and read-only data. pub info: CodeInfo, } @@ -54,7 +51,6 @@ impl<'a> MemoryCodeSink<'a> { data: *mut u8, relocs: &'a mut dyn RelocSink, traps: &'a mut dyn TrapSink, - stack_maps: &'a mut dyn StackMapSink, ) -> Self { Self { data, @@ -67,7 +63,6 @@ impl<'a> MemoryCodeSink<'a> { }, relocs, traps, - stack_maps, } } } @@ -174,12 +169,6 @@ impl<'a> CodeSink for MemoryCodeSink<'a> { self.info.total_size = self.offset(); } - fn add_stack_map(&mut self, val_list: &[Value], func: &Function, isa: &dyn TargetIsa) { - let ofs = self.offset(); - let stack_map = StackMap::from_values(&val_list, func, isa); - self.stack_maps.add_stack_map(ofs, stack_map); - } - fn add_call_site(&mut self, opcode: Opcode, loc: SourceLoc) { debug_assert!( opcode.is_call(), diff --git a/cranelift/codegen/src/binemit/mod.rs b/cranelift/codegen/src/binemit/mod.rs index 28b75865bd..4e9725f374 100644 --- a/cranelift/codegen/src/binemit/mod.rs +++ b/cranelift/codegen/src/binemit/mod.rs @@ -11,7 +11,6 @@ pub use self::memorysink::{ TrapSink, }; pub use self::stack_map::StackMap; -use crate::ir::entities::Value; use crate::ir::{ ConstantOffset, ExternalName, Function, Inst, JumpTable, Opcode, SourceLoc, TrapCode, }; @@ -169,9 +168,6 @@ pub trait CodeSink { /// Read-only data output is complete, we're done. fn end_codegen(&mut self); - /// Add a stack map at the current code offset. - fn add_stack_map(&mut self, _: &[Value], _: &Function, _: &dyn TargetIsa); - /// Add a call site for a call with the given opcode, returning at the current offset. fn add_call_site(&mut self, _: Opcode, _: SourceLoc) { // Default implementation doesn't need to do anything. diff --git a/cranelift/codegen/src/binemit/stack_map.rs b/cranelift/codegen/src/binemit/stack_map.rs index c3055a0154..f9b99269ab 100644 --- a/cranelift/codegen/src/binemit/stack_map.rs +++ b/cranelift/codegen/src/binemit/stack_map.rs @@ -1,6 +1,4 @@ use crate::bitset::BitSet; -use crate::ir; -use crate::isa::TargetIsa; use alloc::vec::Vec; type Num = u32; @@ -76,57 +74,6 @@ pub struct StackMap { } impl StackMap { - /// Create a `StackMap` based on where references are located on a - /// function's stack. - pub fn from_values( - args: &[ir::entities::Value], - func: &ir::Function, - isa: &dyn TargetIsa, - ) -> Self { - let loc = &func.locations; - let mut live_ref_in_stack_slot = crate::HashSet::new(); - // References can be in registers, and live registers values are pushed onto the stack before calls and traps. - // TODO: Implement register maps. If a register containing a reference is spilled and reused after a safepoint, - // it could contain a stale reference value if the garbage collector relocated the value. - for val in args { - if let Some(value_loc) = loc.get(*val) { - match *value_loc { - ir::ValueLoc::Stack(stack_slot) => { - live_ref_in_stack_slot.insert(stack_slot); - } - _ => {} - } - } - } - - let stack = &func.stack_slots; - let info = func.stack_slots.layout_info.unwrap(); - - // Refer to the doc comment for `StackMap` above to understand the - // bitmap representation used here. - let map_size = (info.frame_size + info.inbound_args_size) as usize; - let word_size = isa.pointer_bytes() as usize; - let num_words = map_size / word_size; - - let mut vec = alloc::vec::Vec::with_capacity(num_words); - vec.resize(num_words, false); - - for (ss, ssd) in stack.iter() { - if !live_ref_in_stack_slot.contains(&ss) - || ssd.kind == ir::stackslot::StackSlotKind::OutgoingArg - { - continue; - } - - debug_assert!(ssd.size as usize == word_size); - let bytes_from_bottom = info.frame_size as i32 + ssd.offset.unwrap(); - let words_from_bottom = (bytes_from_bottom as usize) / word_size; - vec[words_from_bottom] = true; - } - - Self::from_slice(&vec) - } - /// Create a vec of Bitsets from a slice of bools. pub fn from_slice(vec: &[bool]) -> Self { let len = vec.len(); diff --git a/cranelift/codegen/src/cfg_printer.rs b/cranelift/codegen/src/cfg_printer.rs index 4ceae473b2..843b66f277 100644 --- a/cranelift/codegen/src/cfg_printer.rs +++ b/cranelift/codegen/src/cfg_printer.rs @@ -51,11 +51,11 @@ impl<'a> CFGPrinter<'a> { for block in &self.func.layout { write!(w, " {} [shape=record, label=\"{{", block)?; - crate::write::write_block_header(w, self.func, None, block, 4)?; + crate::write::write_block_header(w, self.func, block, 4)?; // Add all outgoing branch instructions to the label. for inst in self.func.layout.block_likely_branches(block) { write!(w, " | <{}>", inst)?; - PlainWriter.write_instruction(w, self.func, &aliases, None, inst, 0)?; + PlainWriter.write_instruction(w, self.func, &aliases, inst, 0)?; } writeln!(w, "}}\"]")? } diff --git a/cranelift/codegen/src/context.rs b/cranelift/codegen/src/context.rs index 14d4eb88e4..48503952e5 100644 --- a/cranelift/codegen/src/context.rs +++ b/cranelift/codegen/src/context.rs @@ -140,7 +140,7 @@ impl Context { log::debug!( "Compiling (opt level {:?}):\n{}", opt_level, - self.func.display(isa) + self.func.display() ); self.compute_cfg(); @@ -196,7 +196,7 @@ impl Context { stack_maps: &mut dyn StackMapSink, ) -> CodeInfo { let _tt = timing::binemit(); - let mut sink = MemoryCodeSink::new(mem, relocs, traps, stack_maps); + let mut sink = MemoryCodeSink::new(mem, relocs, traps); let result = self .mach_compile_result .as_ref() diff --git a/cranelift/codegen/src/cursor.rs b/cranelift/codegen/src/cursor.rs index f47ddf3d4e..56ccc40743 100644 --- a/cranelift/codegen/src/cursor.rs +++ b/cranelift/codegen/src/cursor.rs @@ -720,7 +720,7 @@ impl<'f> EncCursor<'f> { /// /// This is a convenience wrapper for the DFG equivalent. pub fn display_inst(&self, inst: ir::Inst) -> ir::dfg::DisplayInst { - self.func.dfg.display_inst(inst, self.isa) + self.func.dfg.display_inst(inst) } } diff --git a/cranelift/codegen/src/ir/builder.rs b/cranelift/codegen/src/ir/builder.rs index 55611978e0..3191f9dae1 100644 --- a/cranelift/codegen/src/ir/builder.rs +++ b/cranelift/codegen/src/ir/builder.rs @@ -7,7 +7,6 @@ use crate::ir; use crate::ir::types; use crate::ir::{DataFlowGraph, InstructionData}; use crate::ir::{Inst, Opcode, Type, Value}; -use crate::isa; /// Base trait for instruction builders. /// diff --git a/cranelift/codegen/src/ir/dfg.rs b/cranelift/codegen/src/ir/dfg.rs index f64cf896c4..91f3711f57 100644 --- a/cranelift/codegen/src/ir/dfg.rs +++ b/cranelift/codegen/src/ir/dfg.rs @@ -10,7 +10,6 @@ use crate::ir::{ Block, FuncRef, Inst, SigRef, Signature, SourceLoc, Type, Value, ValueLabelAssignments, ValueList, ValueListPool, }; -use crate::isa::TargetIsa; use crate::packed_option::ReservedValue; use crate::write::write_operands; use crate::HashMap; @@ -466,12 +465,8 @@ impl DataFlowGraph { } /// Returns an object that displays `inst`. - pub fn display_inst<'a, I: Into>>( - &'a self, - inst: Inst, - isa: I, - ) -> DisplayInst<'a> { - DisplayInst(self, isa.into(), inst) + pub fn display_inst<'a>(&'a self, inst: Inst) -> DisplayInst<'a> { + DisplayInst(self, inst) } /// Get all value arguments on `inst` as a slice. @@ -657,7 +652,7 @@ impl DataFlowGraph { old_value, "{} wasn't detached from {}", old_value, - self.display_inst(inst, None) + self.display_inst(inst) ); new_value } @@ -963,13 +958,12 @@ impl BlockData { } /// Object that can display an instruction. -pub struct DisplayInst<'a>(&'a DataFlowGraph, Option<&'a dyn TargetIsa>, Inst); +pub struct DisplayInst<'a>(&'a DataFlowGraph, Inst); impl<'a> fmt::Display for DisplayInst<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let dfg = self.0; - let isa = self.1; - let inst = self.2; + let inst = self.1; if let Some((first, rest)) = dfg.inst_results(inst).split_first() { write!(f, "{}", first)?; @@ -985,7 +979,7 @@ impl<'a> fmt::Display for DisplayInst<'a> { } else { write!(f, "{}.{}", dfg[inst].opcode(), typevar)?; } - write_operands(f, dfg, isa, inst) + write_operands(f, dfg, inst) } } @@ -1150,10 +1144,7 @@ mod tests { dfg.make_inst_results(inst, types::I32); assert_eq!(inst.to_string(), "inst0"); - assert_eq!( - dfg.display_inst(inst, None).to_string(), - "v0 = iconst.i32 0" - ); + assert_eq!(dfg.display_inst(inst).to_string(), "v0 = iconst.i32 0"); // Immutable reference resolution. { @@ -1188,7 +1179,7 @@ mod tests { code: TrapCode::User(0), }; let inst = dfg.make_inst(idata); - assert_eq!(dfg.display_inst(inst, None).to_string(), "trap user0"); + assert_eq!(dfg.display_inst(inst).to_string(), "trap user0"); // Result slice should be empty. assert_eq!(dfg.inst_results(inst), &[]); diff --git a/cranelift/codegen/src/ir/extfunc.rs b/cranelift/codegen/src/ir/extfunc.rs index 6c1d26f4ab..1a623095a7 100644 --- a/cranelift/codegen/src/ir/extfunc.rs +++ b/cranelift/codegen/src/ir/extfunc.rs @@ -5,8 +5,8 @@ //! //! This module declares the data types used to represent external functions and call signatures. -use crate::ir::{ArgumentLoc, ExternalName, SigRef, Type}; -use crate::isa::{CallConv, RegInfo, RegUnit}; +use crate::ir::{ExternalName, SigRef, Type}; +use crate::isa::CallConv; use crate::machinst::RelocDistance; use alloc::vec::Vec; use core::fmt; @@ -50,11 +50,6 @@ impl Signature { self.call_conv = call_conv; } - /// Return an object that can display `self` with correct register names. - pub fn display<'a, R: Into>>(&'a self, regs: R) -> DisplaySignature<'a> { - DisplaySignature(self, regs.into()) - } - /// Find the index of a presumed unique special-purpose parameter. pub fn special_param_index(&self, purpose: ArgumentPurpose) -> Option { self.params.iter().rposition(|arg| arg.purpose == purpose) @@ -108,38 +103,29 @@ impl Signature { } } -/// Wrapper type capable of displaying a `Signature` with correct register names. -pub struct DisplaySignature<'a>(&'a Signature, Option<&'a RegInfo>); - -fn write_list(f: &mut fmt::Formatter, args: &[AbiParam], regs: Option<&RegInfo>) -> fmt::Result { +fn write_list(f: &mut fmt::Formatter, args: &[AbiParam]) -> fmt::Result { match args.split_first() { None => {} Some((first, rest)) => { - write!(f, "{}", first.display(regs))?; + write!(f, "{}", first)?; for arg in rest { - write!(f, ", {}", arg.display(regs))?; + write!(f, ", {}", arg)?; } } } Ok(()) } -impl<'a> fmt::Display for DisplaySignature<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "(")?; - write_list(f, &self.0.params, self.1)?; - write!(f, ")")?; - if !self.0.returns.is_empty() { - write!(f, " -> ")?; - write_list(f, &self.0.returns, self.1)?; - } - write!(f, " {}", self.0.call_conv) - } -} - impl fmt::Display for Signature { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.display(None).fmt(f) + write!(f, "(")?; + write_list(f, &self.params)?; + write!(f, ")")?; + if !self.returns.is_empty() { + write!(f, " -> ")?; + write_list(f, &self.returns)?; + } + write!(f, " {}", self.call_conv) } } @@ -157,9 +143,6 @@ pub struct AbiParam { /// Method for extending argument to a full register. pub extension: ArgumentExtension, - /// ABI-specific location of this argument, or `Unassigned` for arguments that have not yet - /// been legalized. - pub location: ArgumentLoc, /// Was the argument converted to pointer during legalization? pub legalized_to_pointer: bool, } @@ -171,7 +154,6 @@ impl AbiParam { value_type: vt, extension: ArgumentExtension::None, purpose: ArgumentPurpose::Normal, - location: Default::default(), legalized_to_pointer: false, } } @@ -182,18 +164,6 @@ impl AbiParam { value_type: vt, extension: ArgumentExtension::None, purpose, - location: Default::default(), - legalized_to_pointer: false, - } - } - - /// Create a parameter for a special-purpose register. - pub fn special_reg(vt: Type, purpose: ArgumentPurpose, regunit: RegUnit) -> Self { - Self { - value_type: vt, - extension: ArgumentExtension::None, - purpose, - location: ArgumentLoc::Reg(regunit), legalized_to_pointer: false, } } @@ -215,42 +185,23 @@ impl AbiParam { ..self } } - - /// Return an object that can display `self` with correct register names. - pub fn display<'a, R: Into>>(&'a self, regs: R) -> DisplayAbiParam<'a> { - DisplayAbiParam(self, regs.into()) - } -} - -/// Wrapper type capable of displaying a `AbiParam` with correct register names. -pub struct DisplayAbiParam<'a>(&'a AbiParam, Option<&'a RegInfo>); - -impl<'a> fmt::Display for DisplayAbiParam<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0.value_type)?; - if self.0.legalized_to_pointer { - write!(f, " ptr")?; - } - match self.0.extension { - ArgumentExtension::None => {} - ArgumentExtension::Uext => write!(f, " uext")?, - ArgumentExtension::Sext => write!(f, " sext")?, - } - if self.0.purpose != ArgumentPurpose::Normal { - write!(f, " {}", self.0.purpose)?; - } - - if self.0.location.is_assigned() { - write!(f, " [{}]", self.0.location.display(self.1))?; - } - - Ok(()) - } } impl fmt::Display for AbiParam { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.display(None).fmt(f) + write!(f, "{}", self.value_type)?; + if self.legalized_to_pointer { + write!(f, " ptr")?; + } + match self.extension { + ArgumentExtension::None => {} + ArgumentExtension::Uext => write!(f, " uext")?, + ArgumentExtension::Sext => write!(f, " sext")?, + } + if self.purpose != ArgumentPurpose::Normal { + write!(f, " {}", self.purpose)?; + } + Ok(()) } } @@ -519,15 +470,5 @@ mod tests { sig.to_string(), "(i32, i32x4) -> f32, b8 baldrdash_system_v" ); - - // Order does not matter. - sig.params[0].location = ArgumentLoc::Stack(24); - sig.params[1].location = ArgumentLoc::Stack(8); - - // Writing ABI-annotated signatures. - assert_eq!( - sig.to_string(), - "(i32 [24], i32x4 [8]) -> f32, b8 baldrdash_system_v" - ); } } diff --git a/cranelift/codegen/src/ir/function.rs b/cranelift/codegen/src/ir/function.rs index 6f609b2a9a..5ccca1fe50 100644 --- a/cranelift/codegen/src/ir/function.rs +++ b/cranelift/codegen/src/ir/function.rs @@ -10,10 +10,10 @@ use crate::ir::{ HeapData, Inst, InstructionData, JumpTable, JumpTableData, Opcode, SigRef, StackSlot, StackSlotData, Table, TableData, }; -use crate::ir::{BlockOffsets, SourceLocs, StackSlots, ValueLocations}; +use crate::ir::{BlockOffsets, SourceLocs, StackSlots}; use crate::ir::{DataFlowGraph, ExternalName, Layout, Signature}; use crate::ir::{JumpTableOffsets, JumpTables}; -use crate::isa::{CallConv, TargetIsa}; +use crate::isa::CallConv; use crate::value_label::ValueLabelsRanges; use crate::write::write_function; #[cfg(feature = "enable-serde")] @@ -104,9 +104,6 @@ pub struct Function { /// Layout of blocks and instructions in the function body. pub layout: Layout, - /// Location assigned to every value. - pub locations: ValueLocations, - /// Code offsets of the block headers. /// /// This information is only transiently available after the `binemit::relax_branches` function @@ -156,7 +153,6 @@ impl Function { jump_tables: PrimaryMap::new(), dfg: DataFlowGraph::new(), layout: Layout::new(), - locations: SecondaryMap::new(), offsets: SecondaryMap::new(), jt_offsets: SecondaryMap::new(), srclocs: SecondaryMap::new(), @@ -176,7 +172,6 @@ impl Function { self.jump_tables.clear(); self.dfg.clear(); self.layout.clear(); - self.locations.clear(); self.offsets.clear(); self.jt_offsets.clear(); self.srclocs.clear(); @@ -227,11 +222,8 @@ impl Function { } /// Return an object that can display this function with correct ISA-specific annotations. - pub fn display<'a, I: Into>>( - &'a self, - isa: I, - ) -> DisplayFunction<'a> { - DisplayFunction(self, isa.into().into()) + pub fn display(&self) -> DisplayFunction<'_> { + DisplayFunction(self, Default::default()) } /// Return an object that can display this function with correct ISA-specific annotations. @@ -295,7 +287,7 @@ impl Function { } _ => panic!( "Unexpected instruction {} having default destination", - self.dfg.display_inst(inst, None) + self.dfg.display_inst(inst) ), } } @@ -372,39 +364,27 @@ impl Function { /// Additional annotations for function display. #[derive(Default)] pub struct DisplayFunctionAnnotations<'a> { - /// Enable ISA annotations. - pub isa: Option<&'a dyn TargetIsa>, - /// Enable value labels annotations. pub value_ranges: Option<&'a ValueLabelsRanges>, } -impl<'a> From> for DisplayFunctionAnnotations<'a> { - fn from(isa: Option<&'a dyn TargetIsa>) -> DisplayFunctionAnnotations { - DisplayFunctionAnnotations { - isa, - value_ranges: None, - } - } -} - /// Wrapper type capable of displaying a `Function` with correct ISA annotations. pub struct DisplayFunction<'a>(&'a Function, DisplayFunctionAnnotations<'a>); impl<'a> fmt::Display for DisplayFunction<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write_function(fmt, self.0, &self.1) + write_function(fmt, self.0) } } impl fmt::Display for Function { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write_function(fmt, self, &DisplayFunctionAnnotations::default()) + write_function(fmt, self) } } impl fmt::Debug for Function { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write_function(fmt, self, &DisplayFunctionAnnotations::default()) + write_function(fmt, self) } } diff --git a/cranelift/codegen/src/ir/instructions.rs b/cranelift/codegen/src/ir/instructions.rs index 351921f6af..3580f27376 100644 --- a/cranelift/codegen/src/ir/instructions.rs +++ b/cranelift/codegen/src/ir/instructions.rs @@ -25,7 +25,6 @@ use crate::ir::{ trapcode::TrapCode, types, Block, FuncRef, JumpTable, MemFlags, SigRef, StackSlot, Type, Value, }; -use crate::isa; /// Some instructions use an external list of argument values because there is not enough space in /// the 16-byte `InstructionData` struct. These value lists are stored in a memory pool in diff --git a/cranelift/codegen/src/ir/libcall.rs b/cranelift/codegen/src/ir/libcall.rs index 52360a9bf9..e8298d8ee7 100644 --- a/cranelift/codegen/src/ir/libcall.rs +++ b/cranelift/codegen/src/ir/libcall.rs @@ -1,10 +1,6 @@ //! Naming well-known routines in the runtime library. -use crate::ir::{ - types, AbiParam, ArgumentPurpose, ExtFuncData, ExternalName, FuncRef, Function, Opcode, - Signature, Type, -}; -use crate::isa::{CallConv, RegUnit, TargetIsa}; +use crate::ir::{types, ExternalName, FuncRef, Function, Opcode, Type}; use core::fmt; use core::str::FromStr; #[cfg(feature = "enable-serde")] @@ -169,14 +165,8 @@ impl LibCall { /// Get a function reference for the probestack function in `func`. /// /// If there is an existing reference, use it, otherwise make a new one. -pub fn get_probestack_funcref( - func: &mut Function, - reg_type: Type, - arg_reg: RegUnit, - isa: &dyn TargetIsa, -) -> FuncRef { +pub fn get_probestack_funcref(func: &mut Function) -> Option { find_funcref(LibCall::Probestack, func) - .unwrap_or_else(|| make_funcref_for_probestack(func, reg_type, arg_reg, isa)) } /// Get the existing function reference for `libcall` in `func` if it exists. @@ -196,38 +186,6 @@ fn find_funcref(libcall: LibCall, func: &Function) -> Option { None } -/// Create a funcref for `LibCall::Probestack`. -fn make_funcref_for_probestack( - func: &mut Function, - reg_type: Type, - arg_reg: RegUnit, - isa: &dyn TargetIsa, -) -> FuncRef { - let mut sig = Signature::new(CallConv::Probestack); - let rax = AbiParam::special_reg(reg_type, ArgumentPurpose::Normal, arg_reg); - sig.params.push(rax); - if !isa.flags().probestack_func_adjusts_sp() { - sig.returns.push(rax); - } - make_funcref(LibCall::Probestack, func, sig, isa) -} - -/// Create a funcref for `libcall`. -fn make_funcref( - libcall: LibCall, - func: &mut Function, - sig: Signature, - isa: &dyn TargetIsa, -) -> FuncRef { - let sigref = func.import_signature(sig); - - func.import_function(ExtFuncData { - name: ExternalName::LibCall(libcall), - signature: sigref, - colocated: isa.flags().use_colocated_libcalls(), - }) -} - #[cfg(test)] mod tests { use super::*; diff --git a/cranelift/codegen/src/ir/mod.rs b/cranelift/codegen/src/ir/mod.rs index 4b325d366c..d97d23c447 100644 --- a/cranelift/codegen/src/ir/mod.rs +++ b/cranelift/codegen/src/ir/mod.rs @@ -22,7 +22,6 @@ pub mod stackslot; mod table; mod trapcode; pub mod types; -mod valueloc; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -57,16 +56,12 @@ pub use crate::ir::stackslot::{StackLayoutInfo, StackSlotData, StackSlotKind, St pub use crate::ir::table::TableData; pub use crate::ir::trapcode::TrapCode; pub use crate::ir::types::Type; -pub use crate::ir::valueloc::{ArgumentLoc, ValueLoc}; pub use crate::value_label::LabelValueLoc; pub use cranelift_codegen_shared::condcodes; use crate::binemit; use crate::entity::{entity_impl, PrimaryMap, SecondaryMap}; -/// Map of value locations. -pub type ValueLocations = SecondaryMap; - /// Map of jump tables. pub type JumpTables = PrimaryMap; diff --git a/cranelift/codegen/src/ir/valueloc.rs b/cranelift/codegen/src/ir/valueloc.rs deleted file mode 100644 index d0b924886a..0000000000 --- a/cranelift/codegen/src/ir/valueloc.rs +++ /dev/null @@ -1,166 +0,0 @@ -//! Value locations. -//! -//! The register allocator assigns every SSA value to either a register or a stack slot. This -//! assignment is represented by a `ValueLoc` object. - -use crate::ir::StackSlot; -use crate::isa::{RegInfo, RegUnit}; -use core::fmt; - -#[cfg(feature = "enable-serde")] -use serde::{Deserialize, Serialize}; - -/// Value location. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub enum ValueLoc { - /// This value has not been assigned to a location yet. - Unassigned, - /// Value is assigned to a register. - Reg(RegUnit), - /// Value is assigned to a stack slot. - Stack(StackSlot), -} - -impl Default for ValueLoc { - fn default() -> Self { - Self::Unassigned - } -} - -impl ValueLoc { - /// Is this an assigned location? (That is, not `Unassigned`). - pub fn is_assigned(self) -> bool { - match self { - Self::Unassigned => false, - _ => true, - } - } - - /// Get the register unit of this location, or panic. - pub fn unwrap_reg(self) -> RegUnit { - match self { - Self::Reg(ru) => ru, - _ => panic!("unwrap_reg expected register, found {:?}", self), - } - } - - /// Get the stack slot of this location, or panic. - pub fn unwrap_stack(self) -> StackSlot { - match self { - Self::Stack(ss) => ss, - _ => panic!("unwrap_stack expected stack slot, found {:?}", self), - } - } - - /// Return an object that can display this value location, using the register info from the - /// target ISA. - pub fn display<'a, R: Into>>(self, regs: R) -> DisplayValueLoc<'a> { - DisplayValueLoc(self, regs.into()) - } -} - -/// Displaying a `ValueLoc` correctly requires the associated `RegInfo` from the target ISA. -/// Without the register info, register units are simply show as numbers. -/// -/// The `DisplayValueLoc` type can display the contained `ValueLoc`. -pub struct DisplayValueLoc<'a>(ValueLoc, Option<&'a RegInfo>); - -impl<'a> fmt::Display for DisplayValueLoc<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0 { - ValueLoc::Unassigned => write!(f, "-"), - ValueLoc::Reg(ru) => match self.1 { - Some(regs) => write!(f, "{}", regs.display_regunit(ru)), - None => write!(f, "%{}", ru), - }, - ValueLoc::Stack(ss) => write!(f, "{}", ss), - } - } -} - -/// Function argument location. -/// -/// The ABI specifies how arguments are passed to a function, and where return values appear after -/// the call. Just like a `ValueLoc`, function arguments can be passed in registers or on the -/// stack. -/// -/// Function arguments on the stack are accessed differently for the incoming arguments to the -/// current function and the outgoing arguments to a called external function. For this reason, -/// the location of stack arguments is described as an offset into the array of function arguments -/// on the stack. -/// -/// An `ArgumentLoc` can be translated to a `ValueLoc` only when we know if we're talking about an -/// incoming argument or an outgoing argument. -/// -/// - For stack arguments, different `StackSlot` entities are used to represent incoming and -/// outgoing arguments. -/// - For register arguments, there is usually no difference, but if we ever add support for a -/// register-window ISA like SPARC, register arguments would also need to be translated. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub enum ArgumentLoc { - /// This argument has not been assigned to a location yet. - Unassigned, - /// Argument is passed in a register. - Reg(RegUnit), - /// Argument is passed on the stack, at the given byte offset into the argument array. - Stack(i32), -} - -impl Default for ArgumentLoc { - fn default() -> Self { - Self::Unassigned - } -} - -impl ArgumentLoc { - /// Is this an assigned location? (That is, not `Unassigned`). - pub fn is_assigned(self) -> bool { - match self { - Self::Unassigned => false, - _ => true, - } - } - - /// Is this a register location? - pub fn is_reg(self) -> bool { - match self { - Self::Reg(_) => true, - _ => false, - } - } - - /// Is this a stack location? - pub fn is_stack(self) -> bool { - match self { - Self::Stack(_) => true, - _ => false, - } - } - - /// Return an object that can display this argument location, using the register info from the - /// target ISA. - pub fn display<'a, R: Into>>(self, regs: R) -> DisplayArgumentLoc<'a> { - DisplayArgumentLoc(self, regs.into()) - } -} - -/// Displaying a `ArgumentLoc` correctly requires the associated `RegInfo` from the target ISA. -/// Without the register info, register units are simply show as numbers. -/// -/// The `DisplayArgumentLoc` type can display the contained `ArgumentLoc`. -pub struct DisplayArgumentLoc<'a>(ArgumentLoc, Option<&'a RegInfo>); - -impl<'a> fmt::Display for DisplayArgumentLoc<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0 { - ArgumentLoc::Unassigned => write!(f, "-"), - ArgumentLoc::Reg(ru) => match self.1 { - Some(regs) => write!(f, "{}", regs.display_regunit(ru)), - None => write!(f, "%{}", ru), - }, - ArgumentLoc::Stack(offset) => write!(f, "{}", offset), - } - } -} diff --git a/cranelift/codegen/src/isa/aarch64/lower.rs b/cranelift/codegen/src/isa/aarch64/lower.rs index 990fc5cd02..34a627dfba 100644 --- a/cranelift/codegen/src/isa/aarch64/lower.rs +++ b/cranelift/codegen/src/isa/aarch64/lower.rs @@ -1407,7 +1407,7 @@ pub(crate) fn lower_i64x2_mul>(c: &mut C, insn: IRInst) { // rd = |dg+ch|be+af||dg+ch|be+af| c.emit(Inst::VecRRR { alu_op: VecALUOp::Addp, - rd: rd, + rd, rn: rd.to_reg(), rm: rd.to_reg(), size: VectorSize::Size32x4, diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 18004b5c03..79557bbfae 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -482,9 +482,9 @@ pub(crate) fn lower_insn_to_regs>( ctx.emit(Inst::AluRRRR { alu_op: ALUOp3::MSub64, - rd: rd, + rd, rn: rd.to_reg(), - rm: rm, + rm, ra: rn, }); } else { @@ -2165,16 +2165,11 @@ pub(crate) fn lower_insn_to_regs>( Opcode::Spill | Opcode::Fill | Opcode::FillNop - | Opcode::Regmove - | Opcode::CopySpecial - | Opcode::CopyToSsa | Opcode::CopyNop | Opcode::AdjustSpDown | Opcode::AdjustSpUpImm | Opcode::AdjustSpDownImm - | Opcode::IfcmpSp - | Opcode::Regspill - | Opcode::Regfill => { + | Opcode::IfcmpSp => { panic!("Unused opcode should not be encountered."); } @@ -2412,7 +2407,7 @@ pub(crate) fn lower_insn_to_regs>( alu_op: VecALUOp::Umaxp, rd: tmp, rn: rm, - rm: rm, + rm, size, }); } else { @@ -2835,9 +2830,9 @@ pub(crate) fn lower_insn_to_regs>( let rm = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None); ctx.emit(Inst::VecRRR { alu_op: VecALUOp::Addp, - rd: rd, - rn: rn, - rm: rm, + rd, + rn, + rm, size: VectorSize::from_ty(ty), }); } @@ -3446,7 +3441,7 @@ pub(crate) fn lower_insn_to_regs>( ctx.emit(Inst::FpuRRR { fpu_op: choose_32_64(in_ty, FPUOp2::Min32, FPUOp2::Min64), rd: rtmp2, - rn: rn, + rn, rm: rtmp1.to_reg(), }); if in_bits == 32 { @@ -3468,7 +3463,7 @@ pub(crate) fn lower_insn_to_regs>( } } if in_bits == 32 { - ctx.emit(Inst::FpuCmp32 { rn: rn, rm: rn }); + ctx.emit(Inst::FpuCmp32 { rn, rm: rn }); ctx.emit(Inst::FpuCSel32 { rd: rtmp2, rn: rtmp1.to_reg(), @@ -3476,7 +3471,7 @@ pub(crate) fn lower_insn_to_regs>( cond: Cond::Ne, }); } else { - ctx.emit(Inst::FpuCmp64 { rn: rn, rm: rn }); + ctx.emit(Inst::FpuCmp64 { rn, rm: rn }); ctx.emit(Inst::FpuCSel64 { rd: rtmp2, rn: rtmp1.to_reg(), diff --git a/cranelift/codegen/src/isa/aarch64/mod.rs b/cranelift/codegen/src/isa/aarch64/mod.rs index c239beef05..183fe1c776 100644 --- a/cranelift/codegen/src/isa/aarch64/mod.rs +++ b/cranelift/codegen/src/isa/aarch64/mod.rs @@ -11,7 +11,6 @@ use crate::machinst::{ use crate::result::CodegenResult; use crate::settings as shared_settings; use alloc::{boxed::Box, vec::Vec}; -use core::hash::{Hash, Hasher}; use regalloc::{PrettyPrint, RealRegUniverse}; use target_lexicon::{Aarch64Architecture, Architecture, Triple}; @@ -111,11 +110,6 @@ impl MachBackend for AArch64Backend { self.isa_flags.iter().collect() } - fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) { - self.flags.hash(&mut hasher); - self.isa_flags.hash(&mut hasher); - } - fn reg_universe(&self) -> &RealRegUniverse { &self.reg_universe } @@ -126,13 +120,6 @@ impl MachBackend for AArch64Backend { IntCC::UnsignedGreaterThanOrEqual } - fn unsigned_sub_overflow_condition(&self) -> IntCC { - // unsigned `<`; this corresponds to the carry flag cleared on aarch64, which happens on - // underflow of a subtract (aarch64 follows a carry-cleared-on-borrow convention, the - // opposite of x86). - IntCC::UnsignedLessThan - } - #[cfg(feature = "unwind")] fn emit_unwind_info( &self, diff --git a/cranelift/codegen/src/isa/arm32/mod.rs b/cranelift/codegen/src/isa/arm32/mod.rs index e4280894a1..959be2196b 100644 --- a/cranelift/codegen/src/isa/arm32/mod.rs +++ b/cranelift/codegen/src/isa/arm32/mod.rs @@ -11,7 +11,6 @@ use crate::result::CodegenResult; use crate::settings; use alloc::{boxed::Box, vec::Vec}; -use core::hash::{Hash, Hasher}; use regalloc::{PrettyPrint, RealRegUniverse}; use target_lexicon::{Architecture, ArmArchitecture, Triple}; @@ -101,10 +100,6 @@ impl MachBackend for Arm32Backend { Vec::new() } - fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) { - self.flags.hash(&mut hasher); - } - fn reg_universe(&self) -> &RealRegUniverse { &self.reg_universe } @@ -114,11 +109,6 @@ impl MachBackend for Arm32Backend { IntCC::UnsignedGreaterThanOrEqual } - fn unsigned_sub_overflow_condition(&self) -> IntCC { - // Carry flag clear. - IntCC::UnsignedLessThan - } - fn text_section_builder(&self, num_funcs: u32) -> Box { Box::new(MachTextSectionBuilder::::new(num_funcs)) } diff --git a/cranelift/codegen/src/isa/constraints.rs b/cranelift/codegen/src/isa/constraints.rs index 21a7426ea0..92ec94a24d 100644 --- a/cranelift/codegen/src/isa/constraints.rs +++ b/cranelift/codegen/src/isa/constraints.rs @@ -8,83 +8,6 @@ //! are satisfied. use crate::binemit::CodeOffset; -use crate::ir::ValueLoc; -use crate::isa::{RegClass, RegUnit}; - -/// Register constraint for a single value operand or instruction result. -#[derive(PartialEq, Debug)] -pub struct OperandConstraint { - /// The kind of constraint. - pub kind: ConstraintKind, - - /// The register class of the operand. - /// - /// This applies to all kinds of constraints, but with slightly different meaning. - pub regclass: RegClass, -} - -impl OperandConstraint { - /// Check if this operand constraint is satisfied by the given value location. - /// For tied constraints, this only checks the register class, not that the - /// counterpart operand has the same value location. - pub fn satisfied(&self, loc: ValueLoc) -> bool { - match self.kind { - ConstraintKind::Reg | ConstraintKind::Tied(_) => { - if let ValueLoc::Reg(reg) = loc { - self.regclass.contains(reg) - } else { - false - } - } - ConstraintKind::FixedReg(reg) | ConstraintKind::FixedTied(reg) => { - loc == ValueLoc::Reg(reg) && self.regclass.contains(reg) - } - ConstraintKind::Stack => { - if let ValueLoc::Stack(_) = loc { - true - } else { - false - } - } - } - } -} - -/// The different kinds of operand constraints. -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum ConstraintKind { - /// This operand or result must be a register from the given register class. - Reg, - - /// This operand or result must be a fixed register. - /// - /// The constraint's `regclass` field is the top-level register class containing the fixed - /// register. - FixedReg(RegUnit), - - /// This result value must use the same register as an input value operand. - /// - /// The associated number is the index of the input value operand this result is tied to. The - /// constraint's `regclass` field is the same as the tied operand's register class. - /// - /// When an (in, out) operand pair is tied, this constraint kind appears in both the `ins` and - /// the `outs` arrays. The constraint for the in operand is `Tied(out)`, and the constraint for - /// the out operand is `Tied(in)`. - Tied(u8), - - /// This operand must be a fixed register, and it has a tied counterpart. - /// - /// This works just like `FixedReg`, but additionally indicates that there are identical - /// input/output operands for this fixed register. For an input operand, this means that the - /// value will be clobbered by the instruction - FixedTied(RegUnit), - - /// This operand must be a value in a stack slot. - /// - /// The constraint's `regclass` field is the register class that would normally be used to load - /// and store values of this type. - Stack, -} /// Constraints on the range of a branch instruction. /// diff --git a/cranelift/codegen/src/isa/mod.rs b/cranelift/codegen/src/isa/mod.rs index 45aa5ad045..29b84d5959 100644 --- a/cranelift/codegen/src/isa/mod.rs +++ b/cranelift/codegen/src/isa/mod.rs @@ -44,8 +44,7 @@ //! concurrent function compilations. pub use crate::isa::call_conv::CallConv; -pub use crate::isa::constraints::{BranchRange, ConstraintKind, OperandConstraint}; -pub use crate::isa::registers::{regs_overlap, RegClass, RegClassIndex, RegInfo, RegUnit}; +pub use crate::isa::constraints::BranchRange; pub use crate::isa::stack::{StackBase, StackBaseMask, StackRef}; use crate::flowgraph; @@ -57,10 +56,8 @@ use crate::result::CodegenResult; use crate::settings; use crate::settings::SetResult; use alloc::{boxed::Box, vec::Vec}; -use core::any::Any; use core::fmt; use core::fmt::{Debug, Formatter}; -use core::hash::Hasher; use target_lexicon::{triple, Architecture, OperatingSystem, PointerWidth, Triple}; // This module is made public here for benchmarking purposes. No guarantees are @@ -81,7 +78,6 @@ pub mod unwind; mod call_conv; mod constraints; -pub mod registers; mod stack; #[cfg(test)] @@ -220,8 +216,9 @@ impl TargetFrontendConfig { } } -/// Methods that are specialized to a target ISA. Implies a Display trait that shows the -/// shared flags, as well as any isa-specific flags. +/// Methods that are specialized to a target ISA. +/// +/// Implies a Display trait that shows the shared flags, as well as any ISA-specific flags. pub trait TargetIsa: fmt::Display + Send + Sync { /// Get the name of this ISA. fn name(&self) -> &'static str; @@ -235,85 +232,6 @@ pub trait TargetIsa: fmt::Display + Send + Sync { /// Get the ISA-dependent flag values that were used to make this trait object. fn isa_flags(&self) -> Vec; - /// Hashes all flags, both ISA-independent and ISA-specific, into the - /// specified hasher. - fn hash_all_flags(&self, hasher: &mut dyn Hasher); - - /// Get the default calling convention of this target. - fn default_call_conv(&self) -> CallConv { - CallConv::triple_default(self.triple()) - } - - /// Get the endianness of this ISA. - fn endianness(&self) -> ir::Endianness { - match self.triple().endianness().unwrap() { - target_lexicon::Endianness::Little => ir::Endianness::Little, - target_lexicon::Endianness::Big => ir::Endianness::Big, - } - } - - /// Returns the code (text) section alignment for this ISA. - fn code_section_alignment(&self) -> u64 { - use target_lexicon::*; - match (self.triple().operating_system, self.triple().architecture) { - ( - OperatingSystem::MacOSX { .. } - | OperatingSystem::Darwin - | OperatingSystem::Ios - | OperatingSystem::Tvos, - Architecture::Aarch64(..), - ) => 0x4000, - _ => 0x1000, - } - } - - /// Get the pointer type of this ISA. - fn pointer_type(&self) -> ir::Type { - ir::Type::int(u16::from(self.pointer_bits())).unwrap() - } - - /// Get the width of pointers on this ISA. - fn pointer_width(&self) -> PointerWidth { - self.triple().pointer_width().unwrap() - } - - /// Get the width of pointers on this ISA, in units of bits. - fn pointer_bits(&self) -> u8 { - self.pointer_width().bits() - } - - /// Get the width of pointers on this ISA, in units of bytes. - fn pointer_bytes(&self) -> u8 { - self.pointer_width().bytes() - } - - /// Get the information needed by frontends producing Cranelift IR. - fn frontend_config(&self) -> TargetFrontendConfig { - TargetFrontendConfig { - default_call_conv: self.default_call_conv(), - pointer_width: self.pointer_width(), - } - } - - /// Does the CPU implement scalar comparisons using a CPU flags register? - fn uses_cpu_flags(&self) -> bool { - false - } - - /// Does the CPU implement multi-register addressing? - fn uses_complex_addresses(&self) -> bool { - false - } - - /// Get a data structure describing the registers in this ISA. - fn register_info(&self) -> RegInfo; - - #[cfg(feature = "unwind")] - /// Map a Cranelift register to its corresponding DWARF register. - fn map_dwarf_register(&self, _: RegUnit) -> Result { - Err(RegisterMappingError::UnsupportedArchitecture) - } - #[cfg(feature = "unwind")] /// Map a regalloc::Reg to its corresponding DWARF register. fn map_regalloc_reg_to_dwarf(&self, _: ::regalloc::Reg) -> Result { @@ -323,21 +241,6 @@ pub trait TargetIsa: fmt::Display + Send + Sync { /// IntCC condition for Unsigned Addition Overflow (Carry). fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC; - /// IntCC condition for Unsigned Subtraction Overflow (Borrow/Carry). - fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC; - - /// Returns the flavor of unwind information emitted for this target. - fn unwind_info_kind(&self) -> UnwindInfoKind { - match self.triple().operating_system { - #[cfg(feature = "unwind")] - OperatingSystem::Windows => UnwindInfoKind::Windows, - #[cfg(feature = "unwind")] - _ => UnwindInfoKind::SystemV, - #[cfg(not(feature = "unwind"))] - _ => UnwindInfoKind::None, - } - } - /// Creates unwind information for the function. /// /// Returns `None` if there is no unwind information for the function. @@ -363,10 +266,77 @@ pub trait TargetIsa: fmt::Display + Send + Sync { fn get_mach_backend(&self) -> Option<&dyn MachBackend> { None } +} - /// Return an [Any] reference for downcasting to the ISA-specific implementation of this trait - /// with `isa.as_any().downcast_ref::()`. - fn as_any(&self) -> &dyn Any; +/// Methods implemented for free for target ISA! +impl<'a> dyn TargetIsa + 'a { + /// Get the default calling convention of this target. + pub fn default_call_conv(&self) -> CallConv { + CallConv::triple_default(self.triple()) + } + + /// Get the endianness of this ISA. + pub fn endianness(&self) -> ir::Endianness { + match self.triple().endianness().unwrap() { + target_lexicon::Endianness::Little => ir::Endianness::Little, + target_lexicon::Endianness::Big => ir::Endianness::Big, + } + } + + /// Returns the code (text) section alignment for this ISA. + pub fn code_section_alignment(&self) -> u64 { + use target_lexicon::*; + match (self.triple().operating_system, self.triple().architecture) { + ( + OperatingSystem::MacOSX { .. } + | OperatingSystem::Darwin + | OperatingSystem::Ios + | OperatingSystem::Tvos, + Architecture::Aarch64(..), + ) => 0x4000, + _ => 0x1000, + } + } + + /// Get the pointer type of this ISA. + pub fn pointer_type(&self) -> ir::Type { + ir::Type::int(u16::from(self.pointer_bits())).unwrap() + } + + /// Get the width of pointers on this ISA. + pub(crate) fn pointer_width(&self) -> PointerWidth { + self.triple().pointer_width().unwrap() + } + + /// Get the width of pointers on this ISA, in units of bits. + pub fn pointer_bits(&self) -> u8 { + self.pointer_width().bits() + } + + /// Get the width of pointers on this ISA, in units of bytes. + pub fn pointer_bytes(&self) -> u8 { + self.pointer_width().bytes() + } + + /// Get the information needed by frontends producing Cranelift IR. + pub fn frontend_config(&self) -> TargetFrontendConfig { + TargetFrontendConfig { + default_call_conv: self.default_call_conv(), + pointer_width: self.pointer_width(), + } + } + + /// Returns the flavor of unwind information emitted for this target. + pub(crate) fn unwind_info_kind(&self) -> UnwindInfoKind { + match self.triple().operating_system { + #[cfg(feature = "unwind")] + OperatingSystem::Windows => UnwindInfoKind::Windows, + #[cfg(feature = "unwind")] + _ => UnwindInfoKind::SystemV, + #[cfg(not(feature = "unwind"))] + _ => UnwindInfoKind::None, + } + } } impl Debug for &dyn TargetIsa { diff --git a/cranelift/codegen/src/isa/registers.rs b/cranelift/codegen/src/isa/registers.rs deleted file mode 100644 index e67ae13453..0000000000 --- a/cranelift/codegen/src/isa/registers.rs +++ /dev/null @@ -1,360 +0,0 @@ -//! Data structures describing the registers in an ISA. - -use crate::entity::EntityRef; -use core::fmt; - -/// Register units are the smallest units of register allocation. -/// -/// Normally there is a 1-1 correspondence between registers and register units, but when an ISA -/// has aliasing registers, the aliasing can be modeled with registers that cover multiple -/// register units. -/// -/// The register allocator will enforce that each register unit only gets used for one thing. -pub type RegUnit = u16; - -/// A bit mask indexed by register classes. -/// -/// The size of this type is determined by the ISA with the most register classes. -pub type RegClassMask = u32; - -/// A bit mask indexed by register units. -/// -/// The size of this type is determined by the target ISA that has the most register units defined. -/// Currently that is arm32 which has 64+16 units. -pub type RegUnitMask = [RegClassMask; 3]; - -/// The register units in a target ISA are divided into disjoint register banks. Each bank covers a -/// contiguous range of register units. -/// -/// The `RegBank` struct provides a static description of a register bank. -pub struct RegBank { - /// The name of this register bank as defined in the ISA's DSL definition. - pub name: &'static str, - - /// The first register unit in this bank. - pub first_unit: RegUnit, - - /// The total number of register units in this bank. - pub units: RegUnit, - - /// Array of specially named register units. This array can be shorter than the number of units - /// in the bank. - pub names: &'static [&'static str], - - /// Name prefix to use for those register units in the bank not covered by the `names` array. - /// The remaining register units will be named this prefix followed by their decimal offset in - /// the bank. So with a prefix `r`, registers will be named `r8`, `r9`, ... - pub prefix: &'static str, - - /// Index of the first top-level register class in this bank. - pub first_toprc: usize, - - /// Number of top-level register classes in this bank. - /// - /// The top-level register classes in a bank are guaranteed to be numbered sequentially from - /// `first_toprc`, and all top-level register classes across banks come before any sub-classes. - pub num_toprcs: usize, - - /// Is register pressure tracking enabled for this bank? - pub pressure_tracking: bool, -} - -impl RegBank { - /// Does this bank contain `regunit`? - fn contains(&self, regunit: RegUnit) -> bool { - regunit >= self.first_unit && regunit - self.first_unit < self.units - } - - /// Try to parse a regunit name. The name is not expected to begin with `%`. - fn parse_regunit(&self, name: &str) -> Option { - match self.names.iter().position(|&x| x == name) { - Some(offset) => { - // This is one of the special-cased names. - Some(offset as RegUnit) - } - None => { - // Try a regular prefixed name. - if name.starts_with(self.prefix) { - name[self.prefix.len()..].parse().ok() - } else { - None - } - } - } - .and_then(|offset| { - if offset < self.units { - Some(offset + self.first_unit) - } else { - None - } - }) - } - - /// Write `regunit` to `w`, assuming that it belongs to this bank. - /// All regunits are written with a `%` prefix. - fn write_regunit(&self, f: &mut fmt::Formatter, regunit: RegUnit) -> fmt::Result { - let offset = regunit - self.first_unit; - assert!(offset < self.units); - if (offset as usize) < self.names.len() { - write!(f, "%{}", self.names[offset as usize]) - } else { - write!(f, "%{}{}", self.prefix, offset) - } - } -} - -/// A register class reference. -/// -/// All register classes are statically defined in tables generated from the meta descriptions. -pub type RegClass = &'static RegClassData; - -/// Data about a register class. -/// -/// A register class represents a subset of the registers in a bank. It describes the set of -/// permitted registers for a register operand in a given encoding of an instruction. -/// -/// A register class can be a subset of another register class. The top-level register classes are -/// disjoint. -pub struct RegClassData { - /// The name of the register class. - pub name: &'static str, - - /// The index of this class in the ISA's RegInfo description. - pub index: u8, - - /// How many register units to allocate per register. - pub width: u8, - - /// Index of the register bank this class belongs to. - pub bank: u8, - - /// Index of the top-level register class contains this one. - pub toprc: u8, - - /// The first register unit in this class. - pub first: RegUnit, - - /// Bit-mask of sub-classes of this register class, including itself. - /// - /// Bits correspond to RC indexes. - pub subclasses: RegClassMask, - - /// Mask of register units in the class. If `width > 1`, the mask only has a bit set for the - /// first register unit in each allocatable register. - pub mask: RegUnitMask, - - /// The global `RegInfo` instance containing this register class. - pub info: &'static RegInfo, - - /// The "pinned" register of the associated register bank. - /// - /// This register must be non-volatile (callee-preserved) and must not be the fixed - /// output register of any instruction. - pub pinned_reg: Option, -} - -impl RegClassData { - /// Get the register class index corresponding to the intersection of `self` and `other`. - /// - /// This register class is guaranteed to exist if the register classes overlap. If the register - /// classes don't overlap, returns `None`. - pub fn intersect_index(&self, other: RegClass) -> Option { - // Compute the set of common subclasses. - let mask = self.subclasses & other.subclasses; - - if mask == 0 { - // No overlap. - None - } else { - // Register class indexes are topologically ordered, so the largest common subclass has - // the smallest index. - Some(RegClassIndex(mask.trailing_zeros() as u8)) - } - } - - /// Get the intersection of `self` and `other`. - pub fn intersect(&self, other: RegClass) -> Option { - self.intersect_index(other).map(|rci| self.info.rc(rci)) - } - - /// Returns true if `other` is a subclass of this register class. - /// A register class is considered to be a subclass of itself. - pub fn has_subclass>(&self, other: RCI) -> bool { - self.subclasses & (1 << other.into().0) as u32 != 0 - } - - /// Get the top-level register class containing this class. - pub fn toprc(&self) -> RegClass { - self.info.rc(RegClassIndex(self.toprc)) - } - - /// Get a specific register unit in this class. - pub fn unit(&self, offset: usize) -> RegUnit { - let uoffset = offset * usize::from(self.width); - self.first + uoffset as RegUnit - } - - /// Does this register class contain `regunit`? - pub fn contains(&self, regunit: RegUnit) -> bool { - self.mask[(regunit / 32) as usize] & (1u32 << (regunit % 32) as u32) != 0 - } - - /// If the pinned register is used, is the given regunit the pinned register of this class? - #[inline] - pub fn is_pinned_reg(&self, enabled: bool, regunit: RegUnit) -> bool { - enabled - && self - .pinned_reg - .map_or(false, |pinned_reg| pinned_reg == regunit) - } - - /// Calculate the index of the register inside the class. - pub fn index_of(&self, regunit: RegUnit) -> u16 { - assert!( - self.contains(regunit), - "the {} register class does not contain {}", - self.name, - regunit - ); - regunit - self.first - } -} - -impl fmt::Display for RegClassData { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.name) - } -} - -impl fmt::Debug for RegClassData { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.name) - } -} - -/// Within an ISA, register classes are uniquely identified by their index. -impl PartialEq for RegClassData { - fn eq(&self, other: &Self) -> bool { - self.index == other.index - } -} - -/// A small reference to a register class. -/// -/// Use this when storing register classes in compact data structures. The `RegInfo::rc()` method -/// can be used to get the real register class reference back. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct RegClassIndex(u8); - -impl EntityRef for RegClassIndex { - fn new(idx: usize) -> Self { - Self(idx as u8) - } - - fn index(self) -> usize { - usize::from(self.0) - } -} - -impl From for RegClassIndex { - fn from(rc: RegClass) -> Self { - Self(rc.index) - } -} - -impl fmt::Display for RegClassIndex { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "rci{}", self.0) - } -} - -/// Test of two registers overlap. -/// -/// A register is identified as a `(RegClass, RegUnit)` pair. The register class is needed to -/// determine the width (in regunits) of the register. -pub fn regs_overlap(rc1: RegClass, reg1: RegUnit, rc2: RegClass, reg2: RegUnit) -> bool { - let end1 = reg1 + RegUnit::from(rc1.width); - let end2 = reg2 + RegUnit::from(rc2.width); - !(end1 <= reg2 || end2 <= reg1) -} - -/// Information about the registers in an ISA. -/// -/// The `RegUnit` data structure collects all relevant static information about the registers in an -/// ISA. -#[derive(Clone)] -pub struct RegInfo { - /// All register banks, ordered by their `first_unit`. The register banks are disjoint, but - /// there may be holes of unused register unit numbers between banks due to alignment. - pub banks: &'static [RegBank], - - /// All register classes ordered topologically so a sub-class always follows its parent. - pub classes: &'static [RegClass], -} - -impl RegInfo { - /// Get the register bank holding `regunit`. - pub fn bank_containing_regunit(&self, regunit: RegUnit) -> Option<&RegBank> { - // We could do a binary search, but most ISAs have only two register banks... - self.banks.iter().find(|b| b.contains(regunit)) - } - - /// Try to parse a regunit name. The name is not expected to begin with `%`. - pub fn parse_regunit(&self, name: &str) -> Option { - self.banks - .iter() - .filter_map(|b| b.parse_regunit(name)) - .next() - } - - /// Make a temporary object that can display a register unit. - pub fn display_regunit(&self, regunit: RegUnit) -> DisplayRegUnit { - DisplayRegUnit { - regunit, - reginfo: self, - } - } - - /// Get the register class corresponding to `idx`. - pub fn rc(&self, idx: RegClassIndex) -> RegClass { - self.classes[idx.index()] - } - - /// Get the top-level register class containing the `idx` class. - pub fn toprc(&self, idx: RegClassIndex) -> RegClass { - self.classes[self.rc(idx).toprc as usize] - } -} - -/// Temporary object that holds enough information to print a register unit. -pub struct DisplayRegUnit<'a> { - regunit: RegUnit, - reginfo: &'a RegInfo, -} - -impl<'a> fmt::Display for DisplayRegUnit<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.reginfo.bank_containing_regunit(self.regunit) { - Some(b) => b.write_regunit(f, self.regunit), - None => write!(f, "%INVALID{}", self.regunit), - } - } -} - -#[test] -fn assert_sizes() { - use cranelift_codegen_shared::constants; - use std::mem::size_of; - - // In these tests, size_of returns number of bytes: we actually want the number of bits, so - // multiply these by 8. - assert!( - (size_of::() * 8) <= constants::MAX_NUM_REG_CLASSES, - "need to bump MAX_NUM_REG_CLASSES or change RegClassMask type" - ); - - assert!( - constants::MAX_NUM_REG_CLASSES < (1 << (size_of::() * 8)), - "need to change RegClassIndex's type to a wider type" - ); -} diff --git a/cranelift/codegen/src/isa/s390x/lower.rs b/cranelift/codegen/src/isa/s390x/lower.rs index b36337b294..4ff20745c5 100644 --- a/cranelift/codegen/src/isa/s390x/lower.rs +++ b/cranelift/codegen/src/isa/s390x/lower.rs @@ -661,16 +661,7 @@ fn lower_icmp_to_flags>( (false, true) => NarrowValueMode::SignExtend64, (false, false) => NarrowValueMode::ZeroExtend64, }; - let inputs = [ - InsnInput { - insn: insn, - input: 0, - }, - InsnInput { - insn: insn, - input: 1, - }, - ]; + let inputs = [InsnInput { insn, input: 0 }, InsnInput { insn, input: 1 }]; let ty = ctx.input_ty(insn, 0); let rn = put_input_in_reg(ctx, inputs[0], narrow_mode); if is_signed { @@ -759,16 +750,7 @@ fn lower_icmp_to_flags>( fn lower_fcmp_to_flags>(ctx: &mut C, insn: IRInst) { let ty = ctx.input_ty(insn, 0); let bits = ty_bits(ty); - let inputs = [ - InsnInput { - insn: insn, - input: 0, - }, - InsnInput { - insn: insn, - input: 1, - }, - ]; + let inputs = [InsnInput { insn, input: 0 }, InsnInput { insn, input: 1 }]; let rn = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None); let rm = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None); match bits { @@ -2909,17 +2891,12 @@ fn lower_insn_to_regs>( Opcode::Spill | Opcode::Fill | Opcode::FillNop - | Opcode::Regmove - | Opcode::CopySpecial - | Opcode::CopyToSsa | Opcode::CopyNop | Opcode::AdjustSpDown | Opcode::AdjustSpUpImm | Opcode::AdjustSpDownImm | Opcode::DummySargT - | Opcode::IfcmpSp - | Opcode::Regspill - | Opcode::Regfill => { + | Opcode::IfcmpSp => { panic!("Unused opcode should not be encountered."); } @@ -3117,7 +3094,7 @@ fn lower_branch>( info: Box::new(JTSequenceInfo { default_target, targets: jt_targets, - targets_for_term: targets_for_term, + targets_for_term, }), }); } diff --git a/cranelift/codegen/src/isa/s390x/mod.rs b/cranelift/codegen/src/isa/s390x/mod.rs index 5c1b0b32da..2dd3e9f0b1 100644 --- a/cranelift/codegen/src/isa/s390x/mod.rs +++ b/cranelift/codegen/src/isa/s390x/mod.rs @@ -14,7 +14,6 @@ use crate::result::CodegenResult; use crate::settings as shared_settings; use alloc::{boxed::Box, vec::Vec}; -use core::hash::{Hash, Hasher}; use regalloc::{PrettyPrint, RealRegUniverse, Reg}; use target_lexicon::{Architecture, Triple}; @@ -114,11 +113,6 @@ impl MachBackend for S390xBackend { self.isa_flags.iter().collect() } - fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) { - self.flags.hash(&mut hasher); - self.isa_flags.hash(&mut hasher); - } - fn reg_universe(&self) -> &RealRegUniverse { &self.reg_universe } @@ -132,10 +126,6 @@ impl MachBackend for S390xBackend { IntCC::UnsignedGreaterThan } - fn unsigned_sub_overflow_condition(&self) -> IntCC { - unimplemented!() - } - #[cfg(feature = "unwind")] fn emit_unwind_info( &self, diff --git a/cranelift/codegen/src/isa/test_utils.rs b/cranelift/codegen/src/isa/test_utils.rs index 01c500d6ca..10ec683b70 100644 --- a/cranelift/codegen/src/isa/test_utils.rs +++ b/cranelift/codegen/src/isa/test_utils.rs @@ -2,9 +2,7 @@ #![allow(dead_code)] use crate::binemit::{Addend, CodeOffset, CodeSink, Reloc}; -use crate::ir::Value; -use crate::ir::{ConstantOffset, ExternalName, Function, JumpTable, Opcode, SourceLoc, TrapCode}; -use crate::isa::TargetIsa; +use crate::ir::{ConstantOffset, ExternalName, JumpTable, Opcode, SourceLoc, TrapCode}; use alloc::vec::Vec; use std::string::String; @@ -80,7 +78,5 @@ impl CodeSink for TestCodeSink { fn end_codegen(&mut self) {} - fn add_stack_map(&mut self, _val_list: &[Value], _func: &Function, _isa: &dyn TargetIsa) {} - fn add_call_site(&mut self, _opcode: Opcode, _srcloc: SourceLoc) {} } diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index 9b51a27b07..d8c09b1834 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -6865,16 +6865,11 @@ fn lower_insn_to_regs>( Opcode::Spill | Opcode::Fill | Opcode::FillNop - | Opcode::Regmove - | Opcode::CopySpecial - | Opcode::CopyToSsa | Opcode::CopyNop | Opcode::AdjustSpDown | Opcode::AdjustSpUpImm | Opcode::AdjustSpDownImm | Opcode::IfcmpSp - | Opcode::Regspill - | Opcode::Regfill | Opcode::Copy | Opcode::DummySargT => { panic!("Unused opcode should not be encountered."); diff --git a/cranelift/codegen/src/isa/x64/mod.rs b/cranelift/codegen/src/isa/x64/mod.rs index 43c7fb74a6..47677cc885 100644 --- a/cranelift/codegen/src/isa/x64/mod.rs +++ b/cranelift/codegen/src/isa/x64/mod.rs @@ -15,7 +15,6 @@ use crate::machinst::{ use crate::result::CodegenResult; use crate::settings::{self as shared_settings, Flags}; use alloc::{boxed::Box, vec::Vec}; -use core::hash::{Hash, Hasher}; use regalloc::{PrettyPrint, RealRegUniverse, Reg}; use target_lexicon::Triple; @@ -95,11 +94,6 @@ impl MachBackend for X64Backend { self.x64_flags.iter().collect() } - fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) { - self.flags.hash(&mut hasher); - self.x64_flags.hash(&mut hasher); - } - fn name(&self) -> &'static str { "x64" } @@ -118,12 +112,6 @@ impl MachBackend for X64Backend { IntCC::UnsignedLessThan } - fn unsigned_sub_overflow_condition(&self) -> IntCC { - // unsigned `<`; this corresponds to the carry flag set on x86, which - // indicates a sub has underflowed (carry is borrow for subtract). - IntCC::UnsignedLessThan - } - #[cfg(feature = "unwind")] fn emit_unwind_info( &self, diff --git a/cranelift/codegen/src/legalizer/globalvalue.rs b/cranelift/codegen/src/legalizer/globalvalue.rs index 5c7a72b45c..28cf966172 100644 --- a/cranelift/codegen/src/legalizer/globalvalue.rs +++ b/cranelift/codegen/src/legalizer/globalvalue.rs @@ -24,7 +24,7 @@ pub fn expand_global_value( debug_assert_eq!(opcode, ir::Opcode::GlobalValue); global_value } - _ => panic!("Wanted global_value: {}", func.dfg.display_inst(inst, None)), + _ => panic!("Wanted global_value: {}", func.dfg.display_inst(inst)), }; match func.global_values[gv] { diff --git a/cranelift/codegen/src/legalizer/heap.rs b/cranelift/codegen/src/legalizer/heap.rs index 503bec40db..5239c67daf 100644 --- a/cranelift/codegen/src/legalizer/heap.rs +++ b/cranelift/codegen/src/legalizer/heap.rs @@ -27,7 +27,7 @@ pub fn expand_heap_addr( debug_assert_eq!(opcode, ir::Opcode::HeapAddr); (heap, arg, u64::from(imm)) } - _ => panic!("Wanted heap_addr: {}", func.dfg.display_inst(inst, None)), + _ => panic!("Wanted heap_addr: {}", func.dfg.display_inst(inst)), }; match func.heaps[heap].style { diff --git a/cranelift/codegen/src/legalizer/mod.rs b/cranelift/codegen/src/legalizer/mod.rs index ad97e06fc3..b09d1c601c 100644 --- a/cranelift/codegen/src/legalizer/mod.rs +++ b/cranelift/codegen/src/legalizer/mod.rs @@ -40,7 +40,7 @@ pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: } => (arg, imm), _ => panic!( concat!("Expected ", stringify!($from), ": {}"), - $pos.func.dfg.display_inst($inst, None) + $pos.func.dfg.display_inst($inst) ), }; let ty = $pos.func.dfg.value_type(arg); @@ -57,7 +57,7 @@ pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: } => (arg, imm), _ => panic!( concat!("Expected ", stringify!($from), ": {}"), - $pos.func.dfg.display_inst($inst, None) + $pos.func.dfg.display_inst($inst) ), }; let imm = $pos.ins().iconst($ty, imm); @@ -106,10 +106,7 @@ pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: arg, imm, } => (arg, imm), - _ => panic!( - "Expected irsub_imm: {}", - pos.func.dfg.display_inst(inst, None) - ), + _ => panic!("Expected irsub_imm: {}", pos.func.dfg.display_inst(inst)), }; let ty = pos.func.dfg.value_type(arg); let imm = pos.ins().iconst(ty, imm); @@ -131,10 +128,7 @@ pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: arg, imm, } => (cond, arg, imm), - _ => panic!( - "Expected ircmp_imm: {}", - pos.func.dfg.display_inst(inst, None) - ), + _ => panic!("Expected ircmp_imm: {}", pos.func.dfg.display_inst(inst)), }; let ty = pos.func.dfg.value_type(x); let y = pos.ins().iconst(ty, y); @@ -170,11 +164,11 @@ fn expand_cond_trap( trapz = match opcode { ir::Opcode::Trapz => true, ir::Opcode::Trapnz | ir::Opcode::ResumableTrapnz => false, - _ => panic!("Expected cond trap: {}", func.dfg.display_inst(inst, None)), + _ => panic!("Expected cond trap: {}", func.dfg.display_inst(inst)), }; (arg, code, opcode) } - _ => panic!("Expected cond trap: {}", func.dfg.display_inst(inst, None)), + _ => panic!("Expected cond trap: {}", func.dfg.display_inst(inst)), }; // Split the block after `inst`: @@ -250,7 +244,7 @@ fn expand_br_icmp( destination, args.as_slice(&func.dfg.value_lists)[2..].to_vec(), ), - _ => panic!("Expected br_icmp {}", func.dfg.display_inst(inst, None)), + _ => panic!("Expected br_icmp {}", func.dfg.display_inst(inst)), }; let old_block = func.layout.pp_block(inst); @@ -284,10 +278,7 @@ fn expand_stack_load( stack_slot, offset, } => (stack_slot, offset), - _ => panic!( - "Expected stack_load: {}", - pos.func.dfg.display_inst(inst, None) - ), + _ => panic!("Expected stack_load: {}", pos.func.dfg.display_inst(inst)), }; let addr = pos.ins().stack_addr(addr_ty, stack_slot, offset); @@ -316,10 +307,7 @@ fn expand_stack_store( stack_slot, offset, } => (arg, stack_slot, offset), - _ => panic!( - "Expected stack_store: {}", - pos.func.dfg.display_inst(inst, None) - ), + _ => panic!("Expected stack_store: {}", pos.func.dfg.display_inst(inst)), }; let addr = pos.ins().stack_addr(addr_ty, stack_slot, offset); diff --git a/cranelift/codegen/src/legalizer/table.rs b/cranelift/codegen/src/legalizer/table.rs index 0c4385e96b..14e653e944 100644 --- a/cranelift/codegen/src/legalizer/table.rs +++ b/cranelift/codegen/src/legalizer/table.rs @@ -28,7 +28,7 @@ pub fn expand_table_addr( debug_assert_eq!(opcode, ir::Opcode::TableAddr); (table, arg, offset) } - _ => panic!("Wanted table_addr: {}", func.dfg.display_inst(inst, None)), + _ => panic!("Wanted table_addr: {}", func.dfg.display_inst(inst)), }; dynamic_addr(inst, table, index, element_offset, func); diff --git a/cranelift/codegen/src/machinst/adapter.rs b/cranelift/codegen/src/machinst/adapter.rs index 20e198bdce..ee797c466a 100644 --- a/cranelift/codegen/src/machinst/adapter.rs +++ b/cranelift/codegen/src/machinst/adapter.rs @@ -1,14 +1,13 @@ //! Adapter for a `MachBackend` to implement the `TargetIsa` trait. use crate::ir; -use crate::isa::{RegInfo, TargetIsa}; +use crate::isa::TargetIsa; use crate::machinst::*; use crate::settings::{self, Flags}; #[cfg(feature = "unwind")] use crate::isa::unwind::systemv::RegisterMappingError; -use core::any::Any; use std::fmt; use target_lexicon::Triple; @@ -56,18 +55,6 @@ impl TargetIsa for TargetIsaAdapter { self.backend.isa_flags() } - fn hash_all_flags(&self, hasher: &mut dyn Hasher) { - self.backend.hash_all_flags(hasher); - } - - fn register_info(&self) -> RegInfo { - // Called from function's Display impl, so we need a stub here. - RegInfo { - banks: &[], - classes: &[], - } - } - fn get_mach_backend(&self) -> Option<&dyn MachBackend> { Some(&*self.backend) } @@ -76,10 +63,6 @@ impl TargetIsa for TargetIsaAdapter { self.backend.unsigned_add_overflow_condition() } - fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC { - self.backend.unsigned_sub_overflow_condition() - } - #[cfg(feature = "unwind")] fn create_systemv_cie(&self) -> Option { self.backend.create_systemv_cie() @@ -89,8 +72,4 @@ impl TargetIsa for TargetIsaAdapter { fn map_regalloc_reg_to_dwarf(&self, r: Reg) -> Result { self.backend.map_reg_to_dwarf(r) } - - fn as_any(&self) -> &dyn Any { - self as &dyn Any - } } diff --git a/cranelift/codegen/src/machinst/buffer.rs b/cranelift/codegen/src/machinst/buffer.rs index c16528474b..8d9101ca64 100644 --- a/cranelift/codegen/src/machinst/buffer.rs +++ b/cranelift/codegen/src/machinst/buffer.rs @@ -1641,10 +1641,9 @@ impl TextSectionBuilder for MachTextSectionBuilder { #[cfg(all(test, feature = "arm64"))] mod test { use super::*; - use crate::ir::{ConstantOffset, Function, JumpTable, Value}; + use crate::ir::{ConstantOffset, JumpTable}; use crate::isa::aarch64::inst::xreg; use crate::isa::aarch64::inst::{BranchTarget, CondBrKind, EmitInfo, Inst}; - use crate::isa::TargetIsa; use crate::machinst::MachInstEmit; use crate::settings; use std::default::Default; @@ -2076,7 +2075,6 @@ mod test { fn begin_jumptables(&mut self) {} fn begin_rodata(&mut self) {} fn end_codegen(&mut self) {} - fn add_stack_map(&mut self, _: &[Value], _: &Function, _: &dyn TargetIsa) {} fn add_call_site(&mut self, op: Opcode, _: SourceLoc) { self.callsites.push((self.offset, op)); } diff --git a/cranelift/codegen/src/machinst/mod.rs b/cranelift/codegen/src/machinst/mod.rs index 554e31ad4e..b0122dfe9d 100644 --- a/cranelift/codegen/src/machinst/mod.rs +++ b/cranelift/codegen/src/machinst/mod.rs @@ -69,7 +69,6 @@ use crate::value_label::ValueLabelsRanges; use alloc::boxed::Box; use alloc::vec::Vec; use core::fmt::Debug; -use core::hash::Hasher; use cranelift_entity::PrimaryMap; use regalloc::RegUsageCollector; use regalloc::{ @@ -389,9 +388,6 @@ pub trait MachBackend { /// Get the ISA-dependent flag values that were used to make this trait object. fn isa_flags(&self) -> Vec; - /// Hashes all flags, both ISA-independent and ISA-dependent, into the specified hasher. - fn hash_all_flags(&self, hasher: &mut dyn Hasher); - /// Return triple for this backend. fn triple(&self) -> Triple; @@ -405,10 +401,6 @@ pub trait MachBackend { /// Condition that will be true when an IaddIfcout overflows. fn unsigned_add_overflow_condition(&self) -> IntCC; - /// Machine-specific condcode info needed by TargetIsa. - /// Condition that will be true when an IsubIfcout overflows. - fn unsigned_sub_overflow_condition(&self) -> IntCC; - /// Produces unwind info based on backend results. #[cfg(feature = "unwind")] fn emit_unwind_info( diff --git a/cranelift/codegen/src/print_errors.rs b/cranelift/codegen/src/print_errors.rs index e4f6234ebd..e3fe736616 100644 --- a/cranelift/codegen/src/print_errors.rs +++ b/cranelift/codegen/src/print_errors.rs @@ -4,7 +4,6 @@ use crate::entity::SecondaryMap; use crate::ir; use crate::ir::entities::{AnyEntity, Block, Inst, Value}; use crate::ir::function::Function; -use crate::isa::TargetIsa; use crate::result::CodegenError; use crate::verifier::{VerifierError, VerifierErrors}; use crate::write::{decorate_function, FuncWriter, PlainWriter}; @@ -17,7 +16,6 @@ use core::fmt::Write; /// Pretty-print a verifier error. pub fn pretty_verifier_error<'a>( func: &ir::Function, - isa: Option<&dyn TargetIsa>, func_w: Option>, errors: VerifierErrors, ) -> String { @@ -29,7 +27,6 @@ pub fn pretty_verifier_error<'a>( &mut PrettyVerifierError(func_w.unwrap_or_else(|| Box::new(PlainWriter)), &mut errors), &mut w, func, - &isa.into(), ) .unwrap(); @@ -51,11 +48,10 @@ impl<'a> FuncWriter for PrettyVerifierError<'a> { &mut self, w: &mut dyn Write, func: &Function, - isa: Option<&dyn TargetIsa>, block: Block, indent: usize, ) -> fmt::Result { - pretty_block_header_error(w, func, isa, block, indent, &mut *self.0, self.1) + pretty_block_header_error(w, func, block, indent, &mut *self.0, self.1) } fn write_instruction( @@ -63,11 +59,10 @@ impl<'a> FuncWriter for PrettyVerifierError<'a> { w: &mut dyn Write, func: &Function, aliases: &SecondaryMap>, - isa: Option<&dyn TargetIsa>, inst: Inst, indent: usize, ) -> fmt::Result { - pretty_instruction_error(w, func, aliases, isa, inst, indent, &mut *self.0, self.1) + pretty_instruction_error(w, func, aliases, inst, indent, &mut *self.0, self.1) } fn write_entity_definition( @@ -85,14 +80,13 @@ impl<'a> FuncWriter for PrettyVerifierError<'a> { fn pretty_block_header_error( w: &mut dyn Write, func: &Function, - isa: Option<&dyn TargetIsa>, cur_block: Block, indent: usize, func_w: &mut dyn FuncWriter, errors: &mut Vec, ) -> fmt::Result { let mut s = String::new(); - func_w.write_block_header(&mut s, func, isa, cur_block, indent)?; + func_w.write_block_header(&mut s, func, cur_block, indent)?; write!(w, "{}", s)?; // TODO: Use drain_filter here when it gets stabilized @@ -124,14 +118,13 @@ fn pretty_instruction_error( w: &mut dyn Write, func: &Function, aliases: &SecondaryMap>, - isa: Option<&dyn TargetIsa>, cur_inst: Inst, indent: usize, func_w: &mut dyn FuncWriter, errors: &mut Vec, ) -> fmt::Result { let mut s = String::new(); - func_w.write_instruction(&mut s, func, aliases, isa, cur_inst, indent)?; + func_w.write_instruction(&mut s, func, aliases, cur_inst, indent)?; write!(w, "{}", s)?; // TODO: Use drain_filter here when it gets stabilized @@ -218,9 +211,9 @@ fn print_error(w: &mut dyn Write, err: VerifierError) -> fmt::Result { } /// Pretty-print a Cranelift error. -pub fn pretty_error(func: &ir::Function, isa: Option<&dyn TargetIsa>, err: CodegenError) -> String { +pub fn pretty_error(func: &ir::Function, err: CodegenError) -> String { if let CodegenError::Verifier(e) = err { - pretty_verifier_error(func, isa, None, e) + pretty_verifier_error(func, None, e) } else { err.to_string() } diff --git a/cranelift/codegen/src/unreachable_code.rs b/cranelift/codegen/src/unreachable_code.rs index 327e1af3a3..de1af1ac91 100644 --- a/cranelift/codegen/src/unreachable_code.rs +++ b/cranelift/codegen/src/unreachable_code.rs @@ -31,7 +31,7 @@ pub fn eliminate_unreachable_code( // Remove all instructions from `block`. while let Some(inst) = pos.func.layout.first_inst(block) { - log::trace!(" - {}", pos.func.dfg.display_inst(inst, None)); + log::trace!(" - {}", pos.func.dfg.display_inst(inst)); pos.func.layout.remove_inst(inst); } diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index 96f0e7e32e..283a954d48 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -65,9 +65,8 @@ use crate::ir; use crate::ir::entities::AnyEntity; use crate::ir::instructions::{BranchInfo, CallInfo, InstructionFormat, ResolvedConstraint}; use crate::ir::{ - types, ArgumentLoc, ArgumentPurpose, Block, Constant, FuncRef, Function, GlobalValue, Inst, - InstructionData, JumpTable, Opcode, SigRef, StackSlot, StackSlotKind, Type, Value, ValueDef, - ValueList, ValueLoc, + types, ArgumentPurpose, Block, Constant, FuncRef, Function, GlobalValue, Inst, InstructionData, + JumpTable, Opcode, SigRef, StackSlot, Type, Value, ValueDef, ValueList, }; use crate::isa::TargetIsa; use crate::iterators::IteratorExtras; @@ -319,7 +318,7 @@ impl<'a> Verifier<'a> { /// Determine a contextual error string for an instruction. #[inline] fn context(&self, inst: Inst) -> String { - self.func.dfg.display_inst(inst, self.isa).to_string() + self.func.dfg.display_inst(inst).to_string() } // Check for: @@ -700,12 +699,6 @@ impl<'a> Verifier<'a> { TableAddr { table, .. } => { self.verify_table(inst, table, errors)?; } - RegSpill { dst, .. } => { - self.verify_stack_slot(inst, dst, errors)?; - } - RegFill { src, .. } => { - self.verify_stack_slot(inst, src, errors)?; - } LoadComplex { ref args, .. } => { self.verify_value_list(inst, args, errors)?; } @@ -775,9 +768,6 @@ impl<'a> Verifier<'a> { | IntSelect { .. } | Load { .. } | Store { .. } - | RegMove { .. } - | CopySpecial { .. } - | CopyToSsa { .. } | Trap { .. } | CondTrap { .. } | IntCondTrap { .. } @@ -1377,7 +1367,6 @@ impl<'a> Verifier<'a> { .iter() .map(|a| a.value_type); self.typecheck_variable_args_iterator(inst, arg_types, errors)?; - self.check_outgoing_args(inst, sig_ref, errors)?; } CallInfo::Indirect(sig_ref, _) => { let arg_types = self.func.dfg.signatures[sig_ref] @@ -1385,7 +1374,6 @@ impl<'a> Verifier<'a> { .iter() .map(|a| a.value_type); self.typecheck_variable_args_iterator(inst, arg_types, errors)?; - self.check_outgoing_args(inst, sig_ref, errors)?; } CallInfo::NotACall => {} } @@ -1427,7 +1415,7 @@ impl<'a> Verifier<'a> { self.context(inst), format!( "mismatched argument count for `{}`: got {}, expected {}", - self.func.dfg.display_inst(inst, None), + self.func.dfg.display_inst(inst), variable_args.len(), i, ), @@ -1436,77 +1424,6 @@ impl<'a> Verifier<'a> { Ok(()) } - /// Check the locations assigned to outgoing call arguments. - /// - /// When a signature has been legalized, all values passed as outgoing arguments on the stack - /// must be assigned to a matching `OutgoingArg` stack slot. - fn check_outgoing_args( - &self, - inst: Inst, - sig_ref: SigRef, - errors: &mut VerifierErrors, - ) -> VerifierStepResult<()> { - let sig = &self.func.dfg.signatures[sig_ref]; - - let args = self.func.dfg.inst_variable_args(inst); - let expected_args = &sig.params[..]; - - for (&arg, &abi) in args.iter().zip(expected_args) { - // Value types have already been checked by `typecheck_variable_args_iterator()`. - if let ArgumentLoc::Stack(offset) = abi.location { - let arg_loc = self.func.locations[arg]; - if let ValueLoc::Stack(ss) = arg_loc { - // Argument value is assigned to a stack slot as expected. - self.verify_stack_slot(inst, ss, errors)?; - let slot = &self.func.stack_slots[ss]; - if slot.kind != StackSlotKind::OutgoingArg { - return errors.fatal(( - inst, - self.context(inst), - format!( - "Outgoing stack argument {} in wrong stack slot: {} = {}", - arg, ss, slot, - ), - )); - } - if slot.offset != Some(offset) { - return errors.fatal(( - inst, - self.context(inst), - format!( - "Outgoing stack argument {} should have offset {}: {} = {}", - arg, offset, ss, slot, - ), - )); - } - if abi.purpose == ArgumentPurpose::StructArgument(slot.size) { - } else if slot.size != abi.value_type.bytes() { - return errors.fatal(( - inst, - self.context(inst), - format!( - "Outgoing stack argument {} wrong size for {}: {} = {}", - arg, abi.value_type, ss, slot, - ), - )); - } - } else { - let reginfo = self.isa.map(|i| i.register_info()); - return errors.fatal(( - inst, - self.context(inst), - format!( - "Outgoing stack argument {} in wrong location: {}", - arg, - arg_loc.display(reginfo.as_ref()) - ), - )); - } - } - } - Ok(()) - } - fn typecheck_return(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult<()> { if self.func.dfg[inst].opcode().is_return() { let args = self.func.dfg.inst_variable_args(inst); @@ -1668,22 +1585,6 @@ impl<'a> Verifier<'a> { "copy_nop src and dst types must be the same", )); } - let src_loc = self.func.locations[arg]; - let dst_loc = self.func.locations[dst_val]; - let locs_ok = match (src_loc, dst_loc) { - (ValueLoc::Stack(src_slot), ValueLoc::Stack(dst_slot)) => src_slot == dst_slot, - _ => false, - }; - if !locs_ok { - return errors.fatal(( - inst, - self.context(inst), - format!( - "copy_nop must refer to identical stack slots, but found {:?} vs {:?}", - src_loc, dst_loc, - ), - )); - } } Ok(()) } @@ -1903,7 +1804,7 @@ impl<'a> Verifier<'a> { if !errors.is_empty() { log::warn!( "Found verifier errors in function:\n{}", - pretty_verifier_error(self.func, None, None, errors.clone()) + pretty_verifier_error(self.func, None, errors.clone()) ); } diff --git a/cranelift/codegen/src/write.rs b/cranelift/codegen/src/write.rs index 567f86c2c7..3c262a5f6d 100644 --- a/cranelift/codegen/src/write.rs +++ b/cranelift/codegen/src/write.rs @@ -5,10 +5,7 @@ use crate::entity::SecondaryMap; use crate::ir::entities::AnyEntity; -use crate::ir::{ - Block, DataFlowGraph, DisplayFunctionAnnotations, Function, Inst, SigRef, Type, Value, ValueDef, -}; -use crate::isa::{RegInfo, TargetIsa}; +use crate::ir::{Block, DataFlowGraph, Function, Inst, SigRef, Type, Value, ValueDef}; use crate::packed_option::ReservedValue; use alloc::string::String; use alloc::vec::Vec; @@ -21,7 +18,6 @@ pub trait FuncWriter { &mut self, w: &mut dyn Write, func: &Function, - isa: Option<&dyn TargetIsa>, block: Block, indent: usize, ) -> fmt::Result; @@ -32,28 +28,17 @@ pub trait FuncWriter { w: &mut dyn Write, func: &Function, aliases: &SecondaryMap>, - isa: Option<&dyn TargetIsa>, inst: Inst, indent: usize, ) -> fmt::Result; /// Write the preamble to `w`. By default, this uses `write_entity_definition`. - fn write_preamble( - &mut self, - w: &mut dyn Write, - func: &Function, - regs: Option<&RegInfo>, - ) -> Result { - self.super_preamble(w, func, regs) + fn write_preamble(&mut self, w: &mut dyn Write, func: &Function) -> Result { + self.super_preamble(w, func) } /// Default impl of `write_preamble` - fn super_preamble( - &mut self, - w: &mut dyn Write, - func: &Function, - regs: Option<&RegInfo>, - ) -> Result { + fn super_preamble(&mut self, w: &mut dyn Write, func: &Function) -> Result { let mut any = false; for (ss, slot) in func.stack_slots.iter() { @@ -84,7 +69,7 @@ pub trait FuncWriter { // signatures. for (sig, sig_data) in &func.dfg.signatures { any = true; - self.write_entity_definition(w, func, sig.into(), &sig_data.display(regs))?; + self.write_entity_definition(w, func, sig.into(), &sig_data)?; } for (fnref, ext_func) in &func.dfg.ext_funcs { @@ -145,33 +130,27 @@ impl FuncWriter for PlainWriter { w: &mut dyn Write, func: &Function, aliases: &SecondaryMap>, - isa: Option<&dyn TargetIsa>, inst: Inst, indent: usize, ) -> fmt::Result { - write_instruction(w, func, aliases, isa, inst, indent) + write_instruction(w, func, aliases, inst, indent) } fn write_block_header( &mut self, w: &mut dyn Write, func: &Function, - isa: Option<&dyn TargetIsa>, block: Block, indent: usize, ) -> fmt::Result { - write_block_header(w, func, isa, block, indent) + write_block_header(w, func, block, indent) } } /// Write `func` to `w` as equivalent text. /// Use `isa` to emit ISA-dependent annotations. -pub fn write_function( - w: &mut dyn Write, - func: &Function, - annotations: &DisplayFunctionAnnotations, -) -> fmt::Result { - decorate_function(&mut PlainWriter, w, func, annotations) +pub fn write_function(w: &mut dyn Write, func: &Function) -> fmt::Result { + decorate_function(&mut PlainWriter, w, func) } /// Create a reverse-alias map from a value to all aliases having that value as a direct target @@ -193,21 +172,17 @@ pub fn decorate_function( func_w: &mut FW, w: &mut dyn Write, func: &Function, - annotations: &DisplayFunctionAnnotations, ) -> fmt::Result { - let regs = annotations.isa.map(TargetIsa::register_info); - let regs = regs.as_ref(); - write!(w, "function ")?; - write_spec(w, func, regs)?; + write_spec(w, func)?; writeln!(w, " {{")?; let aliases = alias_map(func); - let mut any = func_w.write_preamble(w, func, regs)?; + let mut any = func_w.write_preamble(w, func)?; for block in &func.layout { if any { writeln!(w)?; } - decorate_block(func_w, w, func, &aliases, annotations, block)?; + decorate_block(func_w, w, func, &aliases, block)?; any = true; } writeln!(w, "}}") @@ -217,27 +192,16 @@ pub fn decorate_function( // // Function spec. -fn write_spec(w: &mut dyn Write, func: &Function, regs: Option<&RegInfo>) -> fmt::Result { - write!(w, "{}{}", func.name, func.signature.display(regs)) +fn write_spec(w: &mut dyn Write, func: &Function) -> fmt::Result { + write!(w, "{}{}", func.name, func.signature) } //---------------------------------------------------------------------- // // Basic blocks -fn write_arg( - w: &mut dyn Write, - func: &Function, - regs: Option<&RegInfo>, - arg: Value, -) -> fmt::Result { - write!(w, "{}: {}", arg, func.dfg.value_type(arg))?; - let loc = func.locations[arg]; - if loc.is_assigned() { - write!(w, " [{}]", loc.display(regs))? - } - - Ok(()) +fn write_arg(w: &mut dyn Write, func: &Function, arg: Value) -> fmt::Result { + write!(w, "{}: {}", arg, func.dfg.value_type(arg)) } /// Write out the basic block header, outdented: @@ -249,28 +213,24 @@ fn write_arg( pub fn write_block_header( w: &mut dyn Write, func: &Function, - isa: Option<&dyn TargetIsa>, block: Block, indent: usize, ) -> fmt::Result { // The `indent` is the instruction indentation. block headers are 4 spaces out from that. write!(w, "{1:0$}{2}", indent - 4, "", block)?; - let regs = isa.map(TargetIsa::register_info); - let regs = regs.as_ref(); - let mut args = func.dfg.block_params(block).iter().cloned(); match args.next() { None => return writeln!(w, ":"), Some(arg) => { write!(w, "(")?; - write_arg(w, func, regs, arg)?; + write_arg(w, func, arg)?; } } // Remaining arguments. for arg in args { write!(w, ", ")?; - write_arg(w, func, regs, arg)?; + write_arg(w, func, arg)?; } writeln!(w, "):") } @@ -280,20 +240,18 @@ fn decorate_block( w: &mut dyn Write, func: &Function, aliases: &SecondaryMap>, - annotations: &DisplayFunctionAnnotations, block: Block, ) -> fmt::Result { // Indent all instructions if any srclocs are present. let indent = if func.srclocs.is_empty() { 4 } else { 36 }; - let isa = annotations.isa; - func_w.write_block_header(w, func, isa, block, indent)?; + func_w.write_block_header(w, func, block, indent)?; for a in func.dfg.block_params(block).iter().cloned() { write_value_aliases(w, aliases, a, indent)?; } for inst in func.layout.block_insts(block) { - func_w.write_instruction(w, func, aliases, isa, inst, indent)?; + func_w.write_instruction(w, func, aliases, inst, indent)?; } Ok(()) @@ -359,7 +317,6 @@ fn write_instruction( w: &mut dyn Write, func: &Function, aliases: &SecondaryMap>, - isa: Option<&dyn TargetIsa>, inst: Inst, indent: usize, ) -> fmt::Result { @@ -397,7 +354,7 @@ fn write_instruction( None => write!(w, "{}", opcode)?, } - write_operands(w, &func.dfg, isa, inst)?; + write_operands(w, &func.dfg, inst)?; writeln!(w)?; // Value aliases come out on lines after the instruction defining the referent. @@ -408,12 +365,7 @@ fn write_instruction( } /// Write the operands of `inst` to `w` with a prepended space. -pub fn write_operands( - w: &mut dyn Write, - dfg: &DataFlowGraph, - isa: Option<&dyn TargetIsa>, - inst: Inst, -) -> fmt::Result { +pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt::Result { let pool = &dfg.value_lists; use crate::ir::instructions::InstructionData::*; match dfg[inst] { @@ -582,57 +534,6 @@ pub fn write_operands( offset ) } - RegMove { arg, src, dst, .. } => { - if let Some(isa) = isa { - let regs = isa.register_info(); - write!( - w, - " {}, {} -> {}", - arg, - regs.display_regunit(src), - regs.display_regunit(dst) - ) - } else { - write!(w, " {}, %{} -> %{}", arg, src, dst) - } - } - CopySpecial { src, dst, .. } => { - if let Some(isa) = isa { - let regs = isa.register_info(); - write!( - w, - " {} -> {}", - regs.display_regunit(src), - regs.display_regunit(dst) - ) - } else { - write!(w, " %{} -> %{}", src, dst) - } - } - CopyToSsa { src, .. } => { - if let Some(isa) = isa { - let regs = isa.register_info(); - write!(w, " {}", regs.display_regunit(src)) - } else { - write!(w, " %{}", src) - } - } - RegSpill { arg, src, dst, .. } => { - if let Some(isa) = isa { - let regs = isa.register_info(); - write!(w, " {}, {} -> {}", arg, regs.display_regunit(src), dst) - } else { - write!(w, " {}, %{} -> {}", arg, src, dst) - } - } - RegFill { arg, src, dst, .. } => { - if let Some(isa) = isa { - let regs = isa.register_info(); - write!(w, " {}, {} -> {}", arg, src, regs.display_regunit(dst)) - } else { - write!(w, " {}, {} -> %{}", arg, src, dst) - } - } Trap { code, .. } => write!(w, " {}", code), CondTrap { arg, code, .. } => write!(w, " {}, {}", arg, code), IntCondTrap { diff --git a/cranelift/docs/ir.md b/cranelift/docs/ir.md index d4625621f2..31d0e83867 100644 --- a/cranelift/docs/ir.md +++ b/cranelift/docs/ir.md @@ -884,10 +884,6 @@ are assigned to registers or stack slots. This approach permits SSA form to be preserved throughout the register allocation pass and beyond. -Register values can be temporarily diverted to other registers by the -`regmove` instruction, and to and from stack slots by `regspill` -and `regfill`. - ## Instruction groups All of the shared instructions are part of the `base` instruction diff --git a/cranelift/filetests/filetests/licm/reject.clif b/cranelift/filetests/filetests/licm/reject.clif index eab03760b6..378a9003d1 100644 --- a/cranelift/filetests/filetests/licm/reject.clif +++ b/cranelift/filetests/filetests/licm/reject.clif @@ -7,9 +7,6 @@ block0(v0: i32): jump block1(v0) block1(v1: i32): - regmove.i32 v0, %x10 -> %x20 -; check: block1(v1: i32): -; check: regmove.i32 v0, %x10 -> %x20 v2 = iconst.i32 1 brz v1, block3(v1) jump block2 diff --git a/cranelift/filetests/filetests/parser/tiny.clif b/cranelift/filetests/filetests/parser/tiny.clif index 42fa5a8157..35cf075022 100644 --- a/cranelift/filetests/filetests/parser/tiny.clif +++ b/cranelift/filetests/filetests/parser/tiny.clif @@ -183,42 +183,6 @@ block0(v1: i32): ; nextln: store_complex v3, v1+v2 ; nextln: store_complex v3, v1+v2+1 -; Register diversions. -; This test file has no ISA, so we can unly use register unit numbers. -function %diversion(i32) { - ss0 = spill_slot 4 - -block0(v1: i32): - regmove v1, %10 -> %20 - regmove v1, %20 -> %10 - regspill v1, %10 -> ss0 - regfill v1, ss0 -> %10 - return -} -; sameln: function %diversion(i32) fast { -; nextln: ss0 = spill_slot 4 -; check: block0(v1: i32): -; nextln: regmove v1, %10 -> %20 -; nextln: regmove v1, %20 -> %10 -; nextln: regspill v1, %10 -> ss0 -; nextln: regfill v1, ss0 -> %10 -; nextln: return -; nextln: } - -; Register copies. -function %copy_special() { -block0: - copy_special %10 -> %20 - copy_special %20 -> %10 - return -} -; sameln: function %copy_special() fast { -; nextln: block0: -; nextln: copy_special %10 -> %20 -; nextln: copy_special %20 -> %10 -; nextln: return -; nextln: } - function %cond_traps(i32) { block0(v0: i32): trapz v0, stk_ovf diff --git a/cranelift/filetests/filetests/simple_gvn/reject.clif b/cranelift/filetests/filetests/simple_gvn/reject.clif index c4613af4dc..bb01fe5839 100644 --- a/cranelift/filetests/filetests/simple_gvn/reject.clif +++ b/cranelift/filetests/filetests/simple_gvn/reject.clif @@ -1,15 +1,5 @@ test simple-gvn -function %other_side_effects(i32) -> i32 { -block0(v0: i32): - regmove v0, %10 -> %20 - regmove v0, %10 -> %20 - regmove v0, %20 -> %10 -; check: regmove v0, %10 -> %20 -; check: regmove v0, %10 -> %20 - return v0 -} - function %differing_typevars() -> i64 { block0: v0 = iconst.i32 7 diff --git a/cranelift/filetests/src/lib.rs b/cranelift/filetests/src/lib.rs index ff8031dade..e5ea69e27f 100644 --- a/cranelift/filetests/src/lib.rs +++ b/cranelift/filetests/src/lib.rs @@ -51,7 +51,6 @@ mod test_run; mod test_safepoint; mod test_simple_gvn; mod test_simple_preopt; -mod test_stack_maps; mod test_unwind; mod test_verifier; @@ -127,7 +126,6 @@ fn new_subtest(parsed: &TestCommand) -> anyhow::Result "safepoint" => test_safepoint::subtest(parsed), "simple-gvn" => test_simple_gvn::subtest(parsed), "simple_preopt" => test_simple_preopt::subtest(parsed), - "stack_maps" => test_stack_maps::subtest(parsed), "unwind" => test_unwind::subtest(parsed), "verifier" => test_verifier::subtest(parsed), _ => anyhow::bail!("unknown test command '{}'", parsed.command), @@ -136,9 +134,8 @@ fn new_subtest(parsed: &TestCommand) -> anyhow::Result fn pretty_anyhow_error( func: &cranelift_codegen::ir::Function, - isa: Option<&dyn cranelift_codegen::isa::TargetIsa>, err: cranelift_codegen::CodegenError, ) -> anyhow::Error { - let s = cranelift_codegen::print_errors::pretty_error(func, isa, err); + let s = cranelift_codegen::print_errors::pretty_error(func, err); anyhow::anyhow!("{}", s) } diff --git a/cranelift/filetests/src/runone.rs b/cranelift/filetests/src/runone.rs index 5c1ff01ec9..59bebcba77 100644 --- a/cranelift/filetests/src/runone.rs +++ b/cranelift/filetests/src/runone.rs @@ -179,9 +179,8 @@ fn run_one_test<'a>( // Should we run the verifier before this test? if !context.verified && test.needs_verifier() { - verify_function(&func, context.flags_or_isa()).map_err(|errors| { - anyhow::anyhow!("{}", pretty_verifier_error(&func, isa, None, errors)) - })?; + verify_function(&func, context.flags_or_isa()) + .map_err(|errors| anyhow::anyhow!("{}", pretty_verifier_error(&func, None, errors)))?; context.verified = true; } diff --git a/cranelift/filetests/src/test_cat.rs b/cranelift/filetests/src/test_cat.rs index adf16e9403..fe25ea4935 100644 --- a/cranelift/filetests/src/test_cat.rs +++ b/cranelift/filetests/src/test_cat.rs @@ -31,6 +31,6 @@ impl SubTest for TestCat { } fn run(&self, func: Cow, context: &Context) -> anyhow::Result<()> { - subtest::run_filecheck(&func.display(context.isa).to_string(), context) + subtest::run_filecheck(&func.display().to_string(), context) } } diff --git a/cranelift/filetests/src/test_compile.rs b/cranelift/filetests/src/test_compile.rs index 920a1bc803..6eaaadb392 100644 --- a/cranelift/filetests/src/test_compile.rs +++ b/cranelift/filetests/src/test_compile.rs @@ -6,7 +6,6 @@ use crate::subtest::{run_filecheck, Context, SubTest}; use cranelift_codegen; use cranelift_codegen::binemit::{self, CodeInfo}; use cranelift_codegen::ir; -use cranelift_codegen::isa; use cranelift_reader::TestCommand; use log::info; use std::borrow::Cow; @@ -43,12 +42,12 @@ impl SubTest for TestCompile { let CodeInfo { total_size, .. } = comp_ctx .compile(isa) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, e))?; + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, e))?; info!( "Generated {} bytes of code:\n{}", total_size, - comp_ctx.func.display(isa) + comp_ctx.func.display() ); let disasm = comp_ctx @@ -102,11 +101,4 @@ impl binemit::CodeSink for SizeSink { fn begin_jumptables(&mut self) {} fn begin_rodata(&mut self) {} fn end_codegen(&mut self) {} - fn add_stack_map( - &mut self, - _: &[ir::entities::Value], - _: &ir::Function, - _: &dyn isa::TargetIsa, - ) { - } } diff --git a/cranelift/filetests/src/test_dce.rs b/cranelift/filetests/src/test_dce.rs index 826f7cacc9..48d28c7e72 100644 --- a/cranelift/filetests/src/test_dce.rs +++ b/cranelift/filetests/src/test_dce.rs @@ -37,9 +37,9 @@ impl SubTest for TestDCE { comp_ctx.compute_loop_analysis(); comp_ctx .dce(context.flags_or_isa()) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, Into::into(e)))?; + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, Into::into(e)))?; - let text = comp_ctx.func.display(context.isa).to_string(); + let text = comp_ctx.func.display().to_string(); run_filecheck(&text, context) } } diff --git a/cranelift/filetests/src/test_legalizer.rs b/cranelift/filetests/src/test_legalizer.rs index f161226127..8af819bed2 100644 --- a/cranelift/filetests/src/test_legalizer.rs +++ b/cranelift/filetests/src/test_legalizer.rs @@ -39,9 +39,9 @@ impl SubTest for TestLegalizer { comp_ctx.compute_cfg(); comp_ctx .legalize(isa) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, e))?; + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, e))?; - let text = comp_ctx.func.display(Some(isa)).to_string(); + let text = comp_ctx.func.display().to_string(); run_filecheck(&text, context) } } diff --git a/cranelift/filetests/src/test_licm.rs b/cranelift/filetests/src/test_licm.rs index ad23d281d1..2ca245055a 100644 --- a/cranelift/filetests/src/test_licm.rs +++ b/cranelift/filetests/src/test_licm.rs @@ -42,9 +42,9 @@ impl SubTest for TestLICM { comp_ctx.compute_loop_analysis(); comp_ctx .licm(isa) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, Into::into(e)))?; + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, Into::into(e)))?; - let text = comp_ctx.func.display(context.isa).to_string(); + let text = comp_ctx.func.display().to_string(); run_filecheck(&text, context) } } diff --git a/cranelift/filetests/src/test_peepmatic.rs b/cranelift/filetests/src/test_peepmatic.rs index 5d228239a0..6efe42e00e 100644 --- a/cranelift/filetests/src/test_peepmatic.rs +++ b/cranelift/filetests/src/test_peepmatic.rs @@ -37,8 +37,8 @@ impl SubTest for TestPreopt { comp_ctx.compute_cfg(); comp_ctx .preopt(isa) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, Into::into(e)))?; - let text = &comp_ctx.func.display(isa).to_string(); + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, Into::into(e)))?; + let text = &comp_ctx.func.display().to_string(); log::debug!("After peepmatic-based simple_preopt:\n{}", text); // Only actually run the filecheck if peepmatic is enabled, because it diff --git a/cranelift/filetests/src/test_preopt.rs b/cranelift/filetests/src/test_preopt.rs index 072bd7a2ad..b9d9e9d60c 100644 --- a/cranelift/filetests/src/test_preopt.rs +++ b/cranelift/filetests/src/test_preopt.rs @@ -40,9 +40,9 @@ impl SubTest for TestPreopt { let mut comp_ctx = cranelift_codegen::Context::for_function(func.into_owned()); optimize(&mut comp_ctx, isa) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, Into::into(e)))?; + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, Into::into(e)))?; - let text = comp_ctx.func.display(context.isa).to_string(); + let text = comp_ctx.func.display().to_string(); run_filecheck(&text, context) } } diff --git a/cranelift/filetests/src/test_safepoint.rs b/cranelift/filetests/src/test_safepoint.rs index 0b0c725e1e..49676e01be 100644 --- a/cranelift/filetests/src/test_safepoint.rs +++ b/cranelift/filetests/src/test_safepoint.rs @@ -25,10 +25,10 @@ impl SubTest for TestSafepoint { comp_ctx.compute_cfg(); comp_ctx .legalize(isa) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, e))?; + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, e))?; comp_ctx.compute_domtree(); - let text = comp_ctx.func.display(context.isa).to_string(); + let text = comp_ctx.func.display().to_string(); run_filecheck(&text, context) } } diff --git a/cranelift/filetests/src/test_simple_gvn.rs b/cranelift/filetests/src/test_simple_gvn.rs index 66baa0b7a5..bb563f4315 100644 --- a/cranelift/filetests/src/test_simple_gvn.rs +++ b/cranelift/filetests/src/test_simple_gvn.rs @@ -36,9 +36,9 @@ impl SubTest for TestSimpleGVN { comp_ctx.flowgraph(); comp_ctx .simple_gvn(context.flags_or_isa()) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, Into::into(e)))?; + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, Into::into(e)))?; - let text = comp_ctx.func.display(context.isa).to_string(); + let text = comp_ctx.func.display().to_string(); run_filecheck(&text, context) } } diff --git a/cranelift/filetests/src/test_simple_preopt.rs b/cranelift/filetests/src/test_simple_preopt.rs index 2187afe0eb..01fef79b82 100644 --- a/cranelift/filetests/src/test_simple_preopt.rs +++ b/cranelift/filetests/src/test_simple_preopt.rs @@ -38,8 +38,8 @@ impl SubTest for TestSimplePreopt { comp_ctx.compute_cfg(); comp_ctx .preopt(isa) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, e))?; - let text = &comp_ctx.func.display(isa).to_string(); + .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, e))?; + let text = &comp_ctx.func.display().to_string(); log::debug!("After simple_preopt:\n{}", text); // Only actually run the filecheck if peepmatic is *not* enabled, diff --git a/cranelift/filetests/src/test_stack_maps.rs b/cranelift/filetests/src/test_stack_maps.rs deleted file mode 100644 index 1684520af0..0000000000 --- a/cranelift/filetests/src/test_stack_maps.rs +++ /dev/null @@ -1,109 +0,0 @@ -use crate::subtest::{run_filecheck, Context, SubTest}; -use cranelift_codegen::binemit::{self, Addend, CodeOffset, CodeSink, Reloc, StackMap}; -use cranelift_codegen::ir::*; -use cranelift_codegen::isa::TargetIsa; -use cranelift_reader::TestCommand; -use std::borrow::Cow; -use std::fmt::Write; - -struct TestStackMaps; - -pub fn subtest(parsed: &TestCommand) -> anyhow::Result> { - assert_eq!(parsed.command, "stack_maps"); - if !parsed.options.is_empty() { - anyhow::bail!("No options allowed on {}", parsed); - } - Ok(Box::new(TestStackMaps)) -} - -impl SubTest for TestStackMaps { - fn name(&self) -> &'static str { - "stack_maps" - } - - fn run(&self, func: Cow, context: &Context) -> anyhow::Result<()> { - let mut comp_ctx = cranelift_codegen::Context::for_function(func.into_owned()); - - comp_ctx - .compile(context.isa.expect("`test stack_maps` requires an isa")) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, context.isa, e))?; - - let mut sink = TestStackMapsSink::default(); - // TODO remove entirely? seems a bit meaningless now - binemit::emit_function( - &comp_ctx.func, - |func, inst, sink, isa| { - if func.dfg[inst].opcode() == Opcode::Safepoint { - writeln!(&mut sink.text, "{}", func.dfg.display_inst(inst, isa)).unwrap(); - } - }, - &mut sink, - context.isa.expect("`test stack_maps` requires an isa"), - ); - - let mut text = comp_ctx.func.display(context.isa).to_string(); - text.push('\n'); - text.push_str("Stack maps:\n"); - text.push('\n'); - text.push_str(&sink.text); - - run_filecheck(&text, context) - } -} - -#[derive(Default)] -struct TestStackMapsSink { - offset: u32, - text: String, -} - -impl CodeSink for TestStackMapsSink { - fn offset(&self) -> CodeOffset { - self.offset - } - - fn put1(&mut self, _: u8) { - self.offset += 1; - } - - fn put2(&mut self, _: u16) { - self.offset += 2; - } - - fn put4(&mut self, _: u32) { - self.offset += 4; - } - - fn put8(&mut self, _: u64) { - self.offset += 8; - } - - fn reloc_external(&mut self, _: SourceLoc, _: Reloc, _: &ExternalName, _: Addend) {} - fn reloc_constant(&mut self, _: Reloc, _: ConstantOffset) {} - fn reloc_jt(&mut self, _: Reloc, _: JumpTable) {} - fn trap(&mut self, _: TrapCode, _: SourceLoc) {} - fn begin_jumptables(&mut self) {} - fn begin_rodata(&mut self) {} - fn end_codegen(&mut self) {} - - fn add_stack_map(&mut self, val_list: &[Value], func: &Function, isa: &dyn TargetIsa) { - let map = StackMap::from_values(&val_list, func, isa); - - writeln!(&mut self.text, " - mapped words: {}", map.mapped_words()).unwrap(); - write!(&mut self.text, " - live: [").unwrap(); - - let mut needs_comma_space = false; - for i in 0..(map.mapped_words() as usize) { - if map.get_bit(i) { - if needs_comma_space { - write!(&mut self.text, ", ").unwrap(); - } - needs_comma_space = true; - - write!(&mut self.text, "{}", i).unwrap(); - } - } - - writeln!(&mut self.text, "]").unwrap(); - } -} diff --git a/cranelift/frontend/src/frontend.rs b/cranelift/frontend/src/frontend.rs index 63ccdcb56b..7e72608b51 100644 --- a/cranelift/frontend/src/frontend.rs +++ b/cranelift/frontend/src/frontend.rs @@ -4,14 +4,13 @@ use crate::variable::Variable; use cranelift_codegen::cursor::{Cursor, FuncCursor}; use cranelift_codegen::entity::{EntitySet, SecondaryMap}; use cranelift_codegen::ir; -use cranelift_codegen::ir::function::DisplayFunction; use cranelift_codegen::ir::{ types, AbiParam, Block, DataFlowGraph, ExtFuncData, ExternalName, FuncRef, Function, GlobalValue, GlobalValueData, Heap, HeapData, Inst, InstBuilder, InstBuilderBase, InstructionData, JumpTable, JumpTableData, LibCall, MemFlags, SigRef, Signature, StackSlot, StackSlotData, Type, Value, ValueLabel, ValueLabelAssignments, ValueLabelStart, }; -use cranelift_codegen::isa::{TargetFrontendConfig, TargetIsa}; +use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_codegen::packed_option::PackedOption; /// Structure used for translating a series of functions into Cranelift IR. @@ -481,7 +480,7 @@ impl<'a> FunctionBuilder<'a> { // Iterate manually to provide more helpful error messages. for block in self.func_ctx.blocks.keys() { if let Err((inst, _msg)) = self.func.is_block_basic(block) { - let inst_str = self.func.dfg.display_inst(inst, None); + let inst_str = self.func.dfg.display_inst(inst); panic!("{} failed basic block invariants on {}", block, inst_str); } } @@ -579,15 +578,6 @@ impl<'a> FunctionBuilder<'a> { pub fn is_filled(&self) -> bool { self.func_ctx.blocks[self.position.unwrap()].filled } - - /// Returns a displayable object for the function as it is. - /// - /// Useful for debug purposes. Use it with `None` for standard printing. - // Clippy thinks the lifetime that follows is needless, but rustc needs it - #[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_lifetimes))] - pub fn display<'b, I: Into>>(&'b self, isa: I) -> DisplayFunction { - self.func.display(isa) - } } /// Helper functions @@ -955,7 +945,7 @@ mod tests { let flags = settings::Flags::new(settings::builder()); // println!("{}", func.display(None)); if let Err(errors) = verify_function(&func, &flags) { - panic!("{}\n{}", func.display(None), errors) + panic!("{}\n{}", func.display(), errors) } } @@ -1009,7 +999,7 @@ mod tests { } assert_eq!( - func.display(None).to_string(), + func.display().to_string(), "function %sample() -> i32 system_v { sig0 = (i64, i64, i64) system_v fn0 = %Memcpy sig0 @@ -1065,7 +1055,7 @@ block0: } assert_eq!( - func.display(None).to_string(), + func.display().to_string(), "function %sample() -> i32 system_v { block0: v4 = iconst.i64 0 @@ -1119,7 +1109,7 @@ block0: } assert_eq!( - func.display(None).to_string(), + func.display().to_string(), "function %sample() -> i32 system_v { sig0 = (i64, i64, i64) system_v fn0 = %Memcpy sig0 @@ -1164,7 +1154,7 @@ block0: } assert_eq!( - func.display(None).to_string(), + func.display().to_string(), "function %sample() -> i32 system_v { block0: v2 = iconst.i64 0 @@ -1204,7 +1194,7 @@ block0: } assert_eq!( - func.display(None).to_string(), + func.display().to_string(), "function %sample() -> i32 system_v { sig0 = (i64, i32, i64) system_v fn0 = %Memset sig0 @@ -1253,7 +1243,7 @@ block0: } assert_eq!( - func.display(None).to_string(), + func.display().to_string(), "function %sample() -> i8x16, b8x16, f32x4 system_v { const0 = 0x00000000000000000000000000000000 diff --git a/cranelift/frontend/src/lib.rs b/cranelift/frontend/src/lib.rs index 40bd27bfbc..73928d6d79 100644 --- a/cranelift/frontend/src/lib.rs +++ b/cranelift/frontend/src/lib.rs @@ -156,7 +156,7 @@ //! //! let flags = settings::Flags::new(settings::builder()); //! let res = verify_function(&func, &flags); -//! println!("{}", func.display(None)); +//! println!("{}", func.display()); //! if let Err(errors) = res { //! panic!("{}", errors); //! } diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 93c6bf0a3f..4b3d7dd618 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -452,16 +452,11 @@ where Opcode::Fill => unimplemented!("Fill"), Opcode::FillNop => assign(arg(0)?), Opcode::DummySargT => unimplemented!("DummySargT"), - Opcode::Regmove => ControlFlow::Continue, - Opcode::CopySpecial => ControlFlow::Continue, - Opcode::CopyToSsa => assign(arg(0)?), Opcode::CopyNop => unimplemented!("CopyNop"), Opcode::AdjustSpDown => unimplemented!("AdjustSpDown"), Opcode::AdjustSpUpImm => unimplemented!("AdjustSpUpImm"), Opcode::AdjustSpDownImm => unimplemented!("AdjustSpDownImm"), Opcode::IfcmpSp => unimplemented!("IfcmpSp"), - Opcode::Regspill => unimplemented!("Regspill"), - Opcode::Regfill => unimplemented!("Regfill"), Opcode::Safepoint => unimplemented!("Safepoint"), Opcode::Icmp => assign(icmp( ctrl_ty, diff --git a/cranelift/jit/src/backend.rs b/cranelift/jit/src/backend.rs index e118d9a176..a9362a6069 100644 --- a/cranelift/jit/src/backend.rs +++ b/cranelift/jit/src/backend.rs @@ -634,7 +634,7 @@ impl Module for JITModule { trap_sink: &mut dyn TrapSink, stack_map_sink: &mut dyn StackMapSink, ) -> ModuleResult { - info!("defining function {}: {}", id, ctx.func.display(self.isa())); + info!("defining function {}: {}", id, ctx.func.display()); let CodeInfo { total_size: code_size, .. diff --git a/cranelift/jit/tests/basic.rs b/cranelift/jit/tests/basic.rs index 8fb1b0d73d..f53480702d 100644 --- a/cranelift/jit/tests/basic.rs +++ b/cranelift/jit/tests/basic.rs @@ -149,7 +149,7 @@ fn switch_error() { Ok(_) => {} Err(err) => { let pretty_error = - cranelift_codegen::print_errors::pretty_verifier_error(&func, None, None, err); + cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err); panic!("pretty_error:\n{}", pretty_error); } } diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 22fa807672..cdf29882ee 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -310,11 +310,7 @@ impl Module for ObjectModule { trap_sink: &mut dyn TrapSink, stack_map_sink: &mut dyn StackMapSink, ) -> ModuleResult { - info!( - "defining function {}: {}", - func_id, - ctx.func.display(self.isa()) - ); + info!("defining function {}: {}", func_id, ctx.func.display()); let CodeInfo { total_size: code_size, .. diff --git a/cranelift/object/tests/basic.rs b/cranelift/object/tests/basic.rs index 20fd4453ae..a5add02295 100644 --- a/cranelift/object/tests/basic.rs +++ b/cranelift/object/tests/basic.rs @@ -142,7 +142,7 @@ fn switch_error() { Ok(_) => {} Err(err) => { let pretty_error = - cranelift_codegen::print_errors::pretty_verifier_error(&func, None, None, err); + cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err); panic!("pretty_error:\n{}", pretty_error); } } diff --git a/cranelift/reader/src/parser.rs b/cranelift/reader/src/parser.rs index 3829bde59b..0f63a1c4fd 100644 --- a/cranelift/reader/src/parser.rs +++ b/cranelift/reader/src/parser.rs @@ -17,12 +17,12 @@ use cranelift_codegen::ir::instructions::{InstructionData, InstructionFormat, Va use cranelift_codegen::ir::types::INVALID; use cranelift_codegen::ir::types::*; use cranelift_codegen::ir::{ - AbiParam, ArgumentExtension, ArgumentLoc, ArgumentPurpose, Block, Constant, ConstantData, - ExtFuncData, ExternalName, FuncRef, Function, GlobalValue, GlobalValueData, Heap, HeapData, - HeapStyle, JumpTable, JumpTableData, MemFlags, Opcode, SigRef, Signature, StackSlot, - StackSlotData, StackSlotKind, Table, TableData, Type, Value, ValueLoc, + AbiParam, ArgumentExtension, ArgumentPurpose, Block, Constant, ConstantData, ExtFuncData, + ExternalName, FuncRef, Function, GlobalValue, GlobalValueData, Heap, HeapData, HeapStyle, + JumpTable, JumpTableData, MemFlags, Opcode, SigRef, Signature, StackSlot, StackSlotData, + StackSlotKind, Table, TableData, Type, Value, }; -use cranelift_codegen::isa::{self, CallConv, RegUnit, TargetIsa}; +use cranelift_codegen::isa::{self, CallConv}; use cranelift_codegen::packed_option::ReservedValue; use cranelift_codegen::{settings, settings::Configurable, timing}; use smallvec::SmallVec; @@ -154,7 +154,7 @@ pub fn parse_test<'a>(text: &'a str, options: ParseOptions<'a>) -> ParseResult { } /// Context for resolving references when parsing a single function. -struct Context<'a> { +struct Context { function: Function, map: SourceMap, /// Aliases to resolve once value definitions are known. aliases: Vec, - - /// Reference to the unique_isa for things like parsing target-specific instruction encoding - /// information. This is only `Some` if exactly one set of `isa` directives were found in the - /// prologue (it is valid to have directives for multiple different targets, but in that case - /// we couldn't know which target the provided encodings are intended for) - unique_isa: Option<&'a dyn TargetIsa>, } -impl<'a> Context<'a> { - fn new(f: Function, unique_isa: Option<&'a dyn TargetIsa>) -> Self { +impl Context { + fn new(f: Function) -> Self { Self { function: f, map: SourceMap::new(), - unique_isa, aliases: Vec::new(), } } @@ -948,27 +941,6 @@ impl<'a> Parser<'a> { } } - // Match and consume a register unit either by number `%15` or by name `%rax`. - fn match_regunit(&mut self, isa: Option<&dyn TargetIsa>) -> ParseResult { - if let Some(Token::Name(name)) = self.token() { - self.consume(); - match isa { - Some(isa) => isa - .register_info() - .parse_regunit(name) - .ok_or_else(|| self.error("invalid register name")), - None => name - .parse() - .map_err(|_| self.error("invalid register number")), - } - } else { - match isa { - Some(isa) => err!(self.loc, "Expected {} register unit", isa.name()), - None => err!(self.loc, "Expected register unit number"), - } - } - } - /// Parse an optional source location. /// /// Return an optional source location if no real location is present. @@ -1188,13 +1160,10 @@ impl<'a> Parser<'a> { /// Parse a list of function definitions. /// /// This is the top-level parse function matching the whole contents of a file. - pub fn parse_function_list( - &mut self, - unique_isa: Option<&dyn TargetIsa>, - ) -> ParseResult)>> { + pub fn parse_function_list(&mut self) -> ParseResult)>> { let mut list = Vec::new(); while self.token().is_some() { - list.push(self.parse_function(unique_isa)?); + list.push(self.parse_function()?); } if let Some(err) = self.lex_error { return match err { @@ -1208,10 +1177,7 @@ impl<'a> Parser<'a> { // // function ::= * "function" name signature "{" preamble function-body "}" // - fn parse_function( - &mut self, - unique_isa: Option<&dyn TargetIsa>, - ) -> ParseResult<(Function, Details<'a>)> { + fn parse_function(&mut self) -> ParseResult<(Function, Details<'a>)> { // Begin gathering comments. // Make sure we don't include any comments before the `function` keyword. self.token(); @@ -1226,9 +1192,9 @@ impl<'a> Parser<'a> { let name = self.parse_external_name()?; // function ::= "function" name * signature "{" preamble function-body "}" - let sig = self.parse_signature(unique_isa)?; + let sig = self.parse_signature()?; - let mut ctx = Context::new(Function::with_name_signature(name, sig), unique_isa); + let mut ctx = Context::new(Function::with_name_signature(name, sig)); // function ::= "function" name signature * "{" preamble function-body "}" self.match_token(Token::LBrace, "expected '{' before function body")?; @@ -1298,18 +1264,18 @@ impl<'a> Parser<'a> { // // signature ::= * "(" [paramlist] ")" ["->" retlist] [callconv] // - fn parse_signature(&mut self, unique_isa: Option<&dyn TargetIsa>) -> ParseResult { + fn parse_signature(&mut self) -> ParseResult { // Calling convention defaults to `fast`, but can be changed. let mut sig = Signature::new(self.default_calling_convention); self.match_token(Token::LPar, "expected function signature: ( args... )")?; // signature ::= "(" * [abi-param-list] ")" ["->" retlist] [callconv] if self.token() != Some(Token::RPar) { - sig.params = self.parse_abi_param_list(unique_isa)?; + sig.params = self.parse_abi_param_list()?; } self.match_token(Token::RPar, "expected ')' after function arguments")?; if self.optional(Token::Arrow) { - sig.returns = self.parse_abi_param_list(unique_isa)?; + sig.returns = self.parse_abi_param_list()?; } // The calling convention is optional. @@ -1330,26 +1296,23 @@ impl<'a> Parser<'a> { // // paramlist ::= * param { "," param } // - fn parse_abi_param_list( - &mut self, - unique_isa: Option<&dyn TargetIsa>, - ) -> ParseResult> { + fn parse_abi_param_list(&mut self) -> ParseResult> { let mut list = Vec::new(); // abi-param-list ::= * abi-param { "," abi-param } - list.push(self.parse_abi_param(unique_isa)?); + list.push(self.parse_abi_param()?); // abi-param-list ::= abi-param * { "," abi-param } while self.optional(Token::Comma) { // abi-param-list ::= abi-param { "," * abi-param } - list.push(self.parse_abi_param(unique_isa)?); + list.push(self.parse_abi_param()?); } Ok(list) } // Parse a single argument type with flags. - fn parse_abi_param(&mut self, unique_isa: Option<&dyn TargetIsa>) -> ParseResult { + fn parse_abi_param(&mut self) -> ParseResult { // abi-param ::= * type { flag } [ argumentloc ] let mut arg = AbiParam::new(self.match_type("expected parameter type")?); @@ -1377,53 +1340,9 @@ impl<'a> Parser<'a> { self.consume(); } - // abi-param ::= type { flag } * [ argumentloc ] - arg.location = self.parse_argument_location(unique_isa)?; - Ok(arg) } - // Parse an argument location specifier; either a register or a byte offset into the stack. - fn parse_argument_location( - &mut self, - unique_isa: Option<&dyn TargetIsa>, - ) -> ParseResult { - // argumentloc ::= '[' regname | uimm32 ']' - if self.optional(Token::LBracket) { - let result = match self.token() { - Some(Token::Name(name)) => { - self.consume(); - if let Some(isa) = unique_isa { - isa.register_info() - .parse_regunit(name) - .map(ArgumentLoc::Reg) - .ok_or_else(|| self.error("invalid register name")) - } else { - err!(self.loc, "argument location requires exactly one isa") - } - } - Some(Token::Integer(_)) => { - let offset = self.match_imm32("expected stack argument byte offset")?; - Ok(ArgumentLoc::Stack(offset)) - } - Some(Token::Minus) => { - self.consume(); - Ok(ArgumentLoc::Unassigned) - } - _ => err!(self.loc, "expected argument location"), - }; - - self.match_token( - Token::RBracket, - "expected ']' to end argument location annotation", - )?; - - result - } else { - Ok(ArgumentLoc::Unassigned) - } - } - // Parse the function preamble. // // preamble ::= * { preamble-decl } @@ -1460,10 +1379,9 @@ impl<'a> Parser<'a> { } Some(Token::SigRef(..)) => { self.start_gathering_comments(); - self.parse_signature_decl(ctx.unique_isa) - .and_then(|(sig, dat)| { - ctx.add_sig(sig, dat, self.loc, self.default_calling_convention) - }) + self.parse_signature_decl().and_then(|(sig, dat)| { + ctx.add_sig(sig, dat, self.loc, self.default_calling_convention) + }) } Some(Token::FuncRef(..)) => { self.start_gathering_comments(); @@ -1746,13 +1664,10 @@ impl<'a> Parser<'a> { // // signature-decl ::= SigRef(sigref) "=" signature // - fn parse_signature_decl( - &mut self, - unique_isa: Option<&dyn TargetIsa>, - ) -> ParseResult<(SigRef, Signature)> { + fn parse_signature_decl(&mut self) -> ParseResult<(SigRef, Signature)> { let sig = self.match_sig("expected signature number: sig«n»")?; self.match_token(Token::Equal, "expected '=' in signature decl")?; - let data = self.parse_signature(unique_isa)?; + let data = self.parse_signature()?; // Collect any trailing comments. self.token(); @@ -1787,7 +1702,7 @@ impl<'a> Parser<'a> { let data = match self.token() { Some(Token::LPar) => { // function-decl ::= FuncRef(fnref) "=" ["colocated"] name * signature - let sig = self.parse_signature(ctx.unique_isa)?; + let sig = self.parse_signature()?; let sigref = ctx.function.import_signature(sig); ctx.map .def_entity(sigref.into(), loc) @@ -1981,7 +1896,6 @@ impl<'a> Parser<'a> { _ => false, } { let srcloc = self.optional_srcloc()?; - let result_locations = self.parse_instruction_encoding(ctx)?; // We need to parse instruction results here because they are shared // between the parsing of value aliases and the parsing of instructions. @@ -2002,10 +1916,10 @@ impl<'a> Parser<'a> { } Some(Token::Equal) => { self.consume(); - self.parse_instruction(&results, srcloc, result_locations, ctx, block)?; + self.parse_instruction(&results, srcloc, ctx, block)?; } _ if !results.is_empty() => return err!(self.loc, "expected -> or ="), - _ => self.parse_instruction(&results, srcloc, result_locations, ctx, block)?, + _ => self.parse_instruction(&results, srcloc, ctx, block)?, } } @@ -2057,77 +1971,9 @@ impl<'a> Parser<'a> { ctx.function.dfg.append_block_param_for_parser(block, t, v); ctx.map.def_value(v, v_location)?; - // block-param ::= Value(v) ":" Type(t) * arg-loc? - if self.optional(Token::LBracket) { - let loc = self.parse_value_location(ctx)?; - ctx.function.locations[v] = loc; - self.match_token(Token::RBracket, "expected ']' after value location")?; - } - Ok(()) } - fn parse_value_location(&mut self, ctx: &Context) -> ParseResult { - match self.token() { - Some(Token::StackSlot(src_num)) => { - self.consume(); - let ss = match StackSlot::with_number(src_num) { - None => { - return err!( - self.loc, - "attempted to use invalid stack slot ss{}", - src_num - ); - } - Some(ss) => ss, - }; - ctx.check_ss(ss, self.loc)?; - Ok(ValueLoc::Stack(ss)) - } - Some(Token::Name(name)) => { - self.consume(); - if let Some(isa) = ctx.unique_isa { - isa.register_info() - .parse_regunit(name) - .map(ValueLoc::Reg) - .ok_or_else(|| self.error("invalid register value location")) - } else { - err!(self.loc, "value location requires exactly one isa") - } - } - Some(Token::Minus) => { - self.consume(); - Ok(ValueLoc::Unassigned) - } - _ => err!(self.loc, "invalid value location"), - } - } - - fn parse_instruction_encoding(&mut self, ctx: &Context) -> ParseResult>> { - let mut result_locations = None; - - // encoding ::= "[" encoding_literal result_locations "]" - if self.optional(Token::LBracket) { - // result_locations ::= ("," ( "-" | names ) )? - // names ::= Name { "," Name } - let mut results = Vec::new(); - - results.push(self.parse_value_location(ctx)?); - while self.optional(Token::Comma) { - results.push(self.parse_value_location(ctx)?); - } - - result_locations = Some(results); - - self.match_token( - Token::RBracket, - "expected ']' to terminate instruction encoding", - )?; - } - - Ok(result_locations) - } - // Parse instruction results and return them. // // inst-results ::= Value(v) { "," Value(v) } @@ -2202,7 +2048,6 @@ impl<'a> Parser<'a> { &mut self, results: &[Value], srcloc: ir::SourceLoc, - result_locations: Option>, ctx: &mut Context, block: Block, ) -> ParseResult<()> { @@ -2266,30 +2111,6 @@ impl<'a> Parser<'a> { ); } - if let Some(ref result_locations) = result_locations { - if results.len() != result_locations.len() { - return err!( - self.loc, - "instruction produces {} result values, but {} locations were \ - specified", - results.len(), - result_locations.len() - ); - } - } - - if let Some(result_locations) = result_locations { - for (&value, loc) in ctx - .function - .dfg - .inst_results(inst) - .iter() - .zip(result_locations) - { - ctx.function.locations[value] = loc; - } - } - // Collect any trailing comments. self.token(); self.claim_gathered_comments(inst); @@ -3104,60 +2925,6 @@ impl<'a> Parser<'a> { offset, } } - InstructionFormat::RegMove => { - let arg = self.match_value("expected SSA value operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let src = self.match_regunit(ctx.unique_isa)?; - self.match_token(Token::Arrow, "expected '->' between register units")?; - let dst = self.match_regunit(ctx.unique_isa)?; - InstructionData::RegMove { - opcode, - arg, - src, - dst, - } - } - InstructionFormat::CopySpecial => { - let src = self.match_regunit(ctx.unique_isa)?; - self.match_token(Token::Arrow, "expected '->' between register units")?; - let dst = self.match_regunit(ctx.unique_isa)?; - InstructionData::CopySpecial { opcode, src, dst } - } - InstructionFormat::CopyToSsa => InstructionData::CopyToSsa { - opcode, - src: self.match_regunit(ctx.unique_isa)?, - }, - InstructionFormat::RegSpill => { - let arg = self.match_value("expected SSA value operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let src = self.match_regunit(ctx.unique_isa)?; - self.match_token(Token::Arrow, "expected '->' before destination stack slot")?; - let dst = self.match_ss("expected stack slot number: ss«n»")?; - ctx.check_ss(dst, self.loc)?; - InstructionData::RegSpill { - opcode, - arg, - src, - dst, - } - } - InstructionFormat::RegFill => { - let arg = self.match_value("expected SSA value operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let src = self.match_ss("expected stack slot number: ss«n»")?; - ctx.check_ss(src, self.loc)?; - self.match_token( - Token::Arrow, - "expected '->' before destination register units", - )?; - let dst = self.match_regunit(ctx.unique_isa)?; - InstructionData::RegFill { - opcode, - arg, - src, - dst, - } - } InstructionFormat::Trap => { let code = self.match_enum("expected trap code")?; InstructionData::Trap { opcode, code } @@ -3258,7 +3025,7 @@ mod tests { #[test] fn argument_type() { let mut p = Parser::new("i32 sext"); - let arg = p.parse_abi_param(None).unwrap(); + let arg = p.parse_abi_param().unwrap(); assert_eq!(arg.value_type, types::I32); assert_eq!(arg.extension, ArgumentExtension::Sext); assert_eq!(arg.purpose, ArgumentPurpose::Normal); @@ -3266,7 +3033,7 @@ mod tests { location, message, is_warning, - } = p.parse_abi_param(None).unwrap_err(); + } = p.parse_abi_param().unwrap_err(); assert_eq!(location.line_number, 1); assert_eq!(message, "expected parameter type"); assert!(!is_warning); @@ -3282,7 +3049,7 @@ mod tests { v1 = iadd_imm v3, 17 }", ) - .parse_function(None) + .parse_function() .unwrap(); assert_eq!(func.name.to_string(), "%qux"); let v4 = details.map.lookup_str("v4").unwrap(); @@ -3300,13 +3067,13 @@ mod tests { #[test] fn signature() { - let sig = Parser::new("()system_v").parse_signature(None).unwrap(); + let sig = Parser::new("()system_v").parse_signature().unwrap(); assert_eq!(sig.params.len(), 0); assert_eq!(sig.returns.len(), 0); assert_eq!(sig.call_conv, CallConv::SystemV); let sig2 = Parser::new("(i8 uext, f32, f64, i32 sret) -> i32 sext, f64 baldrdash_system_v") - .parse_signature(None) + .parse_signature() .unwrap(); assert_eq!( sig2.to_string(), @@ -3316,12 +3083,12 @@ mod tests { // Old-style signature without a calling convention. assert_eq!( - Parser::new("()").parse_signature(None).unwrap().to_string(), + Parser::new("()").parse_signature().unwrap().to_string(), "() fast" ); assert_eq!( Parser::new("() notacc") - .parse_signature(None) + .parse_signature() .unwrap_err() .to_string(), "1: unknown calling convention: notacc" @@ -3330,21 +3097,21 @@ mod tests { // `void` is not recognized as a type by the lexer. It should not appear in files. assert_eq!( Parser::new("() -> void") - .parse_signature(None) + .parse_signature() .unwrap_err() .to_string(), "1: expected parameter type" ); assert_eq!( Parser::new("i8 -> i8") - .parse_signature(None) + .parse_signature() .unwrap_err() .to_string(), "1: expected function signature: ( args... )" ); assert_eq!( Parser::new("(i8 -> i8") - .parse_signature(None) + .parse_signature() .unwrap_err() .to_string(), "1: expected ')' after function arguments" @@ -3359,7 +3126,7 @@ mod tests { ss1 = spill_slot 1 }", ) - .parse_function(None) + .parse_function() .unwrap(); assert_eq!(func.name.to_string(), "%foo"); let mut iter = func.stack_slots.keys(); @@ -3383,7 +3150,7 @@ mod tests { ss1 = spill_slot 1 }", ) - .parse_function(None) + .parse_function() .unwrap_err() .to_string(), "3: duplicate entity: ss1" @@ -3398,7 +3165,7 @@ mod tests { block4(v3: i32): }", ) - .parse_function(None) + .parse_function() .unwrap(); assert_eq!(func.name.to_string(), "%blocks"); @@ -3425,7 +3192,7 @@ mod tests { block0: return 2", ) - .parse_function(None) + .parse_function() .unwrap_err(); assert_eq!(location.line_number, 3); @@ -3443,7 +3210,7 @@ mod tests { "function %a() { block100000:", ) - .parse_function(None) + .parse_function() .unwrap_err(); assert_eq!(location.line_number, 2); @@ -3462,7 +3229,7 @@ mod tests { jt0 = jump_table [] jt0 = jump_table []", ) - .parse_function(None) + .parse_function() .unwrap_err(); assert_eq!(location.line_number, 3); @@ -3481,7 +3248,7 @@ mod tests { ss0 = explicit_slot 8 ss0 = explicit_slot 8", ) - .parse_function(None) + .parse_function() .unwrap_err(); assert_eq!(location.line_number, 3); @@ -3500,7 +3267,7 @@ mod tests { gv0 = vmctx gv0 = vmctx", ) - .parse_function(None) + .parse_function() .unwrap_err(); assert_eq!(location.line_number, 3); @@ -3519,7 +3286,7 @@ mod tests { heap0 = static gv0, min 0x1000, bound 0x10_0000, offset_guard 0x1000 heap0 = static gv0, min 0x1000, bound 0x10_0000, offset_guard 0x1000", ) - .parse_function(None) + .parse_function() .unwrap_err(); assert_eq!(location.line_number, 3); @@ -3538,7 +3305,7 @@ mod tests { sig0 = () sig0 = ()", ) - .parse_function(None) + .parse_function() .unwrap_err(); assert_eq!(location.line_number, 3); @@ -3558,7 +3325,7 @@ mod tests { fn0 = %foo sig0 fn0 = %foo sig0", ) - .parse_function(None) + .parse_function() .unwrap_err(); assert_eq!(location.line_number, 4); @@ -3580,7 +3347,7 @@ mod tests { } ; Trailing. ; More trailing.", ) - .parse_function(None) + .parse_function() .unwrap(); assert_eq!(func.name.to_string(), "%comment"); assert_eq!(comments.len(), 8); // no 'before' comment. @@ -3682,7 +3449,7 @@ mod tests { trap int_divz }", ) - .parse_function(None) + .parse_function() .unwrap() .0; assert_eq!(func.name.to_string(), "u1:2"); @@ -3694,7 +3461,7 @@ mod tests { trap stk_ovf }", ); - assert!(parser.parse_function(None).is_err()); + assert!(parser.parse_function().is_err()); // Incomplete function names should not be valid: let mut parser = Parser::new( @@ -3703,7 +3470,7 @@ mod tests { trap int_ovf }", ); - assert!(parser.parse_function(None).is_err()); + assert!(parser.parse_function().is_err()); let mut parser = Parser::new( "function u0() system_v { @@ -3711,7 +3478,7 @@ mod tests { trap int_ovf }", ); - assert!(parser.parse_function(None).is_err()); + assert!(parser.parse_function().is_err()); let mut parser = Parser::new( "function u0:() system_v { @@ -3719,7 +3486,7 @@ mod tests { trap int_ovf }", ); - assert!(parser.parse_function(None).is_err()); + assert!(parser.parse_function().is_err()); } #[test] @@ -3732,14 +3499,14 @@ mod tests { // By default the parser will use the fast calling convention if none is specified. let mut parser = Parser::new(code); assert_eq!( - parser.parse_function(None).unwrap().0.signature.call_conv, + parser.parse_function().unwrap().0.signature.call_conv, CallConv::Fast ); // However, we can specify a different calling convention to be the default. let mut parser = Parser::new(code).with_default_calling_convention(CallConv::Cold); assert_eq!( - parser.parse_function(None).unwrap().0.signature.call_conv, + parser.parse_function().unwrap().0.signature.call_conv, CallConv::Cold ); } diff --git a/cranelift/src/bugpoint.rs b/cranelift/src/bugpoint.rs index 374a5d869b..e16e91ae40 100644 --- a/cranelift/src/bugpoint.rs +++ b/cranelift/src/bugpoint.rs @@ -570,18 +570,6 @@ impl Mutator for RemoveUnusedEntities { .push(inst); } - InstructionData::RegSpill { dst, .. } => { - stack_slot_usage_map - .entry(dst) - .or_insert_with(Vec::new) - .push(inst); - } - InstructionData::RegFill { src, .. } => { - stack_slot_usage_map - .entry(src) - .or_insert_with(Vec::new) - .push(inst); - } _ => {} } } @@ -599,12 +587,6 @@ impl Mutator for RemoveUnusedEntities { | InstructionData::StackStore { stack_slot, .. } => { *stack_slot = new_stack_slot; } - InstructionData::RegSpill { dst, .. } => { - *dst = new_stack_slot; - } - InstructionData::RegFill { src, .. } => { - *src = new_stack_slot; - } _ => unreachable!(), } } diff --git a/cranelift/src/compile.rs b/cranelift/src/compile.rs index e9138f181c..6a498a1b3a 100644 --- a/cranelift/src/compile.rs +++ b/cranelift/src/compile.rs @@ -80,12 +80,10 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) - // Compile and encode the result to machine code. let code_info = context .compile_and_emit(isa, &mut mem, &mut relocs, &mut traps, &mut stack_maps) - .map_err(|err| { - anyhow::anyhow!("{}", pretty_error(&context.func, Some(isa), err)) - })?; + .map_err(|err| anyhow::anyhow!("{}", pretty_error(&context.func, err)))?; if options.print { - println!("{}", context.func.display(isa)); + println!("{}", context.func.display()); } if options.disasm { diff --git a/cranelift/src/wasm.rs b/cranelift/src/wasm.rs index 18593d0c82..35ca9857b3 100644 --- a/cranelift/src/wasm.rs +++ b/cranelift/src/wasm.rs @@ -220,7 +220,7 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) - { println!("; Exported as \"{}\"", export_name); } - println!("{}", context.func.display(None)); + println!("{}", context.func.display()); vprintln!(options.verbose, ""); } let _ = terminal.reset(); @@ -263,15 +263,12 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) - let mut stack_maps = PrintStackMaps::new(options.print); if options.check_translation { if let Err(errors) = context.verify(fisa) { - anyhow::bail!( - "{}", - pretty_verifier_error(&context.func, fisa.isa, None, errors) - ); + anyhow::bail!("{}", pretty_verifier_error(&context.func, None, errors)); } } else { let code_info = context .compile_and_emit(isa, &mut mem, &mut relocs, &mut traps, &mut stack_maps) - .map_err(|err| anyhow::anyhow!("{}", pretty_error(&context.func, fisa.isa, err)))?; + .map_err(|err| anyhow::anyhow!("{}", pretty_error(&context.func, err)))?; if options.print_size { println!( @@ -321,7 +318,6 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) - println!( "{}", context.func.display_with(DisplayFunctionAnnotations { - isa: fisa.isa, value_ranges: value_ranges.as_ref(), }) ); diff --git a/cranelift/wasm/src/func_translator.rs b/cranelift/wasm/src/func_translator.rs index f69ac2e77b..2b28cb54a7 100644 --- a/cranelift/wasm/src/func_translator.rs +++ b/cranelift/wasm/src/func_translator.rs @@ -329,7 +329,7 @@ mod tests { trans .translate_body(&mut validator, body, &mut ctx.func, &mut runtime.func_env()) .unwrap(); - debug!("{}", ctx.func.display(None)); + debug!("{}", ctx.func.display()); ctx.verify(&flags).unwrap(); } @@ -368,7 +368,7 @@ mod tests { trans .translate_body(&mut validator, body, &mut ctx.func, &mut runtime.func_env()) .unwrap(); - debug!("{}", ctx.func.display(None)); + debug!("{}", ctx.func.display()); ctx.verify(&flags).unwrap(); } @@ -411,7 +411,7 @@ mod tests { trans .translate_body(&mut validator, body, &mut ctx.func, &mut runtime.func_env()) .unwrap(); - debug!("{}", ctx.func.display(None)); + debug!("{}", ctx.func.display()); ctx.verify(&flags).unwrap(); } diff --git a/cranelift/wasm/tests/wasm_testsuite.rs b/cranelift/wasm/tests/wasm_testsuite.rs index a5200c3d71..fa07a7ba2c 100644 --- a/cranelift/wasm/tests/wasm_testsuite.rs +++ b/cranelift/wasm/tests/wasm_testsuite.rs @@ -98,7 +98,7 @@ fn handle_module(data: Vec, flags: &Flags, return_mode: ReturnMode) { for func in dummy_environ.info.function_bodies.values() { verifier::verify_function(func, flags) - .map_err(|errors| panic!("{}", pretty_verifier_error(func, None, None, errors))) + .map_err(|errors| panic!("{}", pretty_verifier_error(func, None, errors))) .unwrap(); } } diff --git a/crates/cranelift/src/compiler.rs b/crates/cranelift/src/compiler.rs index ae0219ed60..65b17db357 100644 --- a/crates/cranelift/src/compiler.rs +++ b/crates/cranelift/src/compiler.rs @@ -172,13 +172,11 @@ impl wasmtime_environ::Compiler for Compiler { &mut trap_sink, &mut stack_map_sink, ) - .map_err(|error| { - CompileError::Codegen(pretty_error(&context.func, Some(isa), error)) - })?; + .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?; - let unwind_info = context.create_unwind_info(isa).map_err(|error| { - CompileError::Codegen(pretty_error(&context.func, Some(isa), error)) - })?; + let unwind_info = context + .create_unwind_info(isa) + .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?; let address_transform = self.get_function_address_map(&context, &input, code_buf.len() as u32); @@ -534,13 +532,11 @@ impl Compiler { &mut trap_sink, &mut stack_map_sink, ) - .map_err(|error| { - CompileError::Codegen(pretty_error(&context.func, Some(isa), error)) - })?; + .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?; - let unwind_info = context.create_unwind_info(isa).map_err(|error| { - CompileError::Codegen(pretty_error(&context.func, Some(isa), error)) - })?; + let unwind_info = context + .create_unwind_info(isa) + .map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?; Ok(CompiledFunction { body: code_buf,