diff --git a/lib/cretonne/src/ir/dfg.rs b/lib/cretonne/src/ir/dfg.rs index 9178aeeb38..63ae3a5e97 100644 --- a/lib/cretonne/src/ir/dfg.rs +++ b/lib/cretonne/src/ir/dfg.rs @@ -26,7 +26,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 EBB containing each instruction. - pub insts: EntityMap, + insts: EntityMap, /// Memory pool of value lists referenced by instructions in `insts`. pub value_lists: ValueListPool, @@ -77,6 +77,11 @@ impl DataFlowGraph { self.insts.len() } + /// Returns `true` if the given instruction reference is valid. + pub fn inst_is_valid(&self, inst: Inst) -> bool { + self.insts.is_valid(inst) + } + /// Get the total number of extended basic blocks created in this function, whether they are /// currently inserted in the layout or not. /// diff --git a/lib/cretonne/src/ir/instructions.rs b/lib/cretonne/src/ir/instructions.rs index f48cbcae6f..626c130740 100644 --- a/lib/cretonne/src/ir/instructions.rs +++ b/lib/cretonne/src/ir/instructions.rs @@ -376,6 +376,19 @@ impl InstructionData { } } + /// Get a mutable reference to the single destination of this branch instruction, if it is a + /// single destination branch or jump. + /// + /// Multi-destination branches like `br_table` return `None`. + pub fn branch_destination_mut(&mut self) -> Option<&mut Ebb> { + match *self { + InstructionData::Jump { ref mut destination, .. } => Some(destination), + InstructionData::Branch { ref mut destination, .. } => Some(destination), + InstructionData::BranchIcmp { ref mut destination, .. } => Some(destination), + _ => None, + } + } + /// Return information about a call instruction. /// /// Any instruction that can call another function reveals its call signature here. diff --git a/lib/cretonne/src/verifier.rs b/lib/cretonne/src/verifier.rs index 371ada0440..ace83235df 100644 --- a/lib/cretonne/src/verifier.rs +++ b/lib/cretonne/src/verifier.rs @@ -337,7 +337,7 @@ impl<'a> Verifier<'a> { match dfg.value_def(v) { ValueDef::Res(def_inst, _) => { // Value is defined by an instruction that exists. - if !dfg.insts.is_valid(def_inst) { + if !dfg.inst_is_valid(def_inst) { return err!(loc_inst, "{} is defined by invalid instruction {}", v, diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index a0302a1a30..a5c3b4244c 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -213,71 +213,10 @@ impl<'a> Context<'a> { for ebb in self.function.layout.ebbs() { for inst in self.function.layout.ebb_insts(ebb) { let loc = inst.into(); - let value_lists = &mut self.function.dfg.value_lists; - match self.function.dfg.insts[inst] { - InstructionData::Nullary { .. } | - InstructionData::UnaryImm { .. } | - InstructionData::UnaryIeee32 { .. } | - InstructionData::UnaryIeee64 { .. } | - InstructionData::StackLoad { .. } => {} - - InstructionData::BinaryImm { ref mut arg, .. } | - InstructionData::BranchTable { ref mut arg, .. } | - InstructionData::ExtractLane { ref mut arg, .. } | - InstructionData::IntCompareImm { ref mut arg, .. } | - InstructionData::Unary { ref mut arg, .. } | - InstructionData::UnarySplit { ref mut arg, .. } | - InstructionData::StackStore { ref mut arg, .. } | - InstructionData::HeapLoad { ref mut arg, .. } | - InstructionData::Load { ref mut arg, .. } => { - self.map.rewrite_value(arg, loc)?; - } - - // `args: Value[2]` - InstructionData::Binary { ref mut args, .. } | - InstructionData::BinaryOverflow { ref mut args, .. } | - InstructionData::InsertLane { ref mut args, .. } | - InstructionData::IntCompare { ref mut args, .. } | - InstructionData::FloatCompare { ref mut args, .. } | - InstructionData::HeapStore { ref mut args, .. } | - InstructionData::Store { ref mut args, .. } => { - self.map.rewrite_values(args, loc)?; - } - - InstructionData::Ternary { ref mut args, .. } => { - self.map.rewrite_values(args, loc)?; - } - - InstructionData::MultiAry { ref mut args, .. } => { - self.map - .rewrite_values(args.as_mut_slice(value_lists), loc)?; - } - - InstructionData::Jump { - ref mut destination, - ref mut args, - .. - } | - InstructionData::Branch { - ref mut destination, - ref mut args, - .. - } | - InstructionData::BranchIcmp { - ref mut destination, - ref mut args, - .. - } => { - self.map.rewrite_ebb(destination, loc)?; - self.map - .rewrite_values(args.as_mut_slice(value_lists), loc)?; - } - - InstructionData::Call { ref mut args, .. } | - InstructionData::IndirectCall { ref mut args, .. } => { - self.map - .rewrite_values(args.as_mut_slice(value_lists), loc)?; - } + self.map + .rewrite_values(self.function.dfg.inst_args_mut(inst), loc)?; + if let Some(dest) = self.function.dfg[inst].branch_destination_mut() { + self.map.rewrite_ebb(dest, loc)?; } } }