enhanced dynamic combine of LD and arithmetic instr

This commit is contained in:
JanLJL
2019-12-19 18:50:48 +01:00
parent dc02192d04
commit bad230fa7b
4 changed files with 94 additions and 46 deletions

View File

@@ -417,7 +417,19 @@ instruction_forms:
scale: 1 scale: 1
- class: register - class: register
name: xmm name: xmm
throughput: 1.0 throughput: 0.5
latency: 4.0 # 1*p23+1*p2D3D
port_pressure: [[1, '23'], [1, [2D, 3D]]]
- name: vmovapd
operands:
- class: memory
base: gpr
offset: ~
index: gpr
scale: 1
- class: register
name: ymm
throughput: 0.5
latency: 4.0 # 1*p23+1*p2D3D latency: 4.0 # 1*p23+1*p2D3D
port_pressure: [[1, '23'], [1, [2D, 3D]]] port_pressure: [[1, '23'], [1, [2D, 3D]]]
- name: vmovapd - name: vmovapd
@@ -429,7 +441,7 @@ instruction_forms:
scale: 1 scale: 1
- class: register - class: register
name: ymm name: ymm
throughput: 1.0 throughput: 0.5
latency: 4.0 # 1*p23+1*p2D3D latency: 4.0 # 1*p23+1*p2D3D
port_pressure: [[1, '23'], [1, [2D, 3D]]] port_pressure: [[1, '23'], [1, [2D, 3D]]]
- name: vmovapd - name: vmovapd
@@ -441,7 +453,7 @@ instruction_forms:
offset: ~ offset: ~
index: gpr index: gpr
scale: 1 scale: 1
throughput: 1.0 throughput: 0.5
latency: 4.0 # 1*p23+1*p4 latency: 4.0 # 1*p23+1*p4
port_pressure: [[1, '23'], [1, '4']] port_pressure: [[1, '23'], [1, '4']]
- name: vmovapd - name: vmovapd

View File

@@ -2632,6 +2632,13 @@ instruction_forms:
port_pressure: [[10, '0'], [4, '01'], [3, '015'], [1, '05'], [11, '1'], [1, '15'], [2, '23'], [1, '4'], [25, '5']] port_pressure: [[10, '0'], [4, '01'], [3, '015'], [1, '05'], [11, '1'], [1, '15'], [2, '23'], [1, '4'], [25, '5']]
throughput: 27.0 throughput: 27.0
uops: 58 uops: 58
- name: JA
operands:
- class: identifier
latency: 0
port_pressure: []
throughput: 0.0
uops: 1
- name: JNE - name: JNE
operands: operands:
- class: identifier - class: identifier
@@ -4196,6 +4203,16 @@ instruction_forms:
port_pressure: [[1, '015']] port_pressure: [[1, '015']]
throughput: 0.3333333333333333 throughput: 0.3333333333333333
uops: 1 uops: 1
- name: ADD
operands:
- class: register
name: gpr
- class: register
name: gpr
latency: 1
port_pressure: [[1, '015']]
throughput: 0.3333333333333333
uops: 1
- name: REX ADD - name: REX ADD
operands: operands:
- class: immediate - class: immediate

View File

@@ -135,39 +135,9 @@ class ArchSemantics(ISASemantics):
) )
if instruction_data: if instruction_data:
# instruction form in DB # instruction form in DB
throughput = instruction_data['throughput'] latency_wo_load = self._handle_instruction_found(
port_pressure = self._machine_model.average_port_pressure( instruction_data, port_number, instruction_form, flags
instruction_data['port_pressure']
) )
instruction_form['port_uops'] = instruction_data['port_pressure']
try:
assert isinstance(port_pressure, list)
assert len(port_pressure) == port_number
instruction_form['port_pressure'] = port_pressure
if sum(port_pressure) == 0 and throughput is not None:
# port pressure on all ports 0 --> not bound to a port
flags.append(INSTR_FLAGS.NOT_BOUND)
except AssertionError:
warnings.warn(
'Port pressure could not be imported correctly from database. '
+ 'Please check entry for:\n {}'.format(instruction_form)
)
instruction_form['port_pressure'] = [0.0 for i in range(port_number)]
instruction_form['port_uops'] = []
flags.append(INSTR_FLAGS.TP_UNKWN)
if throughput is None:
# assume 0 cy and mark as unknown
throughput = 0.0
flags.append(INSTR_FLAGS.TP_UNKWN)
latency = instruction_data['latency']
latency_wo_load = latency
if latency is None:
# assume 0 cy and mark as unknown
latency = 0.0
latency_wo_load = latency
flags.append(INSTR_FLAGS.LT_UNKWN)
if INSTR_FLAGS.HAS_LD in instruction_form['flags']:
flags.append(INSTR_FLAGS.LD)
else: else:
# instruction could not be found in DB # instruction could not be found in DB
assign_unknown = True assign_unknown = True
@@ -217,9 +187,9 @@ class ArchSemantics(ISASemantics):
), ),
) )
] ]
instruction_form['port_uops'] = list(chain( instruction_form['port_uops'] = list(
instruction_data_reg['port_pressure'], load_port_uops chain(instruction_data_reg['port_pressure'], load_port_uops)
)) )
if assign_unknown: if assign_unknown:
# --> mark as unknown and assume 0 cy for latency/throughput # --> mark as unknown and assume 0 cy for latency/throughput
@@ -242,12 +212,51 @@ class ArchSemantics(ISASemantics):
instruction_form['latency_cp'] = 0 instruction_form['latency_cp'] = 0
instruction_form['latency_lcd'] = 0 instruction_form['latency_lcd'] = 0
def substitute_mem_address(self, operands): def _handle_instruction_found(self, instruction_data, port_number, instruction_form, flags):
reg_ops = [op for op in operands if 'register' in op] throughput = instruction_data['throughput']
reg_type = self._parser.get_reg_type(reg_ops[0]['register']) port_pressure = self._machine_model.average_port_pressure(
return [self.convert_mem_to_reg(op, reg_type) for op in operands] instruction_data['port_pressure']
)
instruction_form['port_uops'] = instruction_data['port_pressure']
try:
assert isinstance(port_pressure, list)
assert len(port_pressure) == port_number
instruction_form['port_pressure'] = port_pressure
if sum(port_pressure) == 0 and throughput is not None:
# port pressure on all ports 0 --> not bound to a port
flags.append(INSTR_FLAGS.NOT_BOUND)
except AssertionError:
warnings.warn(
'Port pressure could not be imported correctly from database. '
+ 'Please check entry for:\n {}'.format(instruction_form)
)
instruction_form['port_pressure'] = [0.0 for i in range(port_number)]
instruction_form['port_uops'] = []
flags.append(INSTR_FLAGS.TP_UNKWN)
if throughput is None:
# assume 0 cy and mark as unknown
throughput = 0.0
flags.append(INSTR_FLAGS.TP_UNKWN)
latency = instruction_data['latency']
latency_wo_load = latency
if latency is None:
# assume 0 cy and mark as unknown
latency = 0.0
latency_wo_load = latency
flags.append(INSTR_FLAGS.LT_UNKWN)
if INSTR_FLAGS.HAS_LD in instruction_form['flags']:
flags.append(INSTR_FLAGS.LD)
return latency_wo_load
def convert_mem_to_reg(self, memory, reg_type, reg_id='0'): def substitute_mem_address(self, operands):
# reg_ops = [op for op in operands if 'register' in op]
# reg_type = self._parser.get_reg_type(reg_ops[0]['register'])
return [self._create_reg_wildcard() if 'memory' in op else op for op in operands]
def _create_reg_wildcard(self):
return {'*': '*'}
def convert_op_to_reg(self, reg_type, reg_id='0'):
if self._isa == 'x86': if self._isa == 'x86':
if reg_type == 'gpr': if reg_type == 'gpr':
register = {'register': {'name': 'r' + str(int(reg_id) + 9)}} register = {'register': {'name': 'r' + str(int(reg_id) + 9)}}

View File

@@ -347,11 +347,21 @@ class MachineModel(object):
else: else:
return False return False
def _check_operands(self, i_operands, operands): def _check_operands(self, i_operand, operand):
# check for wildcard
if '*' in operand:
if (
'class' in i_operand
and i_operand['class'] == 'register'
or 'register' in i_operand
):
return True
else:
return False
if self._data['isa'].lower() == 'aarch64': if self._data['isa'].lower() == 'aarch64':
return self._check_AArch64_operands(i_operands, operands) return self._check_AArch64_operands(i_operand, operand)
if self._data['isa'].lower() == 'x86': if self._data['isa'].lower() == 'x86':
return self._check_x86_operands(i_operands, operands) return self._check_x86_operands(i_operand, operand)
def _check_AArch64_operands(self, i_operand, operand): def _check_AArch64_operands(self, i_operand, operand):
if 'class' in operand: if 'class' in operand: