Rename the VOID type to INVALID and clean up obsolete comments.

The VOID type isn't used for anything resembling what "void" means in C,
so rename it to INVALID to avoid confusion.
This commit is contained in:
Dan Gohman
2018-09-04 21:46:22 -07:00
parent 18900df4d5
commit d4b8622393
11 changed files with 61 additions and 58 deletions

View File

@@ -28,7 +28,7 @@ pub trait InstBuilderBase<'f>: Sized {
/// Insert an instruction and return a reference to it, consuming the builder.
///
/// The result types may depend on a controlling type variable. For non-polymorphic
/// instructions with multiple results, pass `VOID` for the `ctrl_typevar` argument.
/// instructions with multiple results, pass `INVALID` for the `ctrl_typevar` argument.
fn build(self, data: InstructionData, ctrl_typevar: Type) -> (Inst, &'f mut DataFlowGraph);
}

View File

@@ -157,7 +157,7 @@ pub struct Values<'a> {
/// Check for non-values
fn valid_valuedata(data: &ValueData) -> bool {
if let &ValueData::Alias {
ty: types::VOID,
ty: types::INVALID,
original,
} = data
{
@@ -288,7 +288,7 @@ impl DataFlowGraph {
self.value_type(dest),
ty
);
debug_assert_ne!(ty, types::VOID);
debug_assert_ne!(ty, types::INVALID);
self.values[dest] = ValueData::Alias { ty, original };
}
@@ -332,7 +332,7 @@ impl DataFlowGraph {
self.value_type(dest),
ty
);
debug_assert_ne!(ty, types::VOID);
debug_assert_ne!(ty, types::INVALID);
self.values[dest] = ValueData::Alias { ty, original };
}
@@ -461,7 +461,7 @@ impl DataFlowGraph {
///
/// The result value types are determined from the instruction's value type constraints and the
/// provided `ctrl_typevar` type for polymorphic instructions. For non-polymorphic
/// instructions, `ctrl_typevar` is ignored, and `VOID` can be used.
/// instructions, `ctrl_typevar` is ignored, and `INVALID` can be used.
///
/// The type of the first result value is also set, even if it was already set in the
/// `InstructionData` passed to `make_inst`. If this function is called with a single-result
@@ -679,12 +679,12 @@ impl DataFlowGraph {
})
}
/// Get the controlling type variable, or `VOID` if `inst` isn't polymorphic.
/// 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();
if !constraints.is_polymorphic() {
types::VOID
types::INVALID
} else if constraints.requires_typevar_operand() {
// Not all instruction formats have a designated operand, but in that case
// `requires_typevar_operand()` should never be true.
@@ -897,7 +897,7 @@ impl<'a> fmt::Display for DisplayInst<'a> {
}
let typevar = dfg.ctrl_typevar(inst);
if typevar.is_void() {
if typevar.is_invalid() {
write!(f, "{}", dfg[inst].opcode())?;
} else {
write!(f, "{}.{}", dfg[inst].opcode(), typevar)?;
@@ -914,7 +914,7 @@ impl DataFlowGraph {
fn set_value_type_for_parser(&mut self, v: Value, t: Type) {
assert_eq!(
self.value_type(v),
types::VOID,
types::INVALID,
"this function is only for assigning types to previously invalid values"
);
match self.values[v] {
@@ -980,9 +980,9 @@ impl DataFlowGraph {
let ty = if self.values.is_valid(src) {
self.value_type(src)
} else {
// As a special case, if we can't resolve the aliasee yet, use VOID
// As a special case, if we can't resolve the aliasee yet, use INVALID
// temporarily. It will be resolved later in parsing.
types::VOID
types::INVALID
};
let data = ValueData::Alias { ty, original: src };
self.values[dest] = data;
@@ -1007,7 +1007,7 @@ impl DataFlowGraph {
if let Some(resolved) = maybe_resolve_aliases(&self.values, v) {
let old_ty = self.value_type(v);
let new_ty = self.value_type(resolved);
if old_ty == types::VOID {
if old_ty == types::INVALID {
self.set_value_type_for_parser(v, new_ty);
} else {
assert_eq!(old_ty, new_ty);
@@ -1023,7 +1023,7 @@ impl DataFlowGraph {
#[cold]
pub fn make_invalid_value_for_parser(&mut self) {
let data = ValueData::Alias {
ty: types::VOID,
ty: types::INVALID,
original: Value::reserved_value(),
};
self.make_value(data);
@@ -1037,7 +1037,7 @@ impl DataFlowGraph {
return false;
}
if let ValueData::Alias { ty, .. } = self.values[v] {
ty != types::VOID
ty != types::INVALID
} else {
true
}

View File

@@ -5,8 +5,9 @@ use std::fmt::{self, Debug, Display, Formatter};
/// The type of an SSA value.
///
/// The `VOID` type is only used for instructions that produce no value. It can't be part of a SIMD
/// vector.
/// The `INVALID` type isn't a real type, and is used as a placeholder in the IR where a type
/// field is present put no type is needed, such as the controlling type variable for a
/// non-polymorphic instruction.
///
/// Basic integer types: `I8`, `I16`, `I32`, and `I64`. These types are sign-agnostic.
///
@@ -20,9 +21,8 @@ use std::fmt::{self, Debug, Display, Formatter};
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Type(u8);
/// No type. Used for functions without a return value. Can't be loaded or stored. Can't be part of
/// a SIMD vector.
pub const VOID: Type = Type(0);
/// Not a valid type. Can't be loaded or stored. Can't be part of a SIMD vector.
pub const INVALID: Type = Type(0);
/// Start of the lane types. See also `meta-python/cdsl.types.py`.
const LANE_BASE: u8 = 0x70;
@@ -146,9 +146,9 @@ impl Type {
}))
}
/// Is this the VOID type?
pub fn is_void(self) -> bool {
self == VOID
/// Is this the INVALID type?
pub fn is_invalid(self) -> bool {
self == INVALID
}
/// Is this a special type?
@@ -285,10 +285,10 @@ impl Display for Type {
write!(f, "{}x{}", self.lane_type(), self.lane_count())
} else {
f.write_str(match *self {
VOID => "void",
IFLAGS => "iflags",
FFLAGS => "fflags",
_ => panic!("Invalid Type(0x{:x})", self.0),
INVALID => panic!("INVALID encountered"),
_ => panic!("Unknown Type(0x{:x})", self.0),
})
}
}
@@ -306,7 +306,7 @@ impl Debug for Type {
write!(f, "{:?}X{}", self.lane_type(), self.lane_count())
} else {
match *self {
VOID => write!(f, "types::VOID"),
INVALID => write!(f, "types::INVALID"),
IFLAGS => write!(f, "types::IFLAGS"),
FFLAGS => write!(f, "types::FFLAGS"),
_ => write!(f, "Type(0x{:x})", self.0),
@@ -317,7 +317,7 @@ impl Debug for Type {
impl Default for Type {
fn default() -> Self {
VOID
INVALID
}
}
@@ -328,8 +328,8 @@ mod tests {
#[test]
fn basic_scalars() {
assert_eq!(VOID, VOID.lane_type());
assert_eq!(0, VOID.bits());
assert_eq!(INVALID, INVALID.lane_type());
assert_eq!(0, INVALID.bits());
assert_eq!(IFLAGS, IFLAGS.lane_type());
assert_eq!(0, IFLAGS.bits());
assert_eq!(FFLAGS, FFLAGS.lane_type());
@@ -346,7 +346,7 @@ mod tests {
assert_eq!(F32, F32.lane_type());
assert_eq!(F64, F64.lane_type());
assert_eq!(VOID.lane_bits(), 0);
assert_eq!(INVALID.lane_bits(), 0);
assert_eq!(IFLAGS.lane_bits(), 0);
assert_eq!(FFLAGS.lane_bits(), 0);
assert_eq!(B1.lane_bits(), 1);
@@ -364,8 +364,8 @@ mod tests {
#[test]
fn typevar_functions() {
assert_eq!(VOID.half_width(), None);
assert_eq!(IFLAGS.half_width(), None);
assert_eq!(INVALID.half_width(), None);
assert_eq!(INVALID.half_width(), None);
assert_eq!(FFLAGS.half_width(), None);
assert_eq!(B1.half_width(), None);
assert_eq!(B8.half_width(), None);
@@ -380,7 +380,7 @@ mod tests {
assert_eq!(F32.half_width(), None);
assert_eq!(F64.half_width(), Some(F32));
assert_eq!(VOID.double_width(), None);
assert_eq!(INVALID.double_width(), None);
assert_eq!(IFLAGS.double_width(), None);
assert_eq!(FFLAGS.double_width(), None);
assert_eq!(B1.double_width(), None);
@@ -407,7 +407,7 @@ mod tests {
assert_eq!(big.half_vector().unwrap().to_string(), "f64x128");
assert_eq!(B1.by(2).unwrap().half_vector().unwrap().to_string(), "b1");
assert_eq!(I32.half_vector(), None);
assert_eq!(VOID.half_vector(), None);
assert_eq!(INVALID.half_vector(), None);
// Check that the generated constants match the computed vector types.
assert_eq!(I32.by(4), Some(I32X4));
@@ -416,7 +416,6 @@ mod tests {
#[test]
fn format_scalars() {
assert_eq!(VOID.to_string(), "void");
assert_eq!(IFLAGS.to_string(), "iflags");
assert_eq!(FFLAGS.to_string(), "fflags");
assert_eq!(B1.to_string(), "b1");
@@ -443,7 +442,7 @@ mod tests {
assert_eq!(F64.by(2).unwrap().to_string(), "f64x2");
assert_eq!(I8.by(3), None);
assert_eq!(I8.by(512), None);
assert_eq!(VOID.by(4), None);
assert_eq!(INVALID.by(4), None);
}
#[test]

View File

@@ -30,7 +30,7 @@ pub type LegalizeCode = u8;
/// Level 1 hash table entry.
///
/// One level 1 hash table is generated per CPU mode. This table is keyed by the controlling type
/// variable, using `VOID` for non-polymorphic instructions.
/// variable, using `INVALID` for non-polymorphic instructions.
///
/// The hash table values are references to level 2 hash tables, encoded as an offset in `LEVEL2`
/// where the table begins, and the binary logarithm of its length. All the level 2 hash tables

View File

@@ -1106,8 +1106,8 @@ impl<'a> Verifier<'a> {
ctrl_type
} else {
// Non-polymorphic instructions don't check the controlling type variable, so `Option`
// is unnecessary and we can just make it `VOID`.
types::VOID
// is unnecessary and we can just make it `INVALID`.
types::INVALID
};
// Typechecking instructions is never fatal

View File

@@ -44,13 +44,17 @@ pub trait FuncWriter {
}
for (heap, heap_data) in &func.heaps {
any = true;
self.write_entity_definition(w, func, heap.into(), heap_data)?;
if !heap_data.index_type.is_invalid() {
any = true;
self.write_entity_definition(w, func, heap.into(), heap_data)?;
}
}
for (table, table_data) in &func.tables {
any = true;
self.write_entity_definition(w, func, table.into(), table_data)?;
if !table_data.index_type.is_invalid() {
any = true;
self.write_entity_definition(w, func, table.into(), table_data)?;
}
}
// Write out all signatures before functions since function declarations can refer to
@@ -61,8 +65,8 @@ pub trait FuncWriter {
}
for (fnref, ext_func) in &func.dfg.ext_funcs {
any = true;
if ext_func.signature != SigRef::reserved_value() {
any = true;
self.write_entity_definition(w, func, fnref.into(), ext_func)?;
}
}
@@ -265,7 +269,7 @@ fn type_suffix(func: &Function, inst: Inst) -> Option<Type> {
let rtype = func.dfg.ctrl_typevar(inst);
assert!(
!rtype.is_void(),
!rtype.is_invalid(),
"Polymorphic instruction must produce a result"
);
Some(rtype)