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

@@ -179,7 +179,7 @@ class SpecialType(ValueType):
def __init__(self, name, membytes, doc):
# type: (str, int, str) -> None
super(SpecialType, self).__init__(name, membytes, doc)
# Assign numbers starting from 1. (0 is VOID)
# Assign numbers starting from 1. (0 is INVALID)
ValueType.all_special_types.append(self)
self.number = len(ValueType.all_special_types)
assert self.number < LANE_BASE, 'Too many special types'

View File

@@ -22,8 +22,8 @@ This is the information available to us:
## Level 1 table lookup
The CPU mode provides the first table. The key is the instruction's controlling
type variable. If the instruction is not polymorphic, use `VOID` for the type
variable. The table values are level 2 tables.
type variable. If the instruction is not polymorphic, use `INVALID` for the
type variable. The table values are level 2 tables.
## Level 2 table lookup
@@ -682,7 +682,7 @@ def emit_level1_hashtable(cpumode, level1, offt, fmt):
# Empty hash table entry. Include the default legalization action.
if not level2:
fmt.format(
'Level1Entry {{ ty: ir::types::VOID, log2len: !0, '
'Level1Entry {{ ty: ir::types::INVALID, log2len: !0, '
'offset: 0, legalize: {} }},',
level1.legalize_code)
continue
@@ -690,7 +690,7 @@ def emit_level1_hashtable(cpumode, level1, offt, fmt):
if level2.ty is not None:
tyname = level2.ty.rust_name()
else:
tyname = 'ir::types::VOID'
tyname = 'ir::types::INVALID'
lcode = cpumode.isa.legalize_code(level2.legalize)

View File

@@ -705,7 +705,7 @@ def gen_inst_builder(inst, fmt):
args.append(inst.ctrl_typevar.name)
elif not inst.is_polymorphic:
# No controlling type variable needed.
args.append('types::VOID')
args.append('types::INVALID')
else:
assert inst.is_polymorphic and inst.use_typevar_operand
# Infer the controlling type variable from the input operands.

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)

View File

@@ -5,7 +5,7 @@ use cranelift_codegen::ir;
use cranelift_codegen::ir::entities::AnyEntity;
use cranelift_codegen::ir::immediates::{Ieee32, Ieee64, Imm64, Offset32, Uimm32};
use cranelift_codegen::ir::instructions::{InstructionData, InstructionFormat, VariableArgs};
use cranelift_codegen::ir::types::VOID;
use cranelift_codegen::ir::types::INVALID;
use cranelift_codegen::ir::{
AbiParam, ArgumentExtension, ArgumentLoc, Ebb, ExtFuncData, ExternalName, FuncRef, Function,
GlobalValue, GlobalValueData, Heap, HeapData, HeapStyle, JumpTable, JumpTableData, MemFlags,
@@ -194,7 +194,7 @@ impl<'a> Context<'a> {
style: HeapStyle::Static {
bound: Imm64::new(0),
},
index_type: VOID,
index_type: INVALID,
});
}
self.function.heaps[heap] = data;
@@ -218,7 +218,7 @@ impl<'a> Context<'a> {
min_size: Imm64::new(0),
bound_gv: GlobalValue::reserved_value(),
element_size: Imm64::new(0),
index_type: VOID,
index_type: INVALID,
});
}
self.function.tables[table] = data;
@@ -1951,7 +1951,7 @@ impl<'a> Parser<'a> {
// The controlling type variable can be specified explicitly as 'splat.i32x4 v5', or it can be
// inferred from `inst_data.typevar_operand` for some opcodes.
//
// Returns the controlling typevar for a polymorphic opcode, or `VOID` for a non-polymorphic
// Returns the controlling typevar for a polymorphic opcode, or `INVALID` for a non-polymorphic
// opcode.
fn infer_typevar(
&self,
@@ -2006,7 +2006,7 @@ impl<'a> Parser<'a> {
);
} else {
// This is a non-polymorphic opcode. No typevar needed.
VOID
INVALID
}
}
};
@@ -2025,7 +2025,7 @@ impl<'a> Parser<'a> {
);
}
// Treat it as a syntax error to speficy a typevar on a non-polymorphic opcode.
} else if ctrl_type != VOID {
} else if ctrl_type != INVALID {
return err!(self.loc, "{} does not take a typevar", opcode);
}

View File

@@ -277,7 +277,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
Ok(pos
.ins()
.CallIndirect(ir::Opcode::CallIndirect, VOID, sig_ref, args)
.CallIndirect(ir::Opcode::CallIndirect, INVALID, sig_ref, args)
.0)
}
@@ -300,7 +300,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
args.extend(call_args.iter().cloned(), &mut pos.func.dfg.value_lists);
args.push(vmctx, &mut pos.func.dfg.value_lists);
Ok(pos.ins().Call(ir::Opcode::Call, VOID, callee, args).0)
Ok(pos.ins().Call(ir::Opcode::Call, INVALID, callee, args).0)
}
fn translate_memory_grow(