From cdb4cce3dc9dae1108efd9c02035c86992b49a88 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 10 Mar 2017 10:38:38 -0800 Subject: [PATCH] Change index domain for typevar_operand. An instruction format is now seen as having two separate operand lists: immediates and values. Change InstructionFormat.typevar_operand to be a pure index into the value list. --- lib/cretonne/meta/cdsl/formats.py | 16 +++++++++------- lib/cretonne/meta/cdsl/instructions.py | 3 ++- lib/cretonne/meta/gen_instr.py | 12 ++++++------ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/cretonne/meta/cdsl/formats.py b/lib/cretonne/meta/cdsl/formats.py index 088461d1d2..4b7d512ff1 100644 --- a/lib/cretonne/meta/cdsl/formats.py +++ b/lib/cretonne/meta/cdsl/formats.py @@ -39,9 +39,10 @@ class InstructionFormat(object): :param boxed_storage: Set to `True` is this instruction format requires a `data: Box<...>` pointer to additional storage in its `InstructionData` variant. - :param typevar_operand: Index of the input operand that is used to infer - the controlling type variable. By default, this is the first `value` - operand. + :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, kind, kind, ...) -> InstructionFormat @@ -76,11 +77,12 @@ class InstructionFormat(object): # The typevar_operand argument must point to a 'value' operand. self.typevar_operand = kwargs.get('typevar_operand', None) # type: int if self.typevar_operand is not None: - assert self.kinds[self.typevar_operand] is VALUE, \ - "typevar_operand must indicate a 'value' operand" - elif len(self.value_operands) > 0: + if not self.has_value_list: + assert self.typevar_operand < self.num_value_operands, \ + "typevar_operand must indicate a 'value' operand" + elif self.num_value_operands != 0: # Default to the first 'value' operand, if there is one. - self.typevar_operand = self.value_operands[0] + self.typevar_operand = 0 # Compute a signature for the global registry. sig = (self.multiple_results, self.kinds) diff --git a/lib/cretonne/meta/cdsl/instructions.py b/lib/cretonne/meta/cdsl/instructions.py index 861e6f0883..85581edde2 100644 --- a/lib/cretonne/meta/cdsl/instructions.py +++ b/lib/cretonne/meta/cdsl/instructions.py @@ -168,7 +168,8 @@ class Instruction(object): typevar_error = None if self.format.typevar_operand is not None: try: - tv = self.ins[self.format.typevar_operand].typevar + opnum = self.value_opnums[self.format.typevar_operand] + tv = self.ins[opnum].typevar if tv is tv.free_typevar(): self.other_typevars = self._verify_ctrl_typevar(tv) self.ctrl_typevar = tv diff --git a/lib/cretonne/meta/gen_instr.py b/lib/cretonne/meta/gen_instr.py index b9e46172d7..567cfa16f6 100644 --- a/lib/cretonne/meta/gen_instr.py +++ b/lib/cretonne/meta/gen_instr.py @@ -197,7 +197,7 @@ def gen_instruction_data_impl(fmt): fmt.line(n + ' { .. } => None,') elif f.has_value_list: # We keep all arguments in a value list. - i = f.value_operands.index(f.typevar_operand) + i = f.typevar_operand fmt.line( '{} {{ ref args, .. }} => ' 'args.get({}, pool),'.format(n, i)) @@ -211,9 +211,7 @@ def gen_instruction_data_impl(fmt): else: # We have multiple value operands and an array `args`. # Which `args` index to use? - # Map from index into f.kinds into f.value_operands - # index. - i = f.value_operands.index(f.typevar_operand) + i = f.typevar_operand if f.boxed_storage: fmt.line( n + @@ -280,9 +278,10 @@ def gen_opcodes(groups, fmt): # Document polymorphism. if i.is_polymorphic: if i.use_typevar_operand: + opnum = i.value_opnums[i.format.typevar_operand] fmt.doc_comment( 'Type inferred from {}.' - .format(i.ins[i.format.typevar_operand])) + .format(i.ins[opnum])) # Enum variant itself. if is_first_opcode: fmt.line(i.camel_name + ' = 1,') @@ -612,9 +611,10 @@ def gen_inst_builder(inst, fmt): args.append('types::VOID') elif inst.is_polymorphic: # Infer the controlling type variable from the input operands. + opnum = inst.value_opnums[inst.format.typevar_operand] fmt.line( 'let ctrl_typevar = self.data_flow_graph().value_type({});' - .format(inst.ins[inst.format.typevar_operand].name)) + .format(inst.ins[opnum].name)) if inst.format.multiple_results: # The format constructor will resolve the result types from the # type var.