diff --git a/lib/cretonne/meta/base/formats.py b/lib/cretonne/meta/base/formats.py index acb9ce0131..6e64e0e3f2 100644 --- a/lib/cretonne/meta/base/formats.py +++ b/lib/cretonne/meta/base/formats.py @@ -18,14 +18,10 @@ Unary = InstructionFormat(VALUE) UnaryImm = InstructionFormat(imm64) UnaryIeee32 = InstructionFormat(ieee32) UnaryIeee64 = InstructionFormat(ieee64) -UnarySplit = InstructionFormat(VALUE, multiple_results=True) Binary = InstructionFormat(VALUE, VALUE) BinaryImm = InstructionFormat(VALUE, imm64) -# Generate result + overflow flag. -BinaryOverflow = InstructionFormat(VALUE, VALUE, multiple_results=True) - # The select instructions are controlled by the second VALUE operand. # The first VALUE operand is the controlling flag which has a derived type. # The fma instruction has the same constraint on all inputs. @@ -33,7 +29,7 @@ Ternary = InstructionFormat(VALUE, VALUE, VALUE, typevar_operand=1) # Catch-all for instructions with many outputs and inputs and no immediate # operands. -MultiAry = InstructionFormat(VARIABLE_ARGS, multiple_results=True) +MultiAry = InstructionFormat(VARIABLE_ARGS) InsertLane = InstructionFormat(VALUE, ('lane', uimm8), VALUE) ExtractLane = InstructionFormat(VALUE, ('lane', uimm8)) @@ -47,11 +43,8 @@ Branch = InstructionFormat(VALUE, ebb, VARIABLE_ARGS) BranchIcmp = InstructionFormat(intcc, VALUE, VALUE, ebb, VARIABLE_ARGS) BranchTable = InstructionFormat(VALUE, jump_table) -Call = InstructionFormat( - func_ref, VARIABLE_ARGS, multiple_results=True) -IndirectCall = InstructionFormat( - sig_ref, VALUE, VARIABLE_ARGS, - multiple_results=True) +Call = InstructionFormat(func_ref, VARIABLE_ARGS) +IndirectCall = InstructionFormat(sig_ref, VALUE, VARIABLE_ARGS) Load = InstructionFormat(memflags, VALUE, offset32) Store = InstructionFormat(memflags, VALUE, VALUE, offset32) diff --git a/lib/cretonne/meta/cdsl/formats.py b/lib/cretonne/meta/cdsl/formats.py index f08d6fa119..0b7a72fe0a 100644 --- a/lib/cretonne/meta/cdsl/formats.py +++ b/lib/cretonne/meta/cdsl/formats.py @@ -18,13 +18,6 @@ class InstructionFormat(object): identified structurally, i.e., the format of an instruction is derived from the kinds of operands used in its declaration. - Most instruction formats produce a single result, or no result at all. If - an instruction can produce more than one result, the `multiple_results` - flag must be set on its format. All results are of the `value` kind, and - the instruction format does not keep track of how many results are - produced. Some instructions, like `call`, may have a variable number of - results. - The instruction format stores two separate lists of operands: Immediates and values. Immediate operands (including entity references) are represented as explicit members in the `InstructionData` variants. The @@ -40,16 +33,14 @@ class InstructionFormat(object): :param name: Instruction format name in CamelCase. This is used as a Rust variant name in both the `InstructionData` and `InstructionFormat` enums. - :param multiple_results: Set to `True` if this instruction format allows - more than one result to be produced. :param typevar_operand: Index of the value input operand that is used to infer the controlling type variable. By default, this is `0`, the first `value` operand. The index is relative to the values only, ignoring immediate operands. """ - # Map (multiple_results, imm_kinds, num_value_operands) -> format - _registry = dict() # type: Dict[Tuple[bool, Tuple[OperandKind, ...], int, bool], InstructionFormat] # noqa + # Map (imm_kinds, num_value_operands) -> format + _registry = dict() # type: Dict[Tuple[Tuple[OperandKind, ...], int, bool], InstructionFormat] # noqa # All existing formats. all_formats = list() # type: List[InstructionFormat] @@ -57,7 +48,6 @@ class InstructionFormat(object): def __init__(self, *kinds, **kwargs): # type: (*Union[OperandKind, Tuple[str, OperandKind]], **Any) -> None # noqa self.name = kwargs.get('name', None) # type: str - self.multiple_results = kwargs.get('multiple_results', False) # The number of value operands stored in the format, or `None` when # `has_value_list` is set. @@ -81,9 +71,7 @@ class InstructionFormat(object): # Compute a signature for the global registry. imm_kinds = tuple(f.kind for f in self.imm_fields) - sig = ( - self.multiple_results, imm_kinds, self.num_value_operands, - self.has_value_list) + sig = (imm_kinds, self.num_value_operands, self.has_value_list) if sig in InstructionFormat._registry: raise RuntimeError( "Format '{}' has the same signature as existing format '{}'" @@ -158,37 +146,24 @@ class InstructionFormat(object): :py:class:`Instruction` arguments of the same name, except they must be tuples of :py:`Operand` objects. """ - if len(outs) == 1: - multiple_results = outs[0].kind == VARIABLE_ARGS - else: - multiple_results = len(outs) > 1 - # Construct a signature. imm_kinds = tuple(op.kind for op in ins if op.is_immediate()) num_values = sum(1 for op in ins if op.is_value()) has_varargs = (VARIABLE_ARGS in tuple(op.kind for op in ins)) - sig = (multiple_results, imm_kinds, num_values, has_varargs) + sig = (imm_kinds, num_values, has_varargs) if sig in InstructionFormat._registry: return InstructionFormat._registry[sig] # Try another value list format as an alternative. - sig = (True, imm_kinds, num_values, has_varargs) - if sig in InstructionFormat._registry: - return InstructionFormat._registry[sig] - - sig = (multiple_results, imm_kinds, 0, True) - if sig in InstructionFormat._registry: - return InstructionFormat._registry[sig] - - sig = (True, imm_kinds, 0, True) + sig = (imm_kinds, 0, True) if sig in InstructionFormat._registry: return InstructionFormat._registry[sig] raise RuntimeError( - 'No instruction format matches multiple_results={},' + 'No instruction format matches ' 'imms={}, vals={}, varargs={}'.format( - multiple_results, imm_kinds, num_values, has_varargs)) + imm_kinds, num_values, has_varargs)) @staticmethod def extract_names(globs): diff --git a/lib/cretonne/meta/cdsl/isa.py b/lib/cretonne/meta/cdsl/isa.py index 1ead583c5a..a44a1e6333 100644 --- a/lib/cretonne/meta/cdsl/isa.py +++ b/lib/cretonne/meta/cdsl/isa.py @@ -207,8 +207,6 @@ class EncRecipe(object): if not format.has_value_list: assert len(self.ins) == format.num_value_operands self.outs = self._verify_constraints(outs) - if len(self.outs) > 1: - assert format.multiple_results def __str__(self): # type: () -> str diff --git a/lib/cretonne/src/ir/instructions.rs b/lib/cretonne/src/ir/instructions.rs index 61ed2f1eeb..9484110d83 100644 --- a/lib/cretonne/src/ir/instructions.rs +++ b/lib/cretonne/src/ir/instructions.rs @@ -105,14 +105,12 @@ pub enum InstructionData { 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, arg: Value, imm: Imm64, }, - BinaryOverflow { opcode: Opcode, args: [Value; 2] }, Ternary { opcode: Opcode, args: [Value; 3] }, MultiAry { opcode: Opcode, args: ValueList }, InsertLane { diff --git a/lib/cretonne/src/verifier.rs b/lib/cretonne/src/verifier.rs index ba2f03ec9d..ee78a07501 100644 --- a/lib/cretonne/src/verifier.rs +++ b/lib/cretonne/src/verifier.rs @@ -255,10 +255,8 @@ impl<'a> Verifier<'a> { &UnaryImm { .. } | &UnaryIeee32 { .. } | &UnaryIeee64 { .. } | - &UnarySplit { .. } | &Binary { .. } | &BinaryImm { .. } | - &BinaryOverflow { .. } | &Ternary { .. } | &InsertLane { .. } | &ExtractLane { .. } | diff --git a/lib/cretonne/src/write.rs b/lib/cretonne/src/write.rs index 09e5ee6641..fcfb843c0c 100644 --- a/lib/cretonne/src/write.rs +++ b/lib/cretonne/src/write.rs @@ -245,10 +245,8 @@ pub fn write_operands(w: &mut Write, dfg: &DataFlowGraph, inst: Inst) -> Result UnaryImm { imm, .. } => write!(w, " {}", imm), UnaryIeee32 { imm, .. } => write!(w, " {}", imm), UnaryIeee64 { imm, .. } => write!(w, " {}", imm), - UnarySplit { arg, .. } => write!(w, " {}", arg), Binary { args, .. } => write!(w, " {}, {}", args[0], args[1]), BinaryImm { arg, imm, .. } => write!(w, " {}, {}", arg, imm), - BinaryOverflow { args, .. } => write!(w, " {}, {}", args[0], args[1]), Ternary { args, .. } => write!(w, " {}, {}, {}", args[0], args[1], args[2]), MultiAry { ref args, .. } => { if args.is_empty() { diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index ac2754a46c..f133732e8e 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -1429,12 +1429,6 @@ impl<'a> Parser<'a> { imm: self.match_ieee64("expected immediate 64-bit float operand")?, } } - InstructionFormat::UnarySplit => { - InstructionData::UnarySplit { - opcode: opcode, - arg: self.match_value("expected SSA value operand")?, - } - } InstructionFormat::Binary => { let lhs = self.match_value("expected SSA value first operand")?; self.match_token(Token::Comma, "expected ',' between operands")?; @@ -1454,15 +1448,6 @@ impl<'a> Parser<'a> { imm: rhs, } } - InstructionFormat::BinaryOverflow => { - let lhs = self.match_value("expected SSA value first operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let rhs = self.match_value("expected SSA value second operand")?; - InstructionData::BinaryOverflow { - opcode: opcode, - args: [lhs, rhs], - } - } InstructionFormat::Ternary => { // Names here refer to the `select` instruction. // This format is also use by `fma`.