Make the dfg.insts table private again.
- Add a dfg.is_inst_valid() method for the verifier. - Use the inst_args_mut() method when rewriting values in the parser. - Add a new branch_destination_mut() to use when rewriting EBBs. This also gets rid of one of the large instruction format switches in the parser.
This commit is contained in:
@@ -26,7 +26,7 @@ pub struct DataFlowGraph {
|
|||||||
/// Data about all of the instructions in the function, including opcodes and operands.
|
/// 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
|
/// The instructions in this map are not in program order. That is tracked by `Layout`, along
|
||||||
/// with the EBB containing each instruction.
|
/// with the EBB containing each instruction.
|
||||||
pub insts: EntityMap<Inst, InstructionData>,
|
insts: EntityMap<Inst, InstructionData>,
|
||||||
|
|
||||||
/// Memory pool of value lists referenced by instructions in `insts`.
|
/// Memory pool of value lists referenced by instructions in `insts`.
|
||||||
pub value_lists: ValueListPool,
|
pub value_lists: ValueListPool,
|
||||||
@@ -77,6 +77,11 @@ impl DataFlowGraph {
|
|||||||
self.insts.len()
|
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
|
/// Get the total number of extended basic blocks created in this function, whether they are
|
||||||
/// currently inserted in the layout or not.
|
/// currently inserted in the layout or not.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -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.
|
/// Return information about a call instruction.
|
||||||
///
|
///
|
||||||
/// Any instruction that can call another function reveals its call signature here.
|
/// Any instruction that can call another function reveals its call signature here.
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ impl<'a> Verifier<'a> {
|
|||||||
match dfg.value_def(v) {
|
match dfg.value_def(v) {
|
||||||
ValueDef::Res(def_inst, _) => {
|
ValueDef::Res(def_inst, _) => {
|
||||||
// Value is defined by an instruction that exists.
|
// 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,
|
return err!(loc_inst,
|
||||||
"{} is defined by invalid instruction {}",
|
"{} is defined by invalid instruction {}",
|
||||||
v,
|
v,
|
||||||
|
|||||||
@@ -213,71 +213,10 @@ impl<'a> Context<'a> {
|
|||||||
for ebb in self.function.layout.ebbs() {
|
for ebb in self.function.layout.ebbs() {
|
||||||
for inst in self.function.layout.ebb_insts(ebb) {
|
for inst in self.function.layout.ebb_insts(ebb) {
|
||||||
let loc = inst.into();
|
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
|
self.map
|
||||||
.rewrite_values(args.as_mut_slice(value_lists), loc)?;
|
.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)?;
|
||||||
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)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user