Change InstBuilder low-level format constructor signatures.
The per-instruction format low-level constructors in InstBuilder should be independent of the relative ordering of value and immediate operands in order to prepare for the future instruction format merger. Reorder their arguments such that all the immediate operands are placed before the value operands. For instruction formats that use a value list representation, just take a single ValueList argument. The value lists are created by the individual instruction constructors. This means that the format constructor doesn't care how many of the instructions operands are 'fixed' and how many are 'variable' arguments.
This commit is contained in:
@@ -158,6 +158,13 @@ class Operand(object):
|
|||||||
"""
|
"""
|
||||||
return self.kind is VALUE
|
return self.kind is VALUE
|
||||||
|
|
||||||
|
def is_varargs(self):
|
||||||
|
# type: () -> bool
|
||||||
|
"""
|
||||||
|
Is this a VARIABLE_ARGS operand?
|
||||||
|
"""
|
||||||
|
return self.kind is VARIABLE_ARGS
|
||||||
|
|
||||||
def is_immediate(self):
|
def is_immediate(self):
|
||||||
# type: () -> bool
|
# type: () -> bool
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import constant_hash
|
|||||||
from unique_table import UniqueTable, UniqueSeqTable
|
from unique_table import UniqueTable, UniqueSeqTable
|
||||||
from cdsl import camel_case
|
from cdsl import camel_case
|
||||||
from cdsl.operands import ImmediateKind
|
from cdsl.operands import ImmediateKind
|
||||||
import cdsl.types
|
|
||||||
from cdsl.formats import InstructionFormat
|
from cdsl.formats import InstructionFormat
|
||||||
|
|
||||||
from cdsl.instructions import Instruction # noqa
|
from cdsl.instructions import Instruction # noqa
|
||||||
@@ -477,11 +476,7 @@ def gen_format_constructor(iform, fmt):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Construct method arguments.
|
# Construct method arguments.
|
||||||
if iform.has_value_list:
|
args = ['self', 'opcode: Opcode']
|
||||||
args = ['mut self']
|
|
||||||
else:
|
|
||||||
args = ['self']
|
|
||||||
args.append('opcode: Opcode')
|
|
||||||
|
|
||||||
if iform.multiple_results:
|
if iform.multiple_results:
|
||||||
args.append('ctrl_typevar: Type')
|
args.append('ctrl_typevar: Type')
|
||||||
@@ -491,9 +486,18 @@ def gen_format_constructor(iform, fmt):
|
|||||||
args.append('result_type: Type')
|
args.append('result_type: Type')
|
||||||
result_type = 'result_type'
|
result_type = 'result_type'
|
||||||
|
|
||||||
# Normal operand arguments.
|
# Normal operand arguments. Start with the immediate operands.
|
||||||
for idx, kind in enumerate(iform.kinds):
|
for kind, name in zip(iform.imm_kinds, iform.imm_members):
|
||||||
args.append('op{}: {}'.format(idx, kind.rust_type))
|
args.append('{}: {}'.format(name, kind.rust_type))
|
||||||
|
# Then the value operands.
|
||||||
|
if iform.has_value_list:
|
||||||
|
# Take all value arguments as a finished value list. The value lists
|
||||||
|
# are created by the individual instruction constructors.
|
||||||
|
args.append('args: ValueList')
|
||||||
|
else:
|
||||||
|
# Take a fixed number of value operands.
|
||||||
|
for i in range(iform.num_value_operands):
|
||||||
|
args.append('arg{}: Value'.format(i))
|
||||||
|
|
||||||
proto = '{}({})'.format(iform.name, ', '.join(args))
|
proto = '{}({})'.format(iform.name, ', '.join(args))
|
||||||
proto += " -> (Inst, &'f mut DataFlowGraph)"
|
proto += " -> (Inst, &'f mut DataFlowGraph)"
|
||||||
@@ -501,21 +505,6 @@ def gen_format_constructor(iform, fmt):
|
|||||||
fmt.doc_comment(str(iform))
|
fmt.doc_comment(str(iform))
|
||||||
fmt.line('#[allow(non_snake_case)]')
|
fmt.line('#[allow(non_snake_case)]')
|
||||||
with fmt.indented('fn {} {{'.format(proto), '}'):
|
with fmt.indented('fn {} {{'.format(proto), '}'):
|
||||||
# Start by constructing a value list with *all* the arguments.
|
|
||||||
if iform.has_value_list:
|
|
||||||
fmt.line('let mut vlist = ValueList::default();')
|
|
||||||
with fmt.indented('{', '}'):
|
|
||||||
fmt.line(
|
|
||||||
'let pool = '
|
|
||||||
'&mut self.data_flow_graph_mut().value_lists;')
|
|
||||||
for idx, kind in enumerate(iform.kinds):
|
|
||||||
if kind is cdsl.operands.VALUE:
|
|
||||||
fmt.line('vlist.push(op{}, pool);'.format(idx))
|
|
||||||
elif kind is cdsl.operands.VARIABLE_ARGS:
|
|
||||||
fmt.line(
|
|
||||||
'vlist.extend(op{}.iter().cloned(), pool);'
|
|
||||||
.format(idx))
|
|
||||||
|
|
||||||
# Generate the instruction data.
|
# Generate the instruction data.
|
||||||
with fmt.indented(
|
with fmt.indented(
|
||||||
'let data = InstructionData::{} {{'.format(iform.name), '};'):
|
'let data = InstructionData::{} {{'.format(iform.name), '};'):
|
||||||
@@ -543,20 +532,19 @@ def gen_member_inits(iform, fmt):
|
|||||||
Emit member initializers for an `iform` instruction.
|
Emit member initializers for an `iform` instruction.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Values first.
|
# Immediate operands.
|
||||||
if iform.has_value_list:
|
# We have local variables with the same names as the members.
|
||||||
# Value-list formats put *all* arguments in the list.
|
for member in iform.imm_members:
|
||||||
fmt.line('args: vlist,')
|
fmt.line('{}: {},'.format(member, member))
|
||||||
elif iform.num_value_operands == 1:
|
|
||||||
fmt.line('arg: op{},'.format(iform.value_operands[0]))
|
|
||||||
elif iform.num_value_operands > 1:
|
|
||||||
fmt.line('args: [{}],'.format(
|
|
||||||
', '.join('op{}'.format(i) for i in iform.value_operands)))
|
|
||||||
|
|
||||||
# Immediates and entity references.
|
# Value operands.
|
||||||
for idx, member in enumerate(iform.members):
|
if iform.has_value_list:
|
||||||
if member:
|
fmt.line('args: args,')
|
||||||
fmt.line('{}: op{},'.format(member, idx))
|
elif iform.num_value_operands == 1:
|
||||||
|
fmt.line('arg: arg0,')
|
||||||
|
elif iform.num_value_operands > 1:
|
||||||
|
args = ('arg{}'.format(i) for i in range(iform.num_value_operands))
|
||||||
|
fmt.line('args: [{}],'.format(', '.join(args)))
|
||||||
|
|
||||||
|
|
||||||
def gen_inst_builder(inst, fmt):
|
def gen_inst_builder(inst, fmt):
|
||||||
@@ -570,6 +558,9 @@ def gen_inst_builder(inst, fmt):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Construct method arguments.
|
# Construct method arguments.
|
||||||
|
if inst.format.has_value_list:
|
||||||
|
args = ['mut self']
|
||||||
|
else:
|
||||||
args = ['self']
|
args = ['self']
|
||||||
|
|
||||||
# The controlling type variable will be inferred from the input values if
|
# The controlling type variable will be inferred from the input values if
|
||||||
@@ -645,7 +636,32 @@ def gen_inst_builder(inst, fmt):
|
|||||||
inst.outs[inst.value_results[0]]
|
inst.outs[inst.value_results[0]]
|
||||||
.typevar.singleton_type.rust_name())
|
.typevar.singleton_type.rust_name())
|
||||||
|
|
||||||
args.extend(op.name for op in inst.ins)
|
# Now add all of the immediate operands to the constructor arguments.
|
||||||
|
for opnum in inst.imm_opnums:
|
||||||
|
args.append(inst.ins[opnum].name)
|
||||||
|
|
||||||
|
# Finally, the value operands.
|
||||||
|
if inst.format.has_value_list:
|
||||||
|
# We need to build a value list with all the arguments.
|
||||||
|
fmt.line('let mut vlist = ValueList::default();')
|
||||||
|
args.append('vlist')
|
||||||
|
with fmt.indented('{', '}'):
|
||||||
|
fmt.line(
|
||||||
|
'let pool = '
|
||||||
|
'&mut self.data_flow_graph_mut().value_lists;')
|
||||||
|
for op in inst.ins:
|
||||||
|
if op.is_value():
|
||||||
|
fmt.line('vlist.push({}, pool);'.format(op.name))
|
||||||
|
elif op.is_varargs():
|
||||||
|
fmt.line(
|
||||||
|
'vlist.extend({}.iter().cloned(), pool);'
|
||||||
|
.format(op.name))
|
||||||
|
else:
|
||||||
|
# With no value list, we're guaranteed to just have a set of fixed
|
||||||
|
# value operands.
|
||||||
|
for opnum in inst.value_opnums:
|
||||||
|
args.append(inst.ins[opnum].name)
|
||||||
|
|
||||||
# Call to the format constructor,
|
# Call to the format constructor,
|
||||||
fcall = 'self.{}({})'.format(inst.format.name, ', '.join(args))
|
fcall = 'self.{}({})'.format(inst.format.name, ', '.join(args))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user