Remove the first_type() methods from InstructionData.
Also remove the type field from all the variants. The type of the first result value can be recovered from the value table now.
This commit is contained in:
@@ -117,12 +117,6 @@ impl<'f> InstBuilderBase<'f> for ReplaceBuilder<'f> {
|
||||
// The old result values were either detached or non-existent.
|
||||
// Construct new ones.
|
||||
self.dfg.make_inst_results(self.inst, ctrl_typevar);
|
||||
} else {
|
||||
// Normally, make_inst_results() would also set the first result type, but we're not
|
||||
// going to call that, so set it manually.
|
||||
*self.dfg[self.inst].first_type_mut() = self.dfg
|
||||
.compute_result_type(self.inst, 0, ctrl_typevar)
|
||||
.unwrap_or_default();
|
||||
}
|
||||
|
||||
(self.inst, self.dfg)
|
||||
|
||||
@@ -132,7 +132,7 @@ impl DataFlowGraph {
|
||||
pub fn value_type(&self, v: Value) -> Type {
|
||||
use ir::entities::ExpandedValue::*;
|
||||
match v.expand() {
|
||||
Direct(i) => self.insts[i].first_type(),
|
||||
Direct(_) => panic!("Unexpected direct value"),
|
||||
Table(i) => {
|
||||
match self.extended_values[i] {
|
||||
ValueData::Inst { ty, .. } => ty,
|
||||
@@ -411,11 +411,6 @@ impl DataFlowGraph {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(v) = self.results[inst].first(&mut self.value_lists) {
|
||||
let ty = self.value_type(v);
|
||||
*self[inst].first_type_mut() = ty;
|
||||
}
|
||||
|
||||
total_results
|
||||
}
|
||||
|
||||
@@ -725,10 +720,7 @@ mod tests {
|
||||
fn make_inst() {
|
||||
let mut dfg = DataFlowGraph::new();
|
||||
|
||||
let idata = InstructionData::Nullary {
|
||||
opcode: Opcode::Iconst,
|
||||
ty: types::VOID,
|
||||
};
|
||||
let idata = InstructionData::Nullary { opcode: Opcode::Iconst };
|
||||
let inst = dfg.make_inst(idata);
|
||||
dfg.make_inst_results(inst, types::I32);
|
||||
assert_eq!(inst.to_string(), "inst0");
|
||||
@@ -739,7 +731,6 @@ mod tests {
|
||||
let immdfg = &dfg;
|
||||
let ins = &immdfg[inst];
|
||||
assert_eq!(ins.opcode(), Opcode::Iconst);
|
||||
assert_eq!(ins.first_type(), types::I32);
|
||||
}
|
||||
|
||||
// Results.
|
||||
@@ -754,10 +745,7 @@ mod tests {
|
||||
fn no_results() {
|
||||
let mut dfg = DataFlowGraph::new();
|
||||
|
||||
let idata = InstructionData::Nullary {
|
||||
opcode: Opcode::Trap,
|
||||
ty: types::VOID,
|
||||
};
|
||||
let idata = InstructionData::Nullary { opcode: Opcode::Trap };
|
||||
let inst = dfg.make_inst(idata);
|
||||
assert_eq!(dfg.display_inst(inst).to_string(), "trap");
|
||||
|
||||
|
||||
@@ -100,161 +100,107 @@ impl FromStr for Opcode {
|
||||
#[derive(Clone, Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum InstructionData {
|
||||
Nullary { opcode: Opcode, ty: Type },
|
||||
Unary {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
arg: Value,
|
||||
},
|
||||
UnaryImm {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
imm: Imm64,
|
||||
},
|
||||
UnaryIeee32 {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
imm: Ieee32,
|
||||
},
|
||||
UnaryIeee64 {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
imm: Ieee64,
|
||||
},
|
||||
UnarySplit {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
arg: Value,
|
||||
},
|
||||
Binary {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
args: [Value; 2],
|
||||
},
|
||||
Nullary { opcode: Opcode },
|
||||
Unary { opcode: Opcode, arg: Value },
|
||||
UnaryImm { opcode: Opcode, imm: Imm64 },
|
||||
UnaryIeee32 { opcode: Opcode, imm: Ieee32 },
|
||||
UnaryIeee64 { opcode: Opcode, imm: Ieee64 },
|
||||
UnarySplit { opcode: Opcode, arg: Value },
|
||||
Binary { opcode: Opcode, args: [Value; 2] },
|
||||
BinaryImm {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
arg: Value,
|
||||
imm: Imm64,
|
||||
},
|
||||
BinaryOverflow {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
args: [Value; 2],
|
||||
},
|
||||
Ternary {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
args: [Value; 3],
|
||||
},
|
||||
MultiAry {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
args: ValueList,
|
||||
},
|
||||
BinaryOverflow { opcode: Opcode, args: [Value; 2] },
|
||||
Ternary { opcode: Opcode, args: [Value; 3] },
|
||||
MultiAry { opcode: Opcode, args: ValueList },
|
||||
InsertLane {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
lane: Uimm8,
|
||||
args: [Value; 2],
|
||||
},
|
||||
ExtractLane {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
lane: Uimm8,
|
||||
arg: Value,
|
||||
},
|
||||
IntCompare {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
cond: IntCC,
|
||||
args: [Value; 2],
|
||||
},
|
||||
IntCompareImm {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
cond: IntCC,
|
||||
arg: Value,
|
||||
imm: Imm64,
|
||||
},
|
||||
FloatCompare {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
cond: FloatCC,
|
||||
args: [Value; 2],
|
||||
},
|
||||
Jump {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
destination: Ebb,
|
||||
args: ValueList,
|
||||
},
|
||||
Branch {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
destination: Ebb,
|
||||
args: ValueList,
|
||||
},
|
||||
BranchIcmp {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
cond: IntCC,
|
||||
destination: Ebb,
|
||||
args: ValueList,
|
||||
},
|
||||
BranchTable {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
arg: Value,
|
||||
table: JumpTable,
|
||||
},
|
||||
Call {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
func_ref: FuncRef,
|
||||
args: ValueList,
|
||||
},
|
||||
IndirectCall {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
sig_ref: SigRef,
|
||||
args: ValueList,
|
||||
},
|
||||
StackLoad {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
stack_slot: StackSlot,
|
||||
offset: Offset32,
|
||||
},
|
||||
StackStore {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
arg: Value,
|
||||
stack_slot: StackSlot,
|
||||
offset: Offset32,
|
||||
},
|
||||
HeapLoad {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
arg: Value,
|
||||
offset: Uoffset32,
|
||||
},
|
||||
HeapStore {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
args: [Value; 2],
|
||||
offset: Uoffset32,
|
||||
},
|
||||
Load {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
flags: MemFlags,
|
||||
arg: Value,
|
||||
offset: Offset32,
|
||||
},
|
||||
Store {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
flags: MemFlags,
|
||||
args: [Value; 2],
|
||||
offset: Offset32,
|
||||
|
||||
@@ -118,7 +118,6 @@ mod tests {
|
||||
// Try to encode iadd_imm.i64 vx1, -10.
|
||||
let inst64 = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I64,
|
||||
arg: arg64,
|
||||
imm: immediates::Imm64::new(-10),
|
||||
};
|
||||
@@ -130,7 +129,6 @@ mod tests {
|
||||
// Try to encode iadd_imm.i64 vx1, -10000.
|
||||
let inst64_large = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I64,
|
||||
arg: arg64,
|
||||
imm: immediates::Imm64::new(-10000),
|
||||
};
|
||||
@@ -142,7 +140,6 @@ mod tests {
|
||||
// Create an iadd_imm.i32 which is encodable in RV64.
|
||||
let inst32 = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I32,
|
||||
arg: arg32,
|
||||
imm: immediates::Imm64::new(10),
|
||||
};
|
||||
@@ -168,7 +165,6 @@ mod tests {
|
||||
// Try to encode iadd_imm.i64 vx1, -10.
|
||||
let inst64 = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I64,
|
||||
arg: arg64,
|
||||
imm: immediates::Imm64::new(-10),
|
||||
};
|
||||
@@ -180,7 +176,6 @@ mod tests {
|
||||
// Try to encode iadd_imm.i64 vx1, -10000.
|
||||
let inst64_large = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I64,
|
||||
arg: arg64,
|
||||
imm: immediates::Imm64::new(-10000),
|
||||
};
|
||||
@@ -192,7 +187,6 @@ mod tests {
|
||||
// Create an iadd_imm.i32 which is encodable in RV32.
|
||||
let inst32 = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I32,
|
||||
arg: arg32,
|
||||
imm: immediates::Imm64::new(10),
|
||||
};
|
||||
@@ -204,7 +198,6 @@ mod tests {
|
||||
// Create an imul.i32 which is encodable in RV32, but only when use_m is true.
|
||||
let mul32 = InstructionData::Binary {
|
||||
opcode: Opcode::Imul,
|
||||
ty: types::I32,
|
||||
args: [arg32, arg32],
|
||||
};
|
||||
|
||||
@@ -232,7 +225,6 @@ mod tests {
|
||||
// Create an imul.i32 which is encodable in RV32M.
|
||||
let mul32 = InstructionData::Binary {
|
||||
opcode: Opcode::Imul,
|
||||
ty: types::I32,
|
||||
args: [arg32, arg32],
|
||||
};
|
||||
assert_eq!(encstr(&*isa, isa.encode(&dfg, &mul32, types::I32).unwrap()),
|
||||
|
||||
@@ -183,23 +183,13 @@ impl<'a> Verifier<'a> {
|
||||
.unwrap_or(0);
|
||||
let total_results = fixed_results + var_results;
|
||||
|
||||
if total_results == 0 {
|
||||
// Instructions with no results have a NULL `first_type()`
|
||||
let ret_type = inst_data.first_type();
|
||||
if ret_type != types::VOID {
|
||||
return err!(inst,
|
||||
"instruction with no results expects NULL return type, found {}",
|
||||
ret_type);
|
||||
}
|
||||
} else {
|
||||
// All result values for multi-valued instructions are created
|
||||
let got_results = dfg.inst_results(inst).len();
|
||||
if got_results != total_results {
|
||||
return err!(inst,
|
||||
"expected {} result values, found {}",
|
||||
total_results,
|
||||
got_results);
|
||||
}
|
||||
// All result values for multi-valued instructions are created
|
||||
let got_results = dfg.inst_results(inst).len();
|
||||
if got_results != total_results {
|
||||
return err!(inst,
|
||||
"expected {} result values, found {}",
|
||||
total_results,
|
||||
got_results);
|
||||
}
|
||||
|
||||
self.verify_entity_references(inst)
|
||||
@@ -671,7 +661,6 @@ mod tests {
|
||||
use super::{Verifier, Error};
|
||||
use ir::Function;
|
||||
use ir::instructions::{InstructionData, Opcode};
|
||||
use ir::types;
|
||||
|
||||
macro_rules! assert_err_with_msg {
|
||||
($e:expr, $msg:expr) => (
|
||||
@@ -698,11 +687,9 @@ mod tests {
|
||||
let mut func = Function::new();
|
||||
let ebb0 = func.dfg.make_ebb();
|
||||
func.layout.append_ebb(ebb0);
|
||||
let nullary_with_bad_opcode = func.dfg
|
||||
.make_inst(InstructionData::Nullary {
|
||||
opcode: Opcode::Jump,
|
||||
ty: types::VOID,
|
||||
});
|
||||
let nullary_with_bad_opcode =
|
||||
func.dfg
|
||||
.make_inst(InstructionData::Nullary { opcode: Opcode::Jump });
|
||||
func.layout.append_inst(nullary_with_bad_opcode, ebb0);
|
||||
let verifier = Verifier::new(&func);
|
||||
assert_err_with_msg!(verifier.run(), "instruction format");
|
||||
|
||||
Reference in New Issue
Block a user