diff --git a/cranelift/codegen/meta/src/gen_inst.rs b/cranelift/codegen/meta/src/gen_inst.rs index 1287a2c3ab..4fe1aee522 100644 --- a/cranelift/codegen/meta/src/gen_inst.rs +++ b/cranelift/codegen/meta/src/gen_inst.rs @@ -158,8 +158,8 @@ fn gen_arguments_method(formats: &[&InstructionFormat], fmt: &mut Formatter, is_ /// - `pub fn opcode(&self) -> Opcode` /// - `pub fn arguments(&self, &pool) -> &[Value]` /// - `pub fn arguments_mut(&mut self, &pool) -> &mut [Value]` -/// - `pub fn take_value_list(&mut self) -> Option` -/// - `pub fn put_value_list(&mut self, args: ir::ValueList>` +/// - `pub fn value_list(&self) -> Option` +/// - `pub fn value_list_mut(&mut self) -> Option<&mut ir::ValueList>` /// - `pub fn eq(&self, &other: Self, &pool) -> bool` /// - `pub fn hash(&self, state: &mut H, &pool)` fn gen_instruction_data_impl(formats: &[&InstructionFormat], fmt: &mut Formatter) { @@ -214,21 +214,17 @@ fn gen_instruction_data_impl(formats: &[&InstructionFormat], fmt: &mut Formatter fmt.empty_line(); fmt.doc_comment(r#" - Take out the value list with all the value arguments and return - it. - - This leaves the value list in the instruction empty. Use - `put_value_list` to put the value list back. + The ValueList for the instruction. "#); - fmt.line("pub fn take_value_list(&mut self) -> Option {"); + fmt.line("pub fn value_list(&self) -> Option {"); fmt.indent(|fmt| { let mut m = Match::new("*self"); for format in formats { if format.has_value_list { m.arm(format!("Self::{}", format.name), - vec!["ref mut args", ".."], - "Some(args.take())".to_string()); + vec!["args", ".."], + "Some(args)".to_string()); } } @@ -240,27 +236,24 @@ fn gen_instruction_data_impl(formats: &[&InstructionFormat], fmt: &mut Formatter fmt.empty_line(); fmt.doc_comment(r#" - Put back a value list. - - After removing a value list with `take_value_list()`, use this - method to put it back. It is required that this instruction has - a format that accepts a value list, and that the existing value - list is empty. This avoids leaking list pool memory. + A mutable reference to the ValueList for this instruction, if it + has one. "#); - fmt.line("pub fn put_value_list(&mut self, vlist: ir::ValueList) {"); + fmt.line("pub fn value_list_mut(&mut self) -> Option<&mut ir::ValueList> {"); fmt.indent(|fmt| { - fmt.line("let args = match *self {"); - fmt.indent(|fmt| { - for format in formats { - if format.has_value_list { - fmtln!(fmt, "Self::{} {{ ref mut args, .. }} => args,", format.name); - } + let mut m = Match::new("*self"); + + for format in formats { + if format.has_value_list { + m.arm(format!("Self::{}", format.name), + vec!["ref mut args", ".."], + "Some(args)".to_string()); } - fmt.line("_ => panic!(\"No value list: {:?}\", self),"); - }); - fmt.line("};"); - fmt.line("debug_assert!(args.is_empty(), \"Value list already in use\");"); - fmt.line("*args = vlist;"); + } + + m.arm_no_fields("_", "None"); + + fmt.add_match(m); }); fmt.line("}"); fmt.empty_line(); diff --git a/cranelift/codegen/src/alias_analysis.rs b/cranelift/codegen/src/alias_analysis.rs index f2c1e6e08e..f3b6339f99 100644 --- a/cranelift/codegen/src/alias_analysis.rs +++ b/cranelift/codegen/src/alias_analysis.rs @@ -85,14 +85,14 @@ pub struct LastStores { impl LastStores { fn update(&mut self, func: &Function, inst: Inst) { - let opcode = func.dfg[inst].opcode(); + let opcode = func.dfg.insts[inst].opcode(); if has_memory_fence_semantics(opcode) { self.heap = inst.into(); self.table = inst.into(); self.vmctx = inst.into(); self.other = inst.into(); } else if opcode.can_store() { - if let Some(memflags) = func.dfg[inst].memflags() { + if let Some(memflags) = func.dfg.insts[inst].memflags() { if memflags.heap() { self.heap = inst.into(); } else if memflags.table() { @@ -112,7 +112,7 @@ impl LastStores { } fn get_last_store(&self, func: &Function, inst: Inst) -> PackedOption { - if let Some(memflags) = func.dfg[inst].memflags() { + if let Some(memflags) = func.dfg.insts[inst].memflags() { if memflags.heap() { self.heap } else if memflags.table() { @@ -122,7 +122,9 @@ impl LastStores { } else { self.other } - } else if func.dfg[inst].opcode().can_load() || func.dfg[inst].opcode().can_store() { + } else if func.dfg.insts[inst].opcode().can_load() + || func.dfg.insts[inst].opcode().can_store() + { inst.into() } else { PackedOption::default() @@ -277,13 +279,13 @@ impl<'a> AliasAnalysis<'a> { "alias analysis: scanning at inst{} with state {:?} ({:?})", inst.index(), state, - func.dfg[inst], + func.dfg.insts[inst], ); let replacing_value = if let Some((address, offset, ty)) = inst_addr_offset_type(func, inst) { let address = func.dfg.resolve_aliases(address); - let opcode = func.dfg[inst].opcode(); + let opcode = func.dfg.insts[inst].opcode(); if opcode.can_store() { let store_data = inst_store_data(func, inst).unwrap(); diff --git a/cranelift/codegen/src/cursor.rs b/cranelift/codegen/src/cursor.rs index 0a6d74d21b..3de1b2166d 100644 --- a/cranelift/codegen/src/cursor.rs +++ b/cranelift/codegen/src/cursor.rs @@ -641,9 +641,9 @@ impl<'c, 'f> ir::InstInserterBase<'c> for &'c mut FuncCursor<'f> { if let CursorPosition::At(_) = self.position() { if let Some(curr) = self.current_inst() { if let Some(prev) = self.layout().prev_inst(curr) { - let prev_op = self.data_flow_graph()[prev].opcode(); - let inst_op = self.data_flow_graph()[inst].opcode(); - let curr_op = self.data_flow_graph()[curr].opcode(); + let prev_op = self.data_flow_graph().insts[prev].opcode(); + let inst_op = self.data_flow_graph().insts[inst].opcode(); + let curr_op = self.data_flow_graph().insts[curr].opcode(); if prev_op.is_branch() && !prev_op.is_terminator() && !inst_op.is_terminator() diff --git a/cranelift/codegen/src/egraph.rs b/cranelift/codegen/src/egraph.rs index 121155008b..f49e61dece 100644 --- a/cranelift/codegen/src/egraph.rs +++ b/cranelift/codegen/src/egraph.rs @@ -102,7 +102,7 @@ impl NewOrExistingInst { NewOrExistingInst::New(data, ty) => (*ty, *data), NewOrExistingInst::Existing(inst) => { let ty = dfg.ctrl_typevar(*inst); - (ty, dfg[*inst].clone()) + (ty, dfg.insts[*inst].clone()) } } } @@ -191,8 +191,11 @@ where union_find: self.eclasses, value_lists: &self.func.dfg.value_lists, }; - self.gvn_map - .insert((ty, self.func.dfg[inst].clone()), opt_value, &gvn_context); + self.gvn_map.insert( + (ty, self.func.dfg.insts[inst].clone()), + opt_value, + &gvn_context, + ); self.value_to_opt_value[result] = opt_value; opt_value } @@ -335,7 +338,7 @@ impl<'a> EgraphPass<'a> { trace!(" -> {} = {:?}", value, def); match def { ValueDef::Result(i, 0) => { - trace!(" -> {} = {:?}", i, self.func.dfg[i]); + trace!(" -> {} = {:?}", i, self.func.dfg.insts[i]); } _ => {} } diff --git a/cranelift/codegen/src/egraph/elaborate.rs b/cranelift/codegen/src/egraph/elaborate.rs index ed145ee706..735834d064 100644 --- a/cranelift/codegen/src/egraph/elaborate.rs +++ b/cranelift/codegen/src/egraph/elaborate.rs @@ -218,7 +218,7 @@ impl<'a> Elaborator<'a> { } ValueDef::Result(inst, _) => { trace!(" -> value {}: result, computing cost", value); - let inst_data = &self.func.dfg[inst]; + let inst_data = &self.func.dfg.insts[inst]; let loop_level = self .func .layout @@ -358,7 +358,7 @@ impl<'a> Elaborator<'a> { trace!( " -> result {} of inst {:?}", result_idx, - self.func.dfg[inst] + self.func.dfg.insts[inst] ); // We're going to need to use this instruction @@ -600,7 +600,7 @@ impl<'a> Elaborator<'a> { // elaboration for args of *any* branch must be inserted // before the *first* branch, because the branch group // must remain contiguous at the end of the block. - if self.func.dfg[inst].opcode().is_branch() && first_branch == None { + if self.func.dfg.insts[inst].opcode().is_branch() && first_branch == None { first_branch = Some(inst); } diff --git a/cranelift/codegen/src/inst_predicates.rs b/cranelift/codegen/src/inst_predicates.rs index b67f110137..368366360f 100644 --- a/cranelift/codegen/src/inst_predicates.rs +++ b/cranelift/codegen/src/inst_predicates.rs @@ -40,7 +40,7 @@ fn is_load_with_defined_trapping(opcode: Opcode, data: &InstructionData) -> bool /// its value is unused? #[inline(always)] pub fn has_side_effect(func: &Function, inst: Inst) -> bool { - let data = &func.dfg[inst]; + let data = &func.dfg.insts[inst]; let opcode = data.opcode(); trivially_has_side_effects(opcode) || is_load_with_defined_trapping(opcode, data) } @@ -51,7 +51,7 @@ pub fn has_side_effect(func: &Function, inst: Inst) -> bool { /// - Actual pure nodes (arithmetic, etc) /// - Loads with the `readonly` flag set pub fn is_pure_for_egraph(func: &Function, inst: Inst) -> bool { - let is_readonly_load = match func.dfg[inst] { + let is_readonly_load = match func.dfg.insts[inst] { InstructionData::Load { opcode: Opcode::Load, flags, @@ -69,7 +69,7 @@ pub fn is_pure_for_egraph(func: &Function, inst: Inst) -> bool { // are, we can always trivially eliminate them with no effect.) let has_one_result = func.dfg.inst_results(inst).len() == 1; - let op = func.dfg[inst].opcode(); + let op = func.dfg.insts[inst].opcode(); has_one_result && (is_readonly_load || (!op.can_load() && !trivially_has_side_effects(op))) } @@ -77,14 +77,14 @@ pub fn is_pure_for_egraph(func: &Function, inst: Inst) -> bool { /// Does the given instruction have any side-effect as per [has_side_effect], or else is a load, /// but not the get_pinned_reg opcode? pub fn has_lowering_side_effect(func: &Function, inst: Inst) -> bool { - let op = func.dfg[inst].opcode(); + let op = func.dfg.insts[inst].opcode(); op != Opcode::GetPinnedReg && (has_side_effect(func, inst) || op.can_load()) } /// Is the given instruction a constant value (`iconst`, `fconst`) that can be /// represented in 64 bits? pub fn is_constant_64bit(func: &Function, inst: Inst) -> Option { - let data = &func.dfg[inst]; + let data = &func.dfg.insts[inst]; if data.opcode() == Opcode::Null { return Some(0); } @@ -98,7 +98,7 @@ pub fn is_constant_64bit(func: &Function, inst: Inst) -> Option { /// Get the address, offset, and access type from the given instruction, if any. pub fn inst_addr_offset_type(func: &Function, inst: Inst) -> Option<(Value, Offset32, Type)> { - let data = &func.dfg[inst]; + let data = &func.dfg.insts[inst]; match data { InstructionData::Load { arg, offset, .. } => { let ty = func.dfg.value_type(func.dfg.inst_results(inst)[0]); @@ -122,7 +122,7 @@ pub fn inst_addr_offset_type(func: &Function, inst: Inst) -> Option<(Value, Offs /// Get the store data, if any, from an instruction. pub fn inst_store_data(func: &Function, inst: Inst) -> Option { - let data = &func.dfg[inst]; + let data = &func.dfg.insts[inst]; match data { InstructionData::Store { args, .. } | InstructionData::StoreNoOffset { args, .. } => { Some(args[0]) @@ -157,14 +157,14 @@ pub(crate) fn visit_block_succs( mut visit: F, ) { for inst in f.layout.block_likely_branches(block) { - if f.dfg[inst].opcode().is_branch() { + if f.dfg.insts[inst].opcode().is_branch() { visit_branch_targets(f, inst, &mut visit); } } } fn visit_branch_targets(f: &Function, inst: Inst, visit: &mut F) { - match f.dfg[inst].analyze_branch(&f.dfg.value_lists) { + match f.dfg.insts[inst].analyze_branch(&f.dfg.value_lists) { BranchInfo::NotABranch => {} BranchInfo::SingleDest(dest, _) => { visit(inst, dest, false); diff --git a/cranelift/codegen/src/ir/builder.rs b/cranelift/codegen/src/ir/builder.rs index b28bcd1e01..e4c434cbf3 100644 --- a/cranelift/codegen/src/ir/builder.rs +++ b/cranelift/codegen/src/ir/builder.rs @@ -201,7 +201,7 @@ impl<'f> InstBuilderBase<'f> for ReplaceBuilder<'f> { fn build(self, data: InstructionData, ctrl_typevar: Type) -> (Inst, &'f mut DataFlowGraph) { // Splat the new instruction on top of the old one. - self.dfg[self.inst] = data; + self.dfg.insts[self.inst] = data; if !self.dfg.has_results(self.inst) { // The old result values were either detached or non-existent. diff --git a/cranelift/codegen/src/ir/dfg.rs b/cranelift/codegen/src/ir/dfg.rs index b83ffbb7ea..e47a609aba 100644 --- a/cranelift/codegen/src/ir/dfg.rs +++ b/cranelift/codegen/src/ir/dfg.rs @@ -23,6 +23,27 @@ use alloc::collections::BTreeMap; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; +/// Storage for instructions within the DFG. +#[derive(Clone, PartialEq, Hash)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +pub struct Insts(PrimaryMap); + +/// Allow immutable access to instructions via indexing. +impl Index for Insts { + type Output = InstructionData; + + fn index(&self, inst: Inst) -> &InstructionData { + self.0.index(inst) + } +} + +/// Allow mutable access to instructions via indexing. +impl IndexMut for Insts { + fn index_mut(&mut self, inst: Inst) -> &mut InstructionData { + self.0.index_mut(inst) + } +} + /// A data flow graph defines all instructions and basic blocks in a function as well as /// the data flow dependencies between them. The DFG also tracks values which can be either /// instruction results or block parameters. @@ -36,7 +57,7 @@ pub struct DataFlowGraph { /// Data about all of the instructions in the function, including opcodes and operands. /// The instructions in this map are not in program order. That is tracked by `Layout`, along /// with the block containing each instruction. - insts: PrimaryMap, + pub insts: Insts, /// List of result values for each instruction. /// @@ -89,7 +110,7 @@ impl DataFlowGraph { /// Create a new empty `DataFlowGraph`. pub fn new() -> Self { Self { - insts: PrimaryMap::new(), + insts: Insts(PrimaryMap::new()), results: SecondaryMap::new(), blocks: PrimaryMap::new(), dynamic_types: DynamicTypes::new(), @@ -106,7 +127,7 @@ impl DataFlowGraph { /// Clear everything. pub fn clear(&mut self) { - self.insts.clear(); + self.insts.0.clear(); self.results.clear(); self.blocks.clear(); self.dynamic_types.clear(); @@ -125,12 +146,12 @@ impl DataFlowGraph { /// /// This is intended for use with `SecondaryMap::with_capacity`. pub fn num_insts(&self) -> usize { - self.insts.len() + self.insts.0.len() } /// Returns `true` if the given instruction reference is valid. pub fn inst_is_valid(&self, inst: Inst) -> bool { - self.insts.is_valid(inst) + self.insts.0.is_valid(inst) } /// Get the total number of basic blocks created in this function, whether they are @@ -619,7 +640,7 @@ impl DataFlowGraph { pub fn make_inst(&mut self, data: InstructionData) -> Inst { let n = self.num_insts() + 1; self.results.resize(n); - self.insts.push(data) + self.insts.0.push(data) } /// Declares a dynamic vector type @@ -656,7 +677,7 @@ impl DataFlowGraph { /// Get the fixed value arguments on `inst` as a slice. pub fn inst_fixed_args(&self, inst: Inst) -> &[Value] { - let num_fixed_args = self[inst] + let num_fixed_args = self.insts[inst] .opcode() .constraints() .num_fixed_value_arguments(); @@ -665,7 +686,7 @@ impl DataFlowGraph { /// Get the fixed value arguments on `inst` as a mutable slice. pub fn inst_fixed_args_mut(&mut self, inst: Inst) -> &mut [Value] { - let num_fixed_args = self[inst] + let num_fixed_args = self.insts[inst] .opcode() .constraints() .num_fixed_value_arguments(); @@ -674,7 +695,7 @@ impl DataFlowGraph { /// Get the variable value arguments on `inst` as a slice. pub fn inst_variable_args(&self, inst: Inst) -> &[Value] { - let num_fixed_args = self[inst] + let num_fixed_args = self.insts[inst] .opcode() .constraints() .num_fixed_value_arguments(); @@ -683,7 +704,7 @@ impl DataFlowGraph { /// Get the variable value arguments on `inst` as a mutable slice. pub fn inst_variable_args_mut(&mut self, inst: Inst) -> &mut [Value] { - let num_fixed_args = self[inst] + let num_fixed_args = self.insts[inst] .opcode() .constraints() .num_fixed_value_arguments(); @@ -849,18 +870,17 @@ impl DataFlowGraph { /// /// Panics if the instruction doesn't support arguments. pub fn append_inst_arg(&mut self, inst: Inst, new_arg: Value) { - let mut branch_values = self.insts[inst] - .take_value_list() - .expect("the instruction doesn't have value arguments"); - branch_values.push(new_arg, &mut self.value_lists); - self.insts[inst].put_value_list(branch_values) + self.insts[inst] + .value_list_mut() + .expect("the instruction doesn't have value arguments") + .push(new_arg, &mut self.value_lists); } /// Clone an instruction, attaching new result `Value`s and /// returning them. pub fn clone_inst(&mut self, inst: Inst) -> Inst { // First, add a clone of the InstructionData. - let inst_data = self[inst].clone(); + let inst_data = self.insts[inst].clone(); let new_inst = self.make_inst(inst_data); // Get the controlling type variable. let ctrl_typevar = self.ctrl_typevar(inst); @@ -947,7 +967,7 @@ impl DataFlowGraph { /// Get the controlling type variable, or `INVALID` if `inst` isn't polymorphic. pub fn ctrl_typevar(&self, inst: Inst) -> Type { - let constraints = self[inst].opcode().constraints(); + let constraints = self.insts[inst].opcode().constraints(); if !constraints.is_polymorphic() { types::INVALID @@ -955,12 +975,12 @@ impl DataFlowGraph { // Not all instruction formats have a designated operand, but in that case // `requires_typevar_operand()` should never be true. self.value_type( - self[inst] + self.insts[inst] .typevar_operand(&self.value_lists) .unwrap_or_else(|| { panic!( "Instruction format for {:?} doesn't have a designated operand", - self[inst] + self.insts[inst] ) }), ) @@ -970,22 +990,6 @@ impl DataFlowGraph { } } -/// Allow immutable access to instructions via indexing. -impl Index for DataFlowGraph { - type Output = InstructionData; - - fn index(&self, inst: Inst) -> &InstructionData { - &self.insts[inst] - } -} - -/// Allow mutable access to instructions via indexing. -impl IndexMut for DataFlowGraph { - fn index_mut(&mut self, inst: Inst) -> &mut InstructionData { - &mut self.insts[inst] - } -} - /// basic blocks. impl DataFlowGraph { /// Create a new basic block. @@ -1187,9 +1191,9 @@ impl<'a> fmt::Display for DisplayInst<'a> { let typevar = dfg.ctrl_typevar(inst); if typevar.is_invalid() { - write!(f, "{}", dfg[inst].opcode())?; + write!(f, "{}", dfg.insts[inst].opcode())?; } else { - write!(f, "{}.{}", dfg[inst].opcode(), typevar)?; + write!(f, "{}.{}", dfg.insts[inst].opcode(), typevar)?; } write_operands(f, dfg, inst) } @@ -1376,7 +1380,7 @@ mod tests { // Immutable reference resolution. { let immdfg = &dfg; - let ins = &immdfg[inst]; + let ins = &immdfg.insts[inst]; assert_eq!(ins.opcode(), Opcode::Iconst); } diff --git a/cranelift/codegen/src/ir/function.rs b/cranelift/codegen/src/ir/function.rs index 39a0ab4dd7..f1b1917104 100644 --- a/cranelift/codegen/src/ir/function.rs +++ b/cranelift/codegen/src/ir/function.rs @@ -282,7 +282,7 @@ impl FunctionStencil { /// /// Note that this method ignores multi-destination branches like `br_table`. pub fn change_branch_destination(&mut self, inst: Inst, new_dest: Block) { - match self.dfg[inst].branch_destination_mut() { + match self.dfg.insts[inst].branch_destination_mut() { None => (), Some(inst_dest) => *inst_dest = new_dest, } @@ -309,7 +309,7 @@ impl FunctionStencil { }); if default_dest == Some(old_dest) { - match &mut self.dfg[inst] { + match &mut self.dfg.insts[inst] { InstructionData::BranchTable { destination, .. } => { *destination = new_dest; } @@ -333,13 +333,13 @@ impl FunctionStencil { let inst_iter = self.layout.block_insts(block); // Ignore all instructions prior to the first branch. - let mut inst_iter = inst_iter.skip_while(|&inst| !dfg[inst].opcode().is_branch()); + let mut inst_iter = inst_iter.skip_while(|&inst| !dfg.insts[inst].opcode().is_branch()); // A conditional branch is permitted in a basic block only when followed // by a terminal jump instruction. if let Some(_branch) = inst_iter.next() { if let Some(next) = inst_iter.next() { - match dfg[next].opcode() { + match dfg.insts[next].opcode() { Opcode::Jump => (), _ => return Err((next, "post-branch instruction not jump")), } @@ -377,7 +377,7 @@ impl FunctionStencil { .zip(self.dfg.inst_results(src)) .all(|(a, b)| self.dfg.value_type(*a) == self.dfg.value_type(*b))); - self.dfg[dst] = self.dfg[src]; + self.dfg.insts[dst] = self.dfg.insts[src]; self.layout.remove_inst(src); } diff --git a/cranelift/codegen/src/ir/layout.rs b/cranelift/codegen/src/ir/layout.rs index 7162c848c5..866e3ff8a5 100644 --- a/cranelift/codegen/src/ir/layout.rs +++ b/cranelift/codegen/src/ir/layout.rs @@ -600,7 +600,7 @@ impl Layout { // If two, the former is conditional and the latter is unconditional. let last = self.last_inst(block)?; if let Some(prev) = self.prev_inst(last) { - if dfg[prev].opcode().is_branch() { + if dfg.insts[prev].opcode().is_branch() { return Some(prev); } } diff --git a/cranelift/codegen/src/legalizer/mod.rs b/cranelift/codegen/src/legalizer/mod.rs index 0716b440d9..66241cde52 100644 --- a/cranelift/codegen/src/legalizer/mod.rs +++ b/cranelift/codegen/src/legalizer/mod.rs @@ -53,7 +53,7 @@ pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: while let Some(_block) = pos.next_block() { let mut prev_pos = pos.position(); while let Some(inst) = pos.next_inst() { - match pos.func.dfg[inst] { + match pos.func.dfg.insts[inst] { // control flow InstructionData::CondTrap { opcode: diff --git a/cranelift/codegen/src/licm.rs b/cranelift/codegen/src/licm.rs index 6b4d65f3ef..04551918e5 100644 --- a/cranelift/codegen/src/licm.rs +++ b/cranelift/codegen/src/licm.rs @@ -153,11 +153,11 @@ fn is_unsafe_load(inst_data: &InstructionData) -> bool { /// Test whether the given instruction is loop-invariant. fn is_loop_invariant(inst: Inst, dfg: &DataFlowGraph, loop_values: &FxHashSet) -> bool { - if trivially_unsafe_for_licm(dfg[inst].opcode()) { + if trivially_unsafe_for_licm(dfg.insts[inst].opcode()) { return false; } - if is_unsafe_load(&dfg[inst]) { + if is_unsafe_load(&dfg.insts[inst]) { return false; } diff --git a/cranelift/codegen/src/machinst/blockorder.rs b/cranelift/codegen/src/machinst/blockorder.rs index 847cbf53f2..fc8a1d67e3 100644 --- a/cranelift/codegen/src/machinst/blockorder.rs +++ b/cranelift/codegen/src/machinst/blockorder.rs @@ -251,7 +251,7 @@ impl BlockLoweringOrder { block_succ_range[block] = (block_succ_start, block_succ_end); for inst in f.layout.block_likely_branches(block) { - if f.dfg[inst].opcode() == Opcode::Return { + if f.dfg.insts[inst].opcode() == Opcode::Return { // Implicit output edge for any return. block_out_count[block] += 1; } @@ -279,7 +279,7 @@ impl BlockLoweringOrder { for inst in f.layout.block_likely_branches(block) { // If the block has a branch with any "fixed args" // (not blockparam args) ... - if f.dfg[inst].opcode().is_branch() && f.dfg.inst_fixed_args(inst).len() > 0 { + if f.dfg.insts[inst].opcode().is_branch() && f.dfg.inst_fixed_args(inst).len() > 0 { // ... then force a minimum successor count of // two, so the below algorithm cannot put // edge-moves on the end of the block. diff --git a/cranelift/codegen/src/machinst/isle.rs b/cranelift/codegen/src/machinst/isle.rs index cd45bdbe85..57e3f18de0 100644 --- a/cranelift/codegen/src/machinst/isle.rs +++ b/cranelift/codegen/src/machinst/isle.rs @@ -221,7 +221,7 @@ macro_rules! isle_lower_prelude_methods { #[inline] fn inst_data(&mut self, inst: Inst) -> InstructionData { - self.lower_ctx.dfg()[inst] + self.lower_ctx.dfg().insts[inst] } #[inline] diff --git a/cranelift/codegen/src/machinst/lower.rs b/cranelift/codegen/src/machinst/lower.rs index 6f6b68b921..3ef581c0bc 100644 --- a/cranelift/codegen/src/machinst/lower.rs +++ b/cranelift/codegen/src/machinst/lower.rs @@ -368,7 +368,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> { "bb {} inst {} ({:?}): result {} regs {:?}", bb, inst, - f.dfg[inst], + f.dfg.insts[inst], result, regs, ); @@ -705,7 +705,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> { // then reverse these and append to the VCode at the end of // each IR instruction. for inst in self.f.layout.block_insts(block).rev() { - let data = &self.f.dfg[inst]; + let data = &self.f.dfg.insts[inst]; let has_side_effect = has_lowering_side_effect(self.f, inst); // If inst has been sunk to another location, skip it. if self.is_inst_sunk(inst) { @@ -736,14 +736,14 @@ impl<'func, I: VCodeInst> Lower<'func, I> { // Skip lowering branches; these are handled separately // (see `lower_clif_branches()` below). - if self.f.dfg[inst].opcode().is_branch() { + if self.f.dfg.insts[inst].opcode().is_branch() { continue; } // Normal instruction: codegen if the instruction is side-effecting // or any of its outputs its used. if has_side_effect || value_needed { - trace!("lowering: inst {}: {:?}", inst, self.f.dfg[inst]); + trace!("lowering: inst {}: {:?}", inst, self.f.dfg.insts[inst]); let temp_regs = backend.lower(self, inst).unwrap_or_else(|| { let ty = if self.num_outputs(inst) > 0 { Some(self.output_ty(inst, 0)) @@ -975,7 +975,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> { if last_inst != Some(inst) { branches.push(inst); } else { - debug_assert!(self.f.dfg[inst].opcode() == Opcode::BrTable); + debug_assert!(self.f.dfg.insts[inst].opcode() == Opcode::BrTable); debug_assert!(branches.len() == 1); } last_inst = Some(inst); @@ -1104,7 +1104,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> { impl<'func, I: VCodeInst> Lower<'func, I> { /// Get the instdata for a given IR instruction. pub fn data(&self, ir_inst: Inst) -> &InstructionData { - &self.f.dfg[ir_inst] + &self.f.dfg.insts[ir_inst] } /// Likewise, but starting with a GlobalValue identifier. @@ -1129,7 +1129,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> { /// Returns the memory flags of a given memory access. pub fn memflags(&self, ir_inst: Inst) -> Option { - match &self.f.dfg[ir_inst] { + match &self.f.dfg.insts[ir_inst] { &InstructionData::AtomicCas { flags, .. } => Some(flags), &InstructionData::AtomicRmw { flags, .. } => Some(flags), &InstructionData::Load { flags, .. } diff --git a/cranelift/codegen/src/nan_canonicalization.rs b/cranelift/codegen/src/nan_canonicalization.rs index 2bcf3a1f1f..40600fc6fb 100644 --- a/cranelift/codegen/src/nan_canonicalization.rs +++ b/cranelift/codegen/src/nan_canonicalization.rs @@ -30,7 +30,7 @@ pub fn do_nan_canonicalization(func: &mut Function) { /// arithmetic operation. This ignores operations like `fneg`, `fabs`, or /// `fcopysign` that only operate on the sign bit of a floating point value. fn is_fp_arith(pos: &mut FuncCursor, inst: Inst) -> bool { - match pos.func.dfg[inst] { + match pos.func.dfg.insts[inst] { InstructionData::Unary { opcode, .. } => { opcode == Opcode::Ceil || opcode == Opcode::Floor diff --git a/cranelift/codegen/src/opts.rs b/cranelift/codegen/src/opts.rs index 62146c7854..41f5fb884c 100644 --- a/cranelift/codegen/src/opts.rs +++ b/cranelift/codegen/src/opts.rs @@ -76,7 +76,7 @@ where ValueDef::Result(inst, _) if ctx.ctx.func.dfg.inst_results(inst).len() == 1 => { let ty = ctx.ctx.func.dfg.value_type(value); trace!(" -> value of type {}", ty); - return Some((ty, ctx.ctx.func.dfg[inst].clone())); + return Some((ty, ctx.ctx.func.dfg.insts[inst].clone())); } _ => {} } diff --git a/cranelift/codegen/src/remove_constant_phis.rs b/cranelift/codegen/src/remove_constant_phis.rs index a6a8b073ff..5f31947386 100644 --- a/cranelift/codegen/src/remove_constant_phis.rs +++ b/cranelift/codegen/src/remove_constant_phis.rs @@ -232,7 +232,7 @@ pub fn do_remove_constant_phis(func: &mut Function, domtree: &mut DominatorTree) let mut summary = BlockSummary::new(&bump, formals); for inst in func.layout.block_insts(b) { - let idetails = &func.dfg[inst]; + let idetails = &func.dfg.insts[inst]; // Note that multi-dest transfers (i.e., branch tables) don't // carry parameters in our IR, so we only have to care about // `SingleDest` here. @@ -378,9 +378,9 @@ pub fn do_remove_constant_phis(func: &mut Function, domtree: &mut DominatorTree) continue; } - let old_actuals = func.dfg[edge.inst].take_value_list().unwrap(); + let old_actuals = func.dfg.insts[edge.inst].value_list().unwrap(); let num_old_actuals = old_actuals.len(&func.dfg.value_lists); - let num_fixed_actuals = func.dfg[edge.inst] + let num_fixed_actuals = func.dfg.insts[edge.inst] .opcode() .constraints() .num_fixed_value_arguments(); @@ -412,7 +412,7 @@ pub fn do_remove_constant_phis(func: &mut Function, domtree: &mut DominatorTree) new_actuals.push(actual_i, &mut func.dfg.value_lists); } } - func.dfg[edge.inst].put_value_list(new_actuals); + *func.dfg.insts[edge.inst].value_list_mut().unwrap() = new_actuals; } } diff --git a/cranelift/codegen/src/simple_gvn.rs b/cranelift/codegen/src/simple_gvn.rs index 0606297e3b..c821251133 100644 --- a/cranelift/codegen/src/simple_gvn.rs +++ b/cranelift/codegen/src/simple_gvn.rs @@ -96,7 +96,7 @@ pub fn do_simple_gvn(func: &mut Function, domtree: &mut DominatorTree) { let func = Ref::map(pos.borrow(), |pos| &pos.func); - let opcode = func.dfg[inst].opcode(); + let opcode = func.dfg.insts[inst].opcode(); if opcode.is_branch() && !opcode.is_terminator() { scope_stack.push(func.layout.next_inst(inst).unwrap()); @@ -108,13 +108,13 @@ pub fn do_simple_gvn(func: &mut Function, domtree: &mut DominatorTree) { } // These are split up to separate concerns. - if is_load_and_not_readonly(&func.dfg[inst]) { + if is_load_and_not_readonly(&func.dfg.insts[inst]) { continue; } let ctrl_typevar = func.dfg.ctrl_typevar(inst); let key = HashKey { - inst: func.dfg[inst], + inst: func.dfg.insts[inst], ty: ctrl_typevar, pos: &pos, }; diff --git a/cranelift/codegen/src/simple_preopt.rs b/cranelift/codegen/src/simple_preopt.rs index 2c51aee330..bfe8ccbdc8 100644 --- a/cranelift/codegen/src/simple_preopt.rs +++ b/cranelift/codegen/src/simple_preopt.rs @@ -142,7 +142,7 @@ fn package_up_divrem_info( /// Examine `inst` to see if it is a div or rem by a constant, and if so return the operands, /// signedness, operation size and div-vs-rem-ness in a handy bundle. fn get_div_info(inst: Inst, dfg: &DataFlowGraph) -> Option { - if let InstructionData::BinaryImm64 { opcode, arg, imm } = dfg[inst] { + if let InstructionData::BinaryImm64 { opcode, arg, imm } = dfg.insts[inst] { let (is_signed, is_rem) = match opcode { Opcode::UdivImm => (false, false), Opcode::UremImm => (false, true), @@ -478,7 +478,7 @@ enum BranchOrderKind { /// layout-wise. The unconditional jump can then become a fallthrough. fn branch_order(pos: &mut FuncCursor, cfg: &mut ControlFlowGraph, block: Block, inst: Inst) { let (term_inst, term_inst_args, term_dest, cond_inst, cond_inst_args, cond_dest, kind) = - match pos.func.dfg[inst] { + match pos.func.dfg.insts[inst] { InstructionData::Jump { opcode: Opcode::Jump, destination, @@ -500,7 +500,7 @@ fn branch_order(pos: &mut FuncCursor, cfg: &mut ControlFlowGraph, block: Block, return; }; - let prev_inst_data = &pos.func.dfg[prev_inst]; + let prev_inst_data = &pos.func.dfg.insts[prev_inst]; if let Some(prev_dest) = prev_inst_data.branch_destination() { if prev_dest != next_block { @@ -609,7 +609,7 @@ mod simplify { if let InstructionData::UnaryImm { opcode: Opcode::Iconst, imm, - } = dfg[candidate_inst] + } = dfg.insts[candidate_inst] { return Some(imm); } @@ -631,7 +631,7 @@ mod simplify { opcode: Opcode::IshlImm, arg: prev_arg, imm: prev_imm, - } = &pos.func.dfg[arg_inst] + } = &pos.func.dfg.insts[arg_inst] { if imm != *prev_imm { return false; @@ -677,7 +677,7 @@ mod simplify { /// would likely be expanded back into an instruction on smaller types with the same initial /// opcode, creating unnecessary churn. fn simplify(pos: &mut FuncCursor, inst: Inst, native_word_width: u32) { - match pos.func.dfg[inst] { + match pos.func.dfg.insts[inst] { InstructionData::Binary { opcode, args } => { if let Some(mut imm) = resolve_imm64_value(&pos.func.dfg, args[1]) { let new_opcode = match opcode { @@ -748,7 +748,7 @@ mod simplify { opcode: prev_opcode, arg: prev_arg, imm: prev_imm, - } = &pos.func.dfg[arg_inst] + } = &pos.func.dfg.insts[arg_inst] { if opcode == *prev_opcode && ty == pos.func.dfg.ctrl_typevar(arg_inst) @@ -846,7 +846,7 @@ mod simplify { opcode: br_opcode, args: ref br_args, .. - } = pos.func.dfg[inst] + } = pos.func.dfg.insts[inst] { let first_arg = { let args = pos.func.dfg.inst_args(inst); @@ -865,7 +865,7 @@ mod simplify { arg: cmp_arg, cond: cmp_cond, imm: cmp_imm, - } = pos.func.dfg[icmp_inst] + } = pos.func.dfg.insts[icmp_inst] { let cmp_imm: i64 = cmp_imm.into(); if cmp_imm != 0 { @@ -900,7 +900,7 @@ mod simplify { }; info.args.as_mut_slice(&mut pos.func.dfg.value_lists)[0] = info.cmp_arg; - if let InstructionData::Branch { ref mut opcode, .. } = pos.func.dfg[info.br_inst] { + if let InstructionData::Branch { ref mut opcode, .. } = pos.func.dfg.insts[info.br_inst] { *opcode = info.new_opcode; } else { panic!(); diff --git a/cranelift/codegen/src/souper_harvest.rs b/cranelift/codegen/src/souper_harvest.rs index b036ebcea2..d24b58b997 100644 --- a/cranelift/codegen/src/souper_harvest.rs +++ b/cranelift/codegen/src/souper_harvest.rs @@ -93,7 +93,7 @@ fn harvest_candidate_lhs( // Should we keep tracing through the given `val`? Only if it is defined // by an instruction that we can translate to Souper IR. let should_trace = |val| match func.dfg.value_def(val) { - ir::ValueDef::Result(inst, 0) => match func.dfg[inst].opcode() { + ir::ValueDef::Result(inst, 0) => match func.dfg.insts[inst].opcode() { ir::Opcode::Iadd | ir::Opcode::IaddImm | ir::Opcode::IrsubImm @@ -157,7 +157,7 @@ fn harvest_candidate_lhs( // `iconst`s into souper operands here, // when they are actually used. match func.dfg.value_def(arg) { - ir::ValueDef::Result(inst, 0) => match func.dfg[inst] { + ir::ValueDef::Result(inst, 0) => match func.dfg.insts[inst] { ir::InstructionData::UnaryImm { opcode, imm } => { debug_assert_eq!(opcode, ir::Opcode::Iconst); let imm: i64 = imm.into(); @@ -179,7 +179,7 @@ fn harvest_candidate_lhs( } }; - match (func.dfg[inst].opcode(), &func.dfg[inst]) { + match (func.dfg.insts[inst].opcode(), &func.dfg.insts[inst]) { (ir::Opcode::Iadd, _) => { let a = arg(allocs, 0); let b = arg(allocs, 1); diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index 7382ea31e7..1048248a28 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -470,7 +470,7 @@ impl<'a> Verifier<'a> { inst: Inst, errors: &mut VerifierErrors, ) -> VerifierStepResult<()> { - let is_terminator = self.func.dfg[inst].opcode().is_terminator(); + let is_terminator = self.func.dfg.insts[inst].opcode().is_terminator(); let is_last_inst = self.func.layout.last_inst(block) == Some(inst); if is_terminator && !is_last_inst { @@ -520,7 +520,7 @@ impl<'a> Verifier<'a> { inst: Inst, errors: &mut VerifierErrors, ) -> VerifierStepResult<()> { - let inst_data = &self.func.dfg[inst]; + let inst_data = &self.func.dfg.insts[inst]; let dfg = &self.func.dfg; // The instruction format matches the opcode @@ -580,7 +580,7 @@ impl<'a> Verifier<'a> { self.verify_inst_result(inst, res, errors)?; } - match self.func.dfg[inst] { + match self.func.dfg.insts[inst] { MultiAry { ref args, .. } => { self.verify_value_list(inst, args, errors)?; } @@ -1181,7 +1181,7 @@ impl<'a> Verifier<'a> { } fn typecheck(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult<()> { - let inst_data = &self.func.dfg[inst]; + let inst_data = &self.func.dfg.insts[inst]; let constraints = inst_data.opcode().constraints(); let ctrl_type = if let Some(value_typeset) = constraints.ctrl_typeset() { @@ -1261,7 +1261,7 @@ impl<'a> Verifier<'a> { ctrl_type: Type, errors: &mut VerifierErrors, ) -> VerifierStepResult<()> { - let constraints = self.func.dfg[inst].opcode().constraints(); + let constraints = self.func.dfg.insts[inst].opcode().constraints(); for (i, &arg) in self.func.dfg.inst_fixed_args(inst).iter().enumerate() { let arg_type = self.func.dfg.value_type(arg); @@ -1341,7 +1341,7 @@ impl<'a> Verifier<'a> { BranchInfo::NotABranch => {} } - match self.func.dfg[inst].analyze_call(&self.func.dfg.value_lists) { + match self.func.dfg.insts[inst].analyze_call(&self.func.dfg.value_lists) { CallInfo::Direct(func_ref, _) => { let sig_ref = self.func.dfg.ext_funcs[func_ref].signature; let arg_types = self.func.dfg.signatures[sig_ref] @@ -1407,7 +1407,7 @@ impl<'a> Verifier<'a> { } fn typecheck_return(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult<()> { - if self.func.dfg[inst].opcode().is_return() { + if self.func.dfg.insts[inst].opcode().is_return() { let args = self.func.dfg.inst_variable_args(inst); let expected_types = &self.func.signature.returns; if args.len() != expected_types.len() { @@ -1442,7 +1442,7 @@ impl<'a> Verifier<'a> { ctrl_type: Type, errors: &mut VerifierErrors, ) -> VerifierStepResult<()> { - match self.func.dfg[inst] { + match self.func.dfg.insts[inst] { ir::InstructionData::Unary { opcode, arg } => { let arg_type = self.func.dfg.value_type(arg); match opcode { @@ -1604,7 +1604,7 @@ impl<'a> Verifier<'a> { inst: Inst, errors: &mut VerifierErrors, ) -> VerifierStepResult<()> { - let inst_data = &self.func.dfg[inst]; + let inst_data = &self.func.dfg.insts[inst]; match *inst_data { ir::InstructionData::Store { flags, .. } => { diff --git a/cranelift/codegen/src/write.rs b/cranelift/codegen/src/write.rs index 8e80edc68d..3b1e8a6f1c 100644 --- a/cranelift/codegen/src/write.rs +++ b/cranelift/codegen/src/write.rs @@ -276,7 +276,7 @@ fn decorate_block( // if it can't be trivially inferred. // fn type_suffix(func: &Function, inst: Inst) -> Option { - let inst_data = &func.dfg[inst]; + let inst_data = &func.dfg.insts[inst]; let constraints = inst_data.opcode().constraints(); if !constraints.is_polymorphic() { @@ -357,7 +357,7 @@ fn write_instruction( } // Then the opcode, possibly with a '.type' suffix. - let opcode = func.dfg[inst].opcode(); + let opcode = func.dfg.insts[inst].opcode(); match type_suffix(func, inst) { Some(suf) => write!(w, "{}.{}", opcode, suf)?, @@ -378,7 +378,7 @@ fn write_instruction( 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] { + match dfg.insts[inst] { AtomicRmw { op, args, .. } => write!(w, " {} {}, {}", op, args[0], args[1]), AtomicCas { args, .. } => write!(w, " {}, {}, {}", args[0], args[1], args[2]), LoadNoOffset { flags, arg, .. } => write!(w, "{} {}", flags, arg), @@ -487,7 +487,7 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt let mut sep = " ; "; for &arg in dfg.inst_args(inst) { if let ValueDef::Result(src, _) = dfg.value_def(arg) { - let imm = match dfg[src] { + let imm = match dfg.insts[src] { UnaryImm { imm, .. } => imm.to_string(), UnaryIeee32 { imm, .. } => imm.to_string(), UnaryIeee64 { imm, .. } => imm.to_string(), diff --git a/cranelift/frontend/src/frontend.rs b/cranelift/frontend/src/frontend.rs index 2de8609577..0a2a191d72 100644 --- a/cranelift/frontend/src/frontend.rs +++ b/cranelift/frontend/src/frontend.rs @@ -676,7 +676,7 @@ impl<'a> FunctionBuilder<'a> { /// **Note:** You are responsible for maintaining the coherence with the arguments of /// other jump instructions. pub fn change_jump_destination(&mut self, inst: Inst, new_dest: Block) { - let old_dest = self.func.dfg[inst] + let old_dest = self.func.dfg.insts[inst] .branch_destination_mut() .expect("you want to change the jump destination of a non-jump instruction"); self.func_ctx.ssa.remove_block_predecessor(*old_dest, inst); diff --git a/cranelift/frontend/src/ssa.rs b/cranelift/frontend/src/ssa.rs index 0f2b88e740..ded88909e2 100644 --- a/cranelift/frontend/src/ssa.rs +++ b/cranelift/frontend/src/ssa.rs @@ -611,7 +611,7 @@ impl SSABuilder { } // Redo the match from `analyze_branch` but this time capture mutable references - match &mut func.dfg[branch] { + match &mut func.dfg.insts[branch] { InstructionData::BranchTable { destination, table, .. } => { @@ -1192,7 +1192,7 @@ mod tests { ssa.use_var(&mut func, x_var, I32, block0); assert_eq!(func.dfg.num_block_params(block0), 0); assert_eq!( - func.dfg[func.layout.first_inst(block0).unwrap()].opcode(), + func.dfg.insts[func.layout.first_inst(block0).unwrap()].opcode(), Opcode::Iconst ); } @@ -1213,7 +1213,7 @@ mod tests { ssa.seal_block(block0, &mut func); assert_eq!(func.dfg.num_block_params(block0), 0); assert_eq!( - func.dfg[func.layout.first_inst(block0).unwrap()].opcode(), + func.dfg.insts[func.layout.first_inst(block0).unwrap()].opcode(), Opcode::Iconst ); } diff --git a/cranelift/fuzzgen/src/passes/fcvt.rs b/cranelift/fuzzgen/src/passes/fcvt.rs index 8d6a92c435..106c83e423 100644 --- a/cranelift/fuzzgen/src/passes/fcvt.rs +++ b/cranelift/fuzzgen/src/passes/fcvt.rs @@ -24,7 +24,7 @@ pub fn do_fcvt_trap_pass(fuzz: &mut FuzzGen, func: &mut Function) -> Result<()> /// Returns true/false if this instruction can trap fn can_fcvt_trap(pos: &FuncCursor, inst: Inst) -> bool { - let opcode = pos.func.dfg[inst].opcode(); + let opcode = pos.func.dfg.insts[inst].opcode(); matches!(opcode, Opcode::FcvtToUint | Opcode::FcvtToSint) } @@ -66,7 +66,7 @@ fn float_limits( /// Prepend instructions to inst to avoid traps fn insert_fcvt_sequence(pos: &mut FuncCursor, inst: Inst) { let dfg = &pos.func.dfg; - let opcode = dfg[inst].opcode(); + let opcode = dfg.insts[inst].opcode(); let arg = dfg.inst_args(inst)[0]; let float_ty = dfg.value_type(arg); let int_ty = dfg.value_type(dfg.first_result(inst)); diff --git a/cranelift/fuzzgen/src/passes/int_divz.rs b/cranelift/fuzzgen/src/passes/int_divz.rs index 571e0c9495..73dca80e12 100644 --- a/cranelift/fuzzgen/src/passes/int_divz.rs +++ b/cranelift/fuzzgen/src/passes/int_divz.rs @@ -28,7 +28,7 @@ pub fn do_int_divz_pass(fuzz: &mut FuzzGen, func: &mut Function) -> Result<()> { /// Returns true/false if this instruction can cause a `int_divz` trap fn can_int_divz(pos: &FuncCursor, inst: Inst) -> bool { - let opcode = pos.func.dfg[inst].opcode(); + let opcode = pos.func.dfg.insts[inst].opcode(); matches!( opcode, @@ -38,7 +38,7 @@ fn can_int_divz(pos: &FuncCursor, inst: Inst) -> bool { /// Prepend instructions to inst to avoid `int_divz` traps fn insert_int_divz_sequence(pos: &mut FuncCursor, inst: Inst) { - let opcode = pos.func.dfg[inst].opcode(); + let opcode = pos.func.dfg.insts[inst].opcode(); let inst_args = pos.func.dfg.inst_args(inst); let (lhs, rhs) = (inst_args[0], inst_args[1]); assert_eq!(pos.func.dfg.value_type(lhs), pos.func.dfg.value_type(rhs)); diff --git a/cranelift/interpreter/src/instruction.rs b/cranelift/interpreter/src/instruction.rs index c4f552cec3..993584ce17 100644 --- a/cranelift/interpreter/src/instruction.rs +++ b/cranelift/interpreter/src/instruction.rs @@ -25,7 +25,7 @@ impl<'a> DfgInstructionContext<'a> { impl InstructionContext for DfgInstructionContext<'_> { fn data(&self) -> InstructionData { - self.1[self.0].clone() + self.1.insts[self.0].clone() } fn args(&self) -> &[Value] { diff --git a/cranelift/preopt/src/constant_folding.rs b/cranelift/preopt/src/constant_folding.rs index 59432255cc..8333f6c8e2 100644 --- a/cranelift/preopt/src/constant_folding.rs +++ b/cranelift/preopt/src/constant_folding.rs @@ -45,7 +45,7 @@ pub fn fold_constants(func: &mut ir::Function) { while let Some(_block) = pos.next_block() { while let Some(inst) = pos.next_inst() { use self::ir::InstructionData::*; - match pos.func.dfg[inst] { + match pos.func.dfg.insts[inst] { Binary { opcode, args } => { fold_binary(&mut pos.func.dfg, inst, opcode, args); } @@ -71,7 +71,7 @@ fn resolve_value_to_imm(dfg: &ir::DataFlowGraph, value: ir::Value) -> Option imm, diff --git a/cranelift/src/bugpoint.rs b/cranelift/src/bugpoint.rs index 5ac279eafd..01f18ae589 100644 --- a/cranelift/src/bugpoint.rs +++ b/cranelift/src/bugpoint.rs @@ -174,7 +174,7 @@ impl Mutator for ReplaceInstWithConst { |(_prev_block, prev_inst)| { let num_results = func.dfg.inst_results(prev_inst).len(); - let opcode = func.dfg[prev_inst].opcode(); + let opcode = func.dfg.insts[prev_inst].opcode(); if num_results == 0 || opcode == ir::Opcode::Iconst || opcode == ir::Opcode::F32const @@ -193,7 +193,7 @@ impl Mutator for ReplaceInstWithConst { let arg_def = func.dfg.value_def(arg); let arg_is_iconst = arg_def .inst() - .map(|inst| func.dfg[inst].opcode() == ir::Opcode::Iconst) + .map(|inst| func.dfg.insts[inst].opcode() == ir::Opcode::Iconst) .unwrap_or(false); if is_uextend_i128 && arg_is_iconst { @@ -266,7 +266,7 @@ impl Mutator for ReplaceInstWithTrap { fn mutate(&mut self, mut func: Function) -> Option<(Function, String, ProgressStatus)> { next_inst_ret_prev(&func, &mut self.block, &mut self.inst).map( |(_prev_block, prev_inst)| { - let status = if func.dfg[prev_inst].opcode() == ir::Opcode::Trap { + let status = if func.dfg.insts[prev_inst].opcode() == ir::Opcode::Trap { ProgressStatus::Skip } else { func.dfg.replace(prev_inst).trap(TrapCode::User(0)); @@ -421,11 +421,12 @@ impl Mutator for ReplaceBlockParamWithConst { // Remove parameters in branching instructions that point to this block for pred in cfg.pred_iter(self.block) { - let inst = &mut func.dfg[pred.inst]; + let dfg = &mut func.dfg; + let inst = &mut dfg.insts[pred.inst]; let num_fixed_args = inst.opcode().constraints().num_fixed_value_arguments(); - let mut values = inst.take_value_list().unwrap(); - values.remove(num_fixed_args + param_index, &mut func.dfg.value_lists); - func.dfg[pred.inst].put_value_list(values); + inst.value_list_mut() + .unwrap() + .remove(num_fixed_args + param_index, &mut dfg.value_lists); } if Some(self.block) == func.layout.entry_block() { @@ -471,7 +472,7 @@ impl Mutator for RemoveUnusedEntities { let mut ext_func_usage_map = HashMap::new(); for block in func.layout.blocks() { for inst in func.layout.block_insts(block) { - match func.dfg[inst] { + match func.dfg.insts[inst] { // Add new cases when there are new instruction formats taking a `FuncRef`. InstructionData::Call { func_ref, .. } | InstructionData::FuncAddr { func_ref, .. } => { @@ -491,7 +492,7 @@ impl Mutator for RemoveUnusedEntities { if let Some(func_ref_usage) = ext_func_usage_map.get(&func_ref) { let new_func_ref = ext_funcs.push(ext_func_data.clone()); for &inst in func_ref_usage { - match func.dfg[inst] { + match func.dfg.insts[inst] { // Keep in sync with the above match. InstructionData::Call { ref mut func_ref, .. @@ -522,7 +523,8 @@ impl Mutator for RemoveUnusedEntities { for block in func.layout.blocks() { for inst in func.layout.block_insts(block) { // Add new cases when there are new instruction formats taking a `SigRef`. - if let InstructionData::CallIndirect { sig_ref, .. } = func.dfg[inst] { + if let InstructionData::CallIndirect { sig_ref, .. } = func.dfg.insts[inst] + { signatures_usage_map .entry(sig_ref) .or_insert_with(Vec::new) @@ -544,7 +546,7 @@ impl Mutator for RemoveUnusedEntities { let new_sig_ref = signatures.push(sig_data.clone()); for &sig_ref_user in sig_ref_usage { match sig_ref_user { - SigRefUser::Instruction(inst) => match func.dfg[inst] { + SigRefUser::Instruction(inst) => match func.dfg.insts[inst] { // Keep in sync with the above match. InstructionData::CallIndirect { ref mut sig_ref, .. @@ -569,7 +571,7 @@ impl Mutator for RemoveUnusedEntities { let mut stack_slot_usage_map = HashMap::new(); for block in func.layout.blocks() { for inst in func.layout.block_insts(block) { - match func.dfg[inst] { + match func.dfg.insts[inst] { // Add new cases when there are new instruction formats taking a `StackSlot`. InstructionData::StackLoad { stack_slot, .. } | InstructionData::StackStore { stack_slot, .. } => { @@ -590,7 +592,7 @@ impl Mutator for RemoveUnusedEntities { if let Some(stack_slot_usage) = stack_slot_usage_map.get(&stack_slot) { let new_stack_slot = stack_slots.push(stack_slot_data.clone()); for &inst in stack_slot_usage { - match &mut func.dfg[inst] { + match &mut func.dfg.insts[inst] { // Keep in sync with the above match. InstructionData::StackLoad { stack_slot, .. } | InstructionData::StackStore { stack_slot, .. } => { @@ -612,7 +614,7 @@ impl Mutator for RemoveUnusedEntities { for inst in func.layout.block_insts(block) { // Add new cases when there are new instruction formats taking a `GlobalValue`. if let InstructionData::UnaryGlobalValue { global_value, .. } = - func.dfg[inst] + func.dfg.insts[inst] { global_value_usage_map .entry(global_value) @@ -640,7 +642,7 @@ impl Mutator for RemoveUnusedEntities { if let Some(global_value_usage) = global_value_usage_map.get(&global_value) { let new_global_value = global_values.push(global_value_data.clone()); for &inst in global_value_usage { - match &mut func.dfg[inst] { + match &mut func.dfg.insts[inst] { // Keep in sync with the above match. InstructionData::UnaryGlobalValue { global_value, .. } => { *global_value = new_global_value; @@ -711,7 +713,7 @@ impl Mutator for MergeBlocks { // instruction, then we have a conditional jump sequence that we should not break by // replacing the second instruction by more of them. if let Some(pred_pred_inst) = func.layout.prev_inst(pred.inst) { - if func.dfg[pred_pred_inst].opcode().is_branch() { + if func.dfg.insts[pred_pred_inst].opcode().is_branch() { return Some(( func, format!("did nothing for {}", block), @@ -1024,7 +1026,7 @@ impl<'a> CrashCheckContext<'a> { let contains_call = func.layout.blocks().any(|block| { func.layout .block_insts(block) - .any(|inst| match func.dfg[inst] { + .any(|inst| match func.dfg.insts[inst] { InstructionData::Call { .. } => true, _ => false, }) diff --git a/fuzz/fuzz_targets/cranelift-icache.rs b/fuzz/fuzz_targets/cranelift-icache.rs index f239ef4aad..684d80c985 100644 --- a/fuzz/fuzz_targets/cranelift-icache.rs +++ b/fuzz/fuzz_targets/cranelift-icache.rs @@ -95,15 +95,15 @@ fuzz_target!(|func: SingleFunction| { if let ir::InstructionData::UnaryImm { opcode: ir::Opcode::Iconst, imm, - } = cursor.func.dfg[inst] + } = cursor.func.dfg.insts[inst] { let imm = imm.bits(); - cursor.func.dfg[inst] = ir::InstructionData::UnaryImm { + cursor.func.dfg.insts[inst] = ir::InstructionData::UnaryImm { opcode: ir::Opcode::Iconst, imm: Imm64::new(imm.checked_add(1).unwrap_or_else(|| imm - 1)), }; } else { - cursor.func.dfg[inst] = ir::InstructionData::UnaryImm { + cursor.func.dfg.insts[inst] = ir::InstructionData::UnaryImm { opcode: ir::Opcode::Iconst, imm: Imm64::new(42), };