mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-16 09:00:05 +01:00
Changing operand matching for class operand style
This commit is contained in:
@@ -320,13 +320,15 @@ class MachineModel(object):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_full_instruction_name(instruction_form):
|
def get_full_instruction_name(instruction_form):
|
||||||
"""Get one instruction name string including the mnemonic and all operands."""
|
"""Get one instruction name string including the mnemonic and all operands."""
|
||||||
|
if instruction_form==None:
|
||||||
|
return ""
|
||||||
operands = []
|
operands = []
|
||||||
for op in instruction_form.operands:
|
for op in instruction_form["operands"]:
|
||||||
op_attrs = [
|
op_attrs = [
|
||||||
y + ":" + str(op[y])
|
"name:" + op.name
|
||||||
for y in list(filter(lambda x: True if x != "class" else False, op))
|
#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))
|
return "{} {}".format(instruction_form["name"].lower(), ",".join(operands))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -595,53 +597,53 @@ class MachineModel(object):
|
|||||||
|
|
||||||
def _check_AArch64_operands(self, i_operand, operand):
|
def _check_AArch64_operands(self, i_operand, operand):
|
||||||
"""Check if the types of operand ``i_operand`` and ``operand`` match."""
|
"""Check if the types of operand ``i_operand`` and ``operand`` match."""
|
||||||
if "class" in operand:
|
#if "class" in operand:
|
||||||
# compare two DB entries
|
# compare two DB entries
|
||||||
return self._compare_db_entries(i_operand, operand)
|
# return self._compare_db_entries(i_operand, operand)
|
||||||
# TODO support class wildcards
|
# TODO support class wildcards
|
||||||
# register
|
# register
|
||||||
if "register" in operand:
|
if isinstance(operand, RegisterOperand):
|
||||||
if i_operand["class"] != "register":
|
if not isinstance(i_operand, RegisterOperand):
|
||||||
return False
|
return False
|
||||||
return self._is_AArch64_reg_type(i_operand, operand["register"])
|
return self._is_AArch64_reg_type(i_operand, operand)
|
||||||
# memory
|
# memory
|
||||||
if "memory" in operand:
|
if isinstance(operand, MemoryOperand):
|
||||||
if i_operand["class"] != "memory":
|
if not isinstance(i_operand, MemoryOperand):
|
||||||
return False
|
return False
|
||||||
return self._is_AArch64_mem_type(i_operand, operand["memory"])
|
return self._is_AArch64_mem_type(i_operand, operand)
|
||||||
# immediate
|
# immediate
|
||||||
if i_operand["class"] == "immediate" and i_operand["imd"] == self.WILDCARD:
|
if isinstance(i_operand, ImmediateOperand) and i_operand.type == self.WILDCARD:
|
||||||
return "value" in operand or (
|
return "value" in operand.value or (
|
||||||
"immediate" in operand and "value" in operand["immediate"]
|
"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 (
|
return ("value" in operand and operand.get("type", None) == "int") or (
|
||||||
"immediate" in operand
|
"immediate" in operand
|
||||||
and "value" in operand["immediate"]
|
and "value" in operand["immediate"]
|
||||||
and operand["immediate"].get("type", None) == "int"
|
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 (
|
return ("float" in operand and operand.get("type", None) == "float") or (
|
||||||
"immediate" in operand
|
"immediate" in operand
|
||||||
and "float" in operand["immediate"]
|
and "float" in operand["immediate"]
|
||||||
and operand["immediate"].get("type", None) == "float"
|
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 (
|
return ("double" in operand and operand.get("type", None) == "double") or (
|
||||||
"immediate" in operand
|
"immediate" in operand
|
||||||
and "double" in operand["immediate"]
|
and "double" in operand["immediate"]
|
||||||
and operand["immediate"].get("type", None) == "double"
|
and operand["immediate"].get("type", None) == "double"
|
||||||
)
|
)
|
||||||
# identifier
|
# identifier
|
||||||
if "identifier" in operand or (
|
if isinstance(operand, IdentifierOperand) or (
|
||||||
"immediate" in operand and "identifier" in operand["immediate"]
|
isinstance(operand, ImmediateOperand) and isinstance(operand, IdentifierOperand)
|
||||||
):
|
):
|
||||||
return i_operand["class"] == "identifier"
|
return i_operand["class"] == "identifier"
|
||||||
# prefetch option
|
# prefetch option
|
||||||
if "prfop" in operand:
|
if not isinstance(operand, Operand) and "prfop" in operand:
|
||||||
return i_operand["class"] == "prfop"
|
return i_operand["class"] == "prfop"
|
||||||
# condition
|
# condition
|
||||||
if "condition" in operand:
|
if not isinstance(operand, Operand) and "condition" in operand:
|
||||||
if i_operand["ccode"] == self.WILDCARD:
|
if i_operand["ccode"] == self.WILDCARD:
|
||||||
return True
|
return True
|
||||||
return i_operand["class"] == "condition" and (
|
return i_operand["class"] == "condition" and (
|
||||||
@@ -698,27 +700,27 @@ class MachineModel(object):
|
|||||||
def _is_AArch64_reg_type(self, i_reg, reg):
|
def _is_AArch64_reg_type(self, i_reg, reg):
|
||||||
"""Check if register type match."""
|
"""Check if register type match."""
|
||||||
# check for wildcards
|
# check for wildcards
|
||||||
if reg["prefix"] == self.WILDCARD or i_reg["prefix"] == self.WILDCARD:
|
if reg.prefix == self.WILDCARD or i_reg.prefix == self.WILDCARD:
|
||||||
if "shape" in reg:
|
if reg.shape!=None:
|
||||||
if "shape" in i_reg and (
|
if i_reg.shape!=None and (
|
||||||
reg["shape"] == i_reg["shape"]
|
reg.shape == i_reg.shape
|
||||||
or self.WILDCARD in (reg["shape"] + i_reg["shape"])
|
or self.WILDCARD in (reg.shape + i_reg.shape)
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
# check for prefix and shape
|
# check for prefix and shape
|
||||||
if reg["prefix"] != i_reg["prefix"]:
|
if reg.prefix != i_reg.prefix:
|
||||||
return False
|
return False
|
||||||
if "shape" in reg:
|
if reg.shape!=None:
|
||||||
if "shape" in i_reg and (
|
if i_reg.shape!=None and (
|
||||||
reg["shape"] == i_reg["shape"] or self.WILDCARD in (reg["shape"] + i_reg["shape"])
|
reg.shape == i_reg.shape or self.WILDCARD in (reg.shape + i_reg.shape)
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
if "lanes" in reg:
|
if reg.lanes!=None:
|
||||||
if "lanes" in i_reg and (
|
if i_reg.lanes!=None and (
|
||||||
reg["lanes"] == i_reg["lanes"] or self.WILDCARD in (reg["lanes"] + i_reg["lanes"])
|
reg.lanes == i_reg.lanes or self.WILDCARD in (reg.lanes + i_reg.lanes)
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@@ -735,6 +737,8 @@ class MachineModel(object):
|
|||||||
else:
|
else:
|
||||||
i_reg_name = i_reg
|
i_reg_name = i_reg
|
||||||
# check for wildcards
|
# check for wildcards
|
||||||
|
if isinstance(reg,str):
|
||||||
|
return False
|
||||||
if i_reg_name == self.WILDCARD or reg.name == self.WILDCARD:
|
if i_reg_name == self.WILDCARD or reg.name == self.WILDCARD:
|
||||||
return True
|
return True
|
||||||
# differentiate between vector registers (mm, xmm, ymm, zmm) and others (gpr)
|
# 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)
|
(mem.base is None and i_mem.base is None)
|
||||||
or i_mem.base == self.WILDCARD
|
or i_mem.base == self.WILDCARD
|
||||||
or mem.base["prefix"] == i_mem.base
|
or mem.base.prefix == i_mem.base
|
||||||
)
|
)
|
||||||
# check offset
|
# check offset
|
||||||
and (
|
and (
|
||||||
@@ -799,8 +803,8 @@ class MachineModel(object):
|
|||||||
or i_mem.index == self.WILDCARD
|
or i_mem.index == self.WILDCARD
|
||||||
or (
|
or (
|
||||||
mem.index is not None
|
mem.index is not None
|
||||||
and mem["index"].prefix != None
|
and mem.index.prefix != None
|
||||||
and mem.index["prefix"] == i_mem.index
|
and mem.index.prefix == i_mem.index
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# check scale
|
# check scale
|
||||||
@@ -811,12 +815,12 @@ class MachineModel(object):
|
|||||||
)
|
)
|
||||||
# check pre-indexing
|
# check pre-indexing
|
||||||
and (
|
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
|
# check post-indexing
|
||||||
and (
|
and (
|
||||||
i_mem.post - indexed == self.WILDCARD
|
i_mem.post_indexed == self.WILDCARD
|
||||||
or (mem.post - indexed) == (i_mem.post - indexed)
|
or (mem.post_indexed) == (i_mem.post_indexed)
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
@@ -856,7 +860,7 @@ class MachineModel(object):
|
|||||||
or i_mem.index == self.WILDCARD
|
or i_mem.index == self.WILDCARD
|
||||||
or (
|
or (
|
||||||
mem.index is not None
|
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)
|
and self._is_x86_reg_type(i_mem.index, mem.index)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -182,19 +182,19 @@ class ISASemantics(object):
|
|||||||
isa_data = self._isa_model.get_instruction(
|
isa_data = self._isa_model.get_instruction(
|
||||||
instruction_form.instruction[:suffix_start], instruction_form.operands
|
instruction_form.instruction[:suffix_start], instruction_form.operands
|
||||||
)
|
)
|
||||||
"""
|
|
||||||
if only_postindexed:
|
if only_postindexed:
|
||||||
for o in instruction_form.operands:
|
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
|
base_name = o.base.prefix if o.base.prefix!=None else "" + o.base.name
|
||||||
return {
|
return {
|
||||||
base_name: {
|
base_name: {
|
||||||
"name": o.base.prefix if o.base.prefix!=None else "" + o.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 {}
|
return {}
|
||||||
"""
|
|
||||||
reg_operand_names = {} # e.g., {'rax': 'op1'}
|
reg_operand_names = {} # e.g., {'rax': 'op1'}
|
||||||
operand_state = {} # e.g., {'op1': {'name': 'rax', 'value': 0}} 0 means unchanged
|
operand_state = {} # e.g., {'op1': {'name': 'rax', 'value': 0}} 0 means unchanged
|
||||||
|
|
||||||
@@ -253,13 +253,12 @@ class ISASemantics(object):
|
|||||||
op_dict["destination"] += operands
|
op_dict["destination"] += operands
|
||||||
if "hidden_operands" in isa_data:
|
if "hidden_operands" in isa_data:
|
||||||
op_dict["destination"] += [
|
op_dict["destination"] += [
|
||||||
AttrDict.convert_dict(
|
|
||||||
{
|
{
|
||||||
hop["class"]: {
|
hop["class"]: {
|
||||||
k: hop[k] for k in ["name", "class", "source", "destination"]
|
k: hop[k] for k in ["name", "class", "source", "destination"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
|
||||||
for hop in isa_data["hidden_operands"]
|
for hop in isa_data["hidden_operands"]
|
||||||
]
|
]
|
||||||
return op_dict
|
return op_dict
|
||||||
@@ -267,6 +266,7 @@ class ISASemantics(object):
|
|||||||
for i, op in enumerate(isa_data["operands"]):
|
for i, op in enumerate(isa_data["operands"]):
|
||||||
if isinstance(op, RegisterOperand):
|
if isinstance(op, RegisterOperand):
|
||||||
continue
|
continue
|
||||||
|
'''
|
||||||
if op["source"] and op["destination"]:
|
if op["source"] and op["destination"]:
|
||||||
op_dict["src_dst"].append(operands[i])
|
op_dict["src_dst"].append(operands[i])
|
||||||
continue
|
continue
|
||||||
@@ -276,6 +276,7 @@ class ISASemantics(object):
|
|||||||
if op["destination"]:
|
if op["destination"]:
|
||||||
op_dict["destination"].append(operands[i])
|
op_dict["destination"].append(operands[i])
|
||||||
continue
|
continue
|
||||||
|
'''
|
||||||
# check for hidden operands like flags or registers
|
# check for hidden operands like flags or registers
|
||||||
if "hidden_operands" in isa_data:
|
if "hidden_operands" in isa_data:
|
||||||
# add operand(s) to semantic_operands of instruction form
|
# add operand(s) to semantic_operands of instruction form
|
||||||
|
|||||||
@@ -443,8 +443,8 @@ class KernelDG(nx.DiGraph):
|
|||||||
continue
|
continue
|
||||||
if mem.index and src.index:
|
if mem.index and src.index:
|
||||||
index_change = register_changes.get(
|
index_change = register_changes.get(
|
||||||
src.index.get("prefix", "") + src.index.name,
|
src.index.prefix if src.index.prefix!=None else "" + src.index.name,
|
||||||
{"name": src.index.get("prefix", "") + src.index.name, "value": 0},
|
{"name": src.index.prefix if src.index.prefix!=None else "" + src.index.name, "value": 0},
|
||||||
)
|
)
|
||||||
if index_change is None:
|
if index_change is None:
|
||||||
# Unknown change occurred
|
# Unknown change occurred
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
ArchSemantics(tmp_mm)
|
ArchSemantics(tmp_mm)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.fail()
|
self.fail()
|
||||||
"""
|
|
||||||
def test_machine_model_various_functions(self):
|
def test_machine_model_various_functions(self):
|
||||||
# check dummy MachineModel creation
|
# check dummy MachineModel creation
|
||||||
try:
|
try:
|
||||||
@@ -173,7 +173,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [{"class": "identifier"}]),
|
test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [{"class": "identifier"}]),
|
||||||
test_mm_arm.get_instruction("b.someOtherName", [{"class": "identifier"}]),
|
test_mm_arm.get_instruction("b.someOtherName", [{"class": "identifier"}]),
|
||||||
)
|
)
|
||||||
|
|
||||||
# test full instruction name
|
# test full instruction name
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
MachineModel.get_full_instruction_name(instr_form_x86_1),
|
MachineModel.get_full_instruction_name(instr_form_x86_1),
|
||||||
@@ -185,14 +185,12 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
"fadd register(prefix:v,shape:s),register(prefix:v,shape:s),"
|
"fadd register(prefix:v,shape:s),register(prefix:v,shape:s),"
|
||||||
+ "register(prefix:v,shape:s)",
|
+ "register(prefix:v,shape:s)",
|
||||||
)
|
)
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
# test get_store_tp
|
# test get_store_tp
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
test_mm_x86.get_store_throughput(
|
test_mm_x86.get_store_throughput(
|
||||||
MemoryOperand(BASE_ID=RegisterOperand(NAME_ID="x"), OFFSET_ID=None,INDEX_ID=None,SCALE_ID="1")
|
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"]],
|
[[2, "237"], [2, "4"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -248,7 +246,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
with open("/dev/null", "w") as dev_null:
|
with open("/dev/null", "w") as dev_null:
|
||||||
test_mm_x86.dump(stream=dev_null)
|
test_mm_x86.dump(stream=dev_null)
|
||||||
test_mm_arm.dump(stream=dev_null)
|
test_mm_arm.dump(stream=dev_null)
|
||||||
"""
|
|
||||||
|
|
||||||
def test_src_dst_assignment_x86(self):
|
def test_src_dst_assignment_x86(self):
|
||||||
for instruction_form in self.kernel_x86:
|
for instruction_form in self.kernel_x86:
|
||||||
@@ -286,7 +284,6 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.assertIsInstance(instruction_form.port_pressure, list)
|
self.assertIsInstance(instruction_form.port_pressure, list)
|
||||||
self.assertEqual(len(instruction_form.port_pressure), port_num)
|
self.assertEqual(len(instruction_form.port_pressure), port_num)
|
||||||
|
|
||||||
"""
|
|
||||||
def test_optimal_throughput_assignment(self):
|
def test_optimal_throughput_assignment(self):
|
||||||
# x86
|
# x86
|
||||||
kernel_fixed = deepcopy(self.kernel_x86)
|
kernel_fixed = deepcopy(self.kernel_x86)
|
||||||
@@ -396,7 +393,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
dg.get_dependent_instruction_forms()
|
dg.get_dependent_instruction_forms()
|
||||||
# test dot creation
|
# test dot creation
|
||||||
dg.export_graph(filepath="/dev/null")
|
dg.export_graph(filepath="/dev/null")
|
||||||
"""
|
|
||||||
|
|
||||||
def test_kernelDG_SVE(self):
|
def test_kernelDG_SVE(self):
|
||||||
KernelDG(
|
KernelDG(
|
||||||
@@ -438,7 +435,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
with self.assertRaises(NotImplementedError):
|
with self.assertRaises(NotImplementedError):
|
||||||
dg.get_loopcarried_dependencies()
|
dg.get_loopcarried_dependencies()
|
||||||
|
|
||||||
"""
|
|
||||||
def test_loop_carried_dependency_aarch64(self):
|
def test_loop_carried_dependency_aarch64(self):
|
||||||
dg = KernelDG(
|
dg = KernelDG(
|
||||||
self.kernel_aarch64_memdep,
|
self.kernel_aarch64_memdep,
|
||||||
@@ -540,7 +537,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.assertTrue(time_10 > 10)
|
self.assertTrue(time_10 > 10)
|
||||||
self.assertTrue(2 < time_2)
|
self.assertTrue(2 < time_2)
|
||||||
self.assertTrue(time_2 < (time_10 - 7))
|
self.assertTrue(time_2 < (time_10 - 7))
|
||||||
"""
|
|
||||||
|
|
||||||
def test_is_read_is_written_x86(self):
|
def test_is_read_is_written_x86(self):
|
||||||
# independent form HW model
|
# independent form HW model
|
||||||
|
|||||||
Reference in New Issue
Block a user