Changing operand matching for class operand style

This commit is contained in:
stefandesouza
2023-09-25 21:35:17 +02:00
parent 42f96753c1
commit db899a2709
4 changed files with 60 additions and 58 deletions

View File

@@ -320,13 +320,15 @@ class MachineModel(object):
@staticmethod
def get_full_instruction_name(instruction_form):
"""Get one instruction name string including the mnemonic and all operands."""
if instruction_form==None:
return ""
operands = []
for op in instruction_form.operands:
for op in instruction_form["operands"]:
op_attrs = [
y + ":" + str(op[y])
for y in list(filter(lambda x: True if x != "class" else False, op))
"name:" + op.name
#for y in list(filter(lambda x: True if x != "class" else False, op))
]
operands.append("{}({})".format(op["class"], ",".join(op_attrs)))
operands.append("{}({})".format("register", ",".join(op_attrs)))
return "{} {}".format(instruction_form["name"].lower(), ",".join(operands))
@staticmethod
@@ -595,53 +597,53 @@ class MachineModel(object):
def _check_AArch64_operands(self, i_operand, operand):
"""Check if the types of operand ``i_operand`` and ``operand`` match."""
if "class" in operand:
#if "class" in operand:
# compare two DB entries
return self._compare_db_entries(i_operand, operand)
# return self._compare_db_entries(i_operand, operand)
# TODO support class wildcards
# register
if "register" in operand:
if i_operand["class"] != "register":
if isinstance(operand, RegisterOperand):
if not isinstance(i_operand, RegisterOperand):
return False
return self._is_AArch64_reg_type(i_operand, operand["register"])
return self._is_AArch64_reg_type(i_operand, operand)
# memory
if "memory" in operand:
if i_operand["class"] != "memory":
if isinstance(operand, MemoryOperand):
if not isinstance(i_operand, MemoryOperand):
return False
return self._is_AArch64_mem_type(i_operand, operand["memory"])
return self._is_AArch64_mem_type(i_operand, operand)
# immediate
if i_operand["class"] == "immediate" and i_operand["imd"] == self.WILDCARD:
return "value" in operand or (
if isinstance(i_operand, ImmediateOperand) and i_operand.type == self.WILDCARD:
return "value" in operand.value or (
"immediate" in operand and "value" in operand["immediate"]
)
if i_operand["class"] == "immediate" and i_operand["imd"] == "int":
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "int":
return ("value" in operand and operand.get("type", None) == "int") or (
"immediate" in operand
and "value" in operand["immediate"]
and operand["immediate"].get("type", None) == "int"
)
if i_operand["class"] == "immediate" and i_operand["imd"] == "float":
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "float":
return ("float" in operand and operand.get("type", None) == "float") or (
"immediate" in operand
and "float" in operand["immediate"]
and operand["immediate"].get("type", None) == "float"
)
if i_operand["class"] == "immediate" and i_operand["imd"] == "double":
if isinstance(i_operand, ImmediateOperand) and i_operand.type == "double":
return ("double" in operand and operand.get("type", None) == "double") or (
"immediate" in operand
and "double" in operand["immediate"]
and operand["immediate"].get("type", None) == "double"
)
# identifier
if "identifier" in operand or (
"immediate" in operand and "identifier" in operand["immediate"]
if isinstance(operand, IdentifierOperand) or (
isinstance(operand, ImmediateOperand) and isinstance(operand, IdentifierOperand)
):
return i_operand["class"] == "identifier"
# prefetch option
if "prfop" in operand:
if not isinstance(operand, Operand) and "prfop" in operand:
return i_operand["class"] == "prfop"
# condition
if "condition" in operand:
if not isinstance(operand, Operand) and "condition" in operand:
if i_operand["ccode"] == self.WILDCARD:
return True
return i_operand["class"] == "condition" and (
@@ -698,27 +700,27 @@ class MachineModel(object):
def _is_AArch64_reg_type(self, i_reg, reg):
"""Check if register type match."""
# check for wildcards
if reg["prefix"] == self.WILDCARD or i_reg["prefix"] == self.WILDCARD:
if "shape" in reg:
if "shape" in i_reg and (
reg["shape"] == i_reg["shape"]
or self.WILDCARD in (reg["shape"] + i_reg["shape"])
if reg.prefix == self.WILDCARD or i_reg.prefix == self.WILDCARD:
if reg.shape!=None:
if i_reg.shape!=None and (
reg.shape == i_reg.shape
or self.WILDCARD in (reg.shape + i_reg.shape)
):
return True
return False
return True
# check for prefix and shape
if reg["prefix"] != i_reg["prefix"]:
if reg.prefix != i_reg.prefix:
return False
if "shape" in reg:
if "shape" in i_reg and (
reg["shape"] == i_reg["shape"] or self.WILDCARD in (reg["shape"] + i_reg["shape"])
if reg.shape!=None:
if i_reg.shape!=None and (
reg.shape == i_reg.shape or self.WILDCARD in (reg.shape + i_reg.shape)
):
return True
return False
if "lanes" in reg:
if "lanes" in i_reg and (
reg["lanes"] == i_reg["lanes"] or self.WILDCARD in (reg["lanes"] + i_reg["lanes"])
if reg.lanes!=None:
if i_reg.lanes!=None and (
reg.lanes == i_reg.lanes or self.WILDCARD in (reg.lanes + i_reg.lanes)
):
return True
return False
@@ -735,6 +737,8 @@ class MachineModel(object):
else:
i_reg_name = i_reg
# check for wildcards
if isinstance(reg,str):
return False
if i_reg_name == self.WILDCARD or reg.name == self.WILDCARD:
return True
# differentiate between vector registers (mm, xmm, ymm, zmm) and others (gpr)
@@ -780,7 +784,7 @@ class MachineModel(object):
(
(mem.base is None and i_mem.base is None)
or i_mem.base == self.WILDCARD
or mem.base["prefix"] == i_mem.base
or mem.base.prefix == i_mem.base
)
# check offset
and (
@@ -799,8 +803,8 @@ class MachineModel(object):
or i_mem.index == self.WILDCARD
or (
mem.index is not None
and mem["index"].prefix != None
and mem.index["prefix"] == i_mem.index
and mem.index.prefix != None
and mem.index.prefix == i_mem.index
)
)
# check scale
@@ -811,12 +815,12 @@ class MachineModel(object):
)
# check pre-indexing
and (
i_mem.pre - indexed == self.WILDCARD or (mempre - indexed) == (i_mem.pre - indexed)
i_mem.pre_indexed == self.WILDCARD or (mem.pre_indexed) == (i_mem.pre_indexed)
)
# check post-indexing
and (
i_mem.post - indexed == self.WILDCARD
or (mem.post - indexed) == (i_mem.post - indexed)
i_mem.post_indexed == self.WILDCARD
or (mem.post_indexed) == (i_mem.post_indexed)
)
):
return True
@@ -856,7 +860,7 @@ class MachineModel(object):
or i_mem.index == self.WILDCARD
or (
mem.index is not None
and mem.index.name != None
#and mem.index.name != None
and self._is_x86_reg_type(i_mem.index, mem.index)
)
)

View File

@@ -182,19 +182,19 @@ class ISASemantics(object):
isa_data = self._isa_model.get_instruction(
instruction_form.instruction[:suffix_start], instruction_form.operands
)
"""
if only_postindexed:
for o in instruction_form.operands:
if isinstance(o, MemoryOperand) and o.base!=None:
if isinstance(o, MemoryOperand) and o.base!=None and o.post_indexed!=False:
base_name = o.base.prefix if o.base.prefix!=None else "" + o.base.name
return {
base_name: {
"name": o.base.prefix if o.base.prefix!=None else "" + o.base.name,
"value": o.post_indexed["value"],
"value": o.post_indexed['value'],
}
}
return {}
"""
reg_operand_names = {} # e.g., {'rax': 'op1'}
operand_state = {} # e.g., {'op1': {'name': 'rax', 'value': 0}} 0 means unchanged
@@ -253,13 +253,12 @@ class ISASemantics(object):
op_dict["destination"] += operands
if "hidden_operands" in isa_data:
op_dict["destination"] += [
AttrDict.convert_dict(
{
hop["class"]: {
k: hop[k] for k in ["name", "class", "source", "destination"]
}
}
)
for hop in isa_data["hidden_operands"]
]
return op_dict
@@ -267,6 +266,7 @@ class ISASemantics(object):
for i, op in enumerate(isa_data["operands"]):
if isinstance(op, RegisterOperand):
continue
'''
if op["source"] and op["destination"]:
op_dict["src_dst"].append(operands[i])
continue
@@ -276,6 +276,7 @@ class ISASemantics(object):
if op["destination"]:
op_dict["destination"].append(operands[i])
continue
'''
# check for hidden operands like flags or registers
if "hidden_operands" in isa_data:
# add operand(s) to semantic_operands of instruction form

View File

@@ -443,8 +443,8 @@ class KernelDG(nx.DiGraph):
continue
if mem.index and src.index:
index_change = register_changes.get(
src.index.get("prefix", "") + src.index.name,
{"name": src.index.get("prefix", "") + src.index.name, "value": 0},
src.index.prefix if src.index.prefix!=None else "" + src.index.name,
{"name": src.index.prefix if src.index.prefix!=None else "" + src.index.name, "value": 0},
)
if index_change is None:
# Unknown change occurred

View File

@@ -125,7 +125,7 @@ class TestSemanticTools(unittest.TestCase):
ArchSemantics(tmp_mm)
except ValueError:
self.fail()
"""
def test_machine_model_various_functions(self):
# check dummy MachineModel creation
try:
@@ -185,14 +185,12 @@ class TestSemanticTools(unittest.TestCase):
"fadd register(prefix:v,shape:s),register(prefix:v,shape:s),"
+ "register(prefix:v,shape:s)",
)
"""
"""
# test get_store_tp
self.assertEqual(
test_mm_x86.get_store_throughput(
MemoryOperand(BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None,INDEX_ID=None,SCALE_ID="1")
)[0]["port_pressure"],
)[0].port_pressure,
[[2, "237"], [2, "4"]],
)
@@ -248,7 +246,7 @@ class TestSemanticTools(unittest.TestCase):
with open("/dev/null", "w") as dev_null:
test_mm_x86.dump(stream=dev_null)
test_mm_arm.dump(stream=dev_null)
"""
def test_src_dst_assignment_x86(self):
for instruction_form in self.kernel_x86:
@@ -286,7 +284,6 @@ class TestSemanticTools(unittest.TestCase):
self.assertIsInstance(instruction_form.port_pressure, list)
self.assertEqual(len(instruction_form.port_pressure), port_num)
"""
def test_optimal_throughput_assignment(self):
# x86
kernel_fixed = deepcopy(self.kernel_x86)
@@ -396,7 +393,7 @@ class TestSemanticTools(unittest.TestCase):
dg.get_dependent_instruction_forms()
# test dot creation
dg.export_graph(filepath="/dev/null")
"""
def test_kernelDG_SVE(self):
KernelDG(
@@ -438,7 +435,7 @@ class TestSemanticTools(unittest.TestCase):
with self.assertRaises(NotImplementedError):
dg.get_loopcarried_dependencies()
"""
def test_loop_carried_dependency_aarch64(self):
dg = KernelDG(
self.kernel_aarch64_memdep,
@@ -540,7 +537,7 @@ class TestSemanticTools(unittest.TestCase):
self.assertTrue(time_10 > 10)
self.assertTrue(2 < time_2)
self.assertTrue(time_2 < (time_10 - 7))
"""
def test_is_read_is_written_x86(self):
# independent form HW model