From d4b862239327e593134412c53b7ea13785adfa74 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 4 Sep 2018 21:46:22 -0700 Subject: [PATCH] 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. --- lib/codegen/meta-python/cdsl/types.py | 2 +- lib/codegen/meta-python/gen_encoding.py | 8 ++--- lib/codegen/meta-python/gen_instr.py | 2 +- lib/codegen/src/ir/builder.rs | 2 +- lib/codegen/src/ir/dfg.rs | 26 ++++++++-------- lib/codegen/src/ir/types.rs | 41 ++++++++++++------------- lib/codegen/src/isa/enc_tables.rs | 2 +- lib/codegen/src/verifier/mod.rs | 4 +-- lib/codegen/src/write.rs | 16 ++++++---- lib/reader/src/parser.rs | 12 ++++---- lib/wasm/src/environ/dummy.rs | 4 +-- 11 files changed, 61 insertions(+), 58 deletions(-) diff --git a/lib/codegen/meta-python/cdsl/types.py b/lib/codegen/meta-python/cdsl/types.py index 13bc5deab1..26777152da 100644 --- a/lib/codegen/meta-python/cdsl/types.py +++ b/lib/codegen/meta-python/cdsl/types.py @@ -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' diff --git a/lib/codegen/meta-python/gen_encoding.py b/lib/codegen/meta-python/gen_encoding.py index a81b66dcca..59875bf489 100644 --- a/lib/codegen/meta-python/gen_encoding.py +++ b/lib/codegen/meta-python/gen_encoding.py @@ -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) diff --git a/lib/codegen/meta-python/gen_instr.py b/lib/codegen/meta-python/gen_instr.py index 4b73b95bc6..2f5eeae93d 100644 --- a/lib/codegen/meta-python/gen_instr.py +++ b/lib/codegen/meta-python/gen_instr.py @@ -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. diff --git a/lib/codegen/src/ir/builder.rs b/lib/codegen/src/ir/builder.rs index 5cd2bfe36d..9128092f67 100644 --- a/lib/codegen/src/ir/builder.rs +++ b/lib/codegen/src/ir/builder.rs @@ -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); } diff --git a/lib/codegen/src/ir/dfg.rs b/lib/codegen/src/ir/dfg.rs index 6d799a43c9..08bec5d624 100644 --- a/lib/codegen/src/ir/dfg.rs +++ b/lib/codegen/src/ir/dfg.rs @@ -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 } diff --git a/lib/codegen/src/ir/types.rs b/lib/codegen/src/ir/types.rs index 195d90968a..1d19f5c6d7 100644 --- a/lib/codegen/src/ir/types.rs +++ b/lib/codegen/src/ir/types.rs @@ -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] diff --git a/lib/codegen/src/isa/enc_tables.rs b/lib/codegen/src/isa/enc_tables.rs index 0a98ace71a..1d8ed94780 100644 --- a/lib/codegen/src/isa/enc_tables.rs +++ b/lib/codegen/src/isa/enc_tables.rs @@ -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 diff --git a/lib/codegen/src/verifier/mod.rs b/lib/codegen/src/verifier/mod.rs index 16e21565ac..51aa484525 100644 --- a/lib/codegen/src/verifier/mod.rs +++ b/lib/codegen/src/verifier/mod.rs @@ -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 diff --git a/lib/codegen/src/write.rs b/lib/codegen/src/write.rs index 24cfdbe284..2e9faf6b40 100644 --- a/lib/codegen/src/write.rs +++ b/lib/codegen/src/write.rs @@ -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 { let rtype = func.dfg.ctrl_typevar(inst); assert!( - !rtype.is_void(), + !rtype.is_invalid(), "Polymorphic instruction must produce a result" ); Some(rtype) diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index 5358109a2e..4a116699b8 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -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); } diff --git a/lib/wasm/src/environ/dummy.rs b/lib/wasm/src/environ/dummy.rs index d7c9c47c10..229e2a7274 100644 --- a/lib/wasm/src/environ/dummy.rs +++ b/lib/wasm/src/environ/dummy.rs @@ -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(