mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-16 09:00:05 +01:00
Black formatting
This commit is contained in:
@@ -16,7 +16,7 @@ class MemoryOperand(Operand):
|
|||||||
POST_INDEXED=False,
|
POST_INDEXED=False,
|
||||||
INDEXED_VAL=None,
|
INDEXED_VAL=None,
|
||||||
PORT_PRESSURE=[],
|
PORT_PRESSURE=[],
|
||||||
DST=None
|
DST=None,
|
||||||
):
|
):
|
||||||
super().__init__("memory")
|
super().__init__("memory")
|
||||||
self._OFFSET_ID = OFFSET_ID
|
self._OFFSET_ID = OFFSET_ID
|
||||||
@@ -82,7 +82,7 @@ class MemoryOperand(Operand):
|
|||||||
@dst.setter
|
@dst.setter
|
||||||
def dst(self, dst):
|
def dst(self, dst):
|
||||||
self._DST = dst
|
self._DST = dst
|
||||||
|
|
||||||
@port_pressure.setter
|
@port_pressure.setter
|
||||||
def port_pressure(self, port_pressure):
|
def port_pressure(self, port_pressure):
|
||||||
self._PORT_PRESSURE = port_pressure
|
self._PORT_PRESSURE = port_pressure
|
||||||
|
|||||||
@@ -422,7 +422,12 @@ class ParserAArch64(BaseParser):
|
|||||||
if "shift" in memory_address["index"]:
|
if "shift" in memory_address["index"]:
|
||||||
if memory_address["index"]["shift_op"].lower() in valid_shift_ops:
|
if memory_address["index"]["shift_op"].lower() in valid_shift_ops:
|
||||||
scale = 2 ** int(memory_address["index"]["shift"][0]["value"])
|
scale = 2 ** int(memory_address["index"]["shift"][0]["value"])
|
||||||
new_dict = MemoryOperand(OFFSET_ID=offset, BASE_ID=RegisterOperand(NAME_ID = base["name"], PREFIX_ID = base["prefix"]), INDEX_ID=index, SCALE_ID=scale)
|
new_dict = MemoryOperand(
|
||||||
|
OFFSET_ID=offset,
|
||||||
|
BASE_ID=RegisterOperand(NAME_ID=base["name"], PREFIX_ID=base["prefix"]),
|
||||||
|
INDEX_ID=index,
|
||||||
|
SCALE_ID=scale,
|
||||||
|
)
|
||||||
if "pre_indexed" in memory_address:
|
if "pre_indexed" in memory_address:
|
||||||
new_dict.pre_indexed = True
|
new_dict.pre_indexed = True
|
||||||
if "post_indexed" in memory_address:
|
if "post_indexed" in memory_address:
|
||||||
|
|||||||
@@ -338,10 +338,16 @@ class ParserX86ATT(BaseParser):
|
|||||||
elif offset is not None and "value" in offset:
|
elif offset is not None and "value" in offset:
|
||||||
offset["value"] = int(offset["value"], 0)
|
offset["value"] = int(offset["value"], 0)
|
||||||
if base != None:
|
if base != None:
|
||||||
baseOp = RegisterOperand(NAME_ID=base['name'],PREFIX_ID=base['prefix'] if 'prefix' in base else None)
|
baseOp = RegisterOperand(
|
||||||
|
NAME_ID=base["name"], PREFIX_ID=base["prefix"] if "prefix" in base else None
|
||||||
|
)
|
||||||
if index != None:
|
if index != None:
|
||||||
indexOp = RegisterOperand(NAME_ID=index['name'],PREFIX_ID=index['prefix'] if 'prefix' in index else None)
|
indexOp = RegisterOperand(
|
||||||
new_dict = MemoryOperand(OFFSET_ID=offset, BASE_ID=baseOp, INDEX_ID=indexOp, SCALE_ID=scale)
|
NAME_ID=index["name"], PREFIX_ID=index["prefix"] if "prefix" in index else None
|
||||||
|
)
|
||||||
|
new_dict = MemoryOperand(
|
||||||
|
OFFSET_ID=offset, BASE_ID=baseOp, INDEX_ID=indexOp, SCALE_ID=scale
|
||||||
|
)
|
||||||
# Add segmentation extension if existing
|
# Add segmentation extension if existing
|
||||||
if self.SEGMENT_EXT_ID in memory_address:
|
if self.SEGMENT_EXT_ID in memory_address:
|
||||||
new_dict.segment_ext_id = memory_address[self.SEGMENT_EXT_ID]
|
new_dict.segment_ext_id = memory_address[self.SEGMENT_EXT_ID]
|
||||||
|
|||||||
@@ -169,9 +169,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
if INSTR_FLAGS.HIDDEN_LD not in load_instr.flags
|
if INSTR_FLAGS.HIDDEN_LD not in load_instr.flags
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
load = [instr for instr in kernel if instr.line_number == min_distance_load[1]][
|
load = [instr for instr in kernel if instr.line_number == min_distance_load[1]][0]
|
||||||
0
|
|
||||||
]
|
|
||||||
# Hide load
|
# Hide load
|
||||||
load.flags += [INSTR_FLAGS.HIDDEN_LD]
|
load.flags += [INSTR_FLAGS.HIDDEN_LD]
|
||||||
load.port_pressure = self._nullify_data_ports(load.port_pressure)
|
load.port_pressure = self._nullify_data_ports(load.port_pressure)
|
||||||
@@ -263,7 +261,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
operands.index(self._create_reg_wildcard())
|
operands.index(self._create_reg_wildcard())
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
#dummy_reg = {"class": "register", "name": reg_type}
|
# dummy_reg = {"class": "register", "name": reg_type}
|
||||||
dummy_reg = RegisterOperand(NAME_ID=reg_type)
|
dummy_reg = RegisterOperand(NAME_ID=reg_type)
|
||||||
data_port_pressure = [0.0 for _ in range(port_number)]
|
data_port_pressure = [0.0 for _ in range(port_number)]
|
||||||
data_port_uops = []
|
data_port_uops = []
|
||||||
@@ -274,14 +272,14 @@ class ArchSemantics(ISASemantics):
|
|||||||
x
|
x
|
||||||
for x in instruction_form.semantic_operands["source"]
|
for x in instruction_form.semantic_operands["source"]
|
||||||
+ instruction_form.semantic_operands["src_dst"]
|
+ instruction_form.semantic_operands["src_dst"]
|
||||||
if isinstance(x,MemoryOperand)
|
if isinstance(x, MemoryOperand)
|
||||||
][0]
|
][0]
|
||||||
)
|
)
|
||||||
# if multiple options, choose based on reg type
|
# if multiple options, choose based on reg type
|
||||||
data_port_uops = [
|
data_port_uops = [
|
||||||
ldp.port_pressure
|
ldp.port_pressure
|
||||||
for ldp in load_perf_data
|
for ldp in load_perf_data
|
||||||
if ldp.dst!=None
|
if ldp.dst != None
|
||||||
and self._machine_model._check_operands(
|
and self._machine_model._check_operands(
|
||||||
dummy_reg, RegisterOperand(NAME_ID=ldp.dst)
|
dummy_reg, RegisterOperand(NAME_ID=ldp.dst)
|
||||||
)
|
)
|
||||||
@@ -305,7 +303,8 @@ class ArchSemantics(ISASemantics):
|
|||||||
+ instruction_form.semantic_operands["src_dst"]
|
+ instruction_form.semantic_operands["src_dst"]
|
||||||
)
|
)
|
||||||
store_perf_data = self._machine_model.get_store_throughput(
|
store_perf_data = self._machine_model.get_store_throughput(
|
||||||
[x for x in destinations if isinstance(x,MemoryOperand)][0], dummy_reg
|
[x for x in destinations if isinstance(x, MemoryOperand)][0],
|
||||||
|
dummy_reg,
|
||||||
)
|
)
|
||||||
st_data_port_uops = store_perf_data[0].port_pressure
|
st_data_port_uops = store_perf_data[0].port_pressure
|
||||||
|
|
||||||
@@ -454,7 +453,7 @@ class ArchSemantics(ISASemantics):
|
|||||||
else:
|
else:
|
||||||
register = RegisterOperand(NAME_ID=reg_type + reg_id)
|
register = RegisterOperand(NAME_ID=reg_type + reg_id)
|
||||||
elif self._isa == "aarch64":
|
elif self._isa == "aarch64":
|
||||||
register = RegisterOperand(NAME_ID=reg_id,PREFIX_ID=reg_type)
|
register = RegisterOperand(NAME_ID=reg_id, PREFIX_ID=reg_type)
|
||||||
return register
|
return register
|
||||||
|
|
||||||
def _nullify_data_ports(self, port_pressure):
|
def _nullify_data_ports(self, port_pressure):
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from osaca.parser.register import RegisterOperand
|
|||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import ImmediateOperand
|
||||||
from osaca.parser.identifier import IdentifierOperand
|
from osaca.parser.identifier import IdentifierOperand
|
||||||
|
|
||||||
|
|
||||||
class MachineModel(object):
|
class MachineModel(object):
|
||||||
WILDCARD = "*"
|
WILDCARD = "*"
|
||||||
INTERNAL_VERSION = 1 # increase whenever self._data format changes to invalidate cache!
|
INTERNAL_VERSION = 1 # increase whenever self._data format changes to invalidate cache!
|
||||||
@@ -102,32 +103,55 @@ class MachineModel(object):
|
|||||||
self._data["instruction_forms_dict"] = defaultdict(list)
|
self._data["instruction_forms_dict"] = defaultdict(list)
|
||||||
for iform in self._data["instruction_forms"]:
|
for iform in self._data["instruction_forms"]:
|
||||||
iform["name"] = iform["name"].upper()
|
iform["name"] = iform["name"].upper()
|
||||||
if iform["operands"]!=[]:
|
if iform["operands"] != []:
|
||||||
new_operands =[]
|
new_operands = []
|
||||||
for o in iform["operands"]:
|
for o in iform["operands"]:
|
||||||
if o["class"] == "register":
|
if o["class"] == "register":
|
||||||
new_operands.append(RegisterOperand(NAME_ID=o["name"] if "name" in o else None,
|
new_operands.append(
|
||||||
PREFIX_ID=o["prefix"] if "prefix" in o else None,
|
RegisterOperand(
|
||||||
MASK=o["mask"] if "mask" in o else False)
|
NAME_ID=o["name"] if "name" in o else None,
|
||||||
)
|
PREFIX_ID=o["prefix"] if "prefix" in o else None,
|
||||||
|
MASK=o["mask"] if "mask" in o else False,
|
||||||
|
)
|
||||||
|
)
|
||||||
elif o["class"] == "memory":
|
elif o["class"] == "memory":
|
||||||
new_operands.append(MemoryOperand(BASE_ID=o["base"],
|
new_operands.append(
|
||||||
OFFSET_ID=o["offset"],
|
MemoryOperand(
|
||||||
INDEX_ID=o["index"],
|
BASE_ID=o["base"],
|
||||||
SCALE_ID=o["scale"])
|
OFFSET_ID=o["offset"],
|
||||||
)
|
INDEX_ID=o["index"],
|
||||||
|
SCALE_ID=o["scale"],
|
||||||
|
)
|
||||||
|
)
|
||||||
iform["operands"] = new_operands
|
iform["operands"] = new_operands
|
||||||
self._data["instruction_forms_dict"][iform["name"]].append(iform)
|
self._data["instruction_forms_dict"][iform["name"]].append(iform)
|
||||||
new_throughputs =[]
|
new_throughputs = []
|
||||||
if 'load_throughput' in self._data:
|
if "load_throughput" in self._data:
|
||||||
for m in self._data["load_throughput"]:
|
for m in self._data["load_throughput"]:
|
||||||
new_throughputs.append(MemoryOperand(BASE_ID=m['base'],OFFSET_ID=m['offset'],SCALE_ID=m['scale'],INDEX_ID=m['index'],PORT_PRESSURE=m['port_pressure'],DST=m['dst'] if 'dst' in m else None))
|
new_throughputs.append(
|
||||||
|
MemoryOperand(
|
||||||
|
BASE_ID=m["base"],
|
||||||
|
OFFSET_ID=m["offset"],
|
||||||
|
SCALE_ID=m["scale"],
|
||||||
|
INDEX_ID=m["index"],
|
||||||
|
PORT_PRESSURE=m["port_pressure"],
|
||||||
|
DST=m["dst"] if "dst" in m else None,
|
||||||
|
)
|
||||||
|
)
|
||||||
self._data["load_throughput"] = new_throughputs
|
self._data["load_throughput"] = new_throughputs
|
||||||
|
|
||||||
new_throughputs =[]
|
new_throughputs = []
|
||||||
if 'store_throughput' in self._data:
|
if "store_throughput" in self._data:
|
||||||
for m in self._data["store_throughput"]:
|
for m in self._data["store_throughput"]:
|
||||||
new_throughputs.append(MemoryOperand(BASE_ID=m['base'],OFFSET_ID=m['offset'],SCALE_ID=m['scale'],INDEX_ID=m['index'],PORT_PRESSURE=m['port_pressure']))
|
new_throughputs.append(
|
||||||
|
MemoryOperand(
|
||||||
|
BASE_ID=m["base"],
|
||||||
|
OFFSET_ID=m["offset"],
|
||||||
|
SCALE_ID=m["scale"],
|
||||||
|
INDEX_ID=m["index"],
|
||||||
|
PORT_PRESSURE=m["port_pressure"],
|
||||||
|
)
|
||||||
|
)
|
||||||
self._data["store_throughput"] = new_throughputs
|
self._data["store_throughput"] = new_throughputs
|
||||||
|
|
||||||
self._data["internal_version"] = self.INTERNAL_VERSION
|
self._data["internal_version"] = self.INTERNAL_VERSION
|
||||||
@@ -491,14 +515,16 @@ class MachineModel(object):
|
|||||||
elif operand in "wxbhsdq":
|
elif operand in "wxbhsdq":
|
||||||
return RegisterOperand(PREFIX_ID=operand)
|
return RegisterOperand(PREFIX_ID=operand)
|
||||||
elif operand.startswith("v"):
|
elif operand.startswith("v"):
|
||||||
return RegisterOperand(PREFIX_ID="v",SHAPE=operand[1:2])
|
return RegisterOperand(PREFIX_ID="v", SHAPE=operand[1:2])
|
||||||
elif operand.startswith("m"):
|
elif operand.startswith("m"):
|
||||||
return MemoryOperand(BASE_ID = "x" if "b" in operand else None,
|
return MemoryOperand(
|
||||||
OFFSET_ID = "imd" if "o" in operand else None,
|
BASE_ID="x" if "b" in operand else None,
|
||||||
INDEX_ID = "gpr" if "i" in operand else None,
|
OFFSET_ID="imd" if "o" in operand else None,
|
||||||
SCALE_ID =8 if "s" in operand else 1,
|
INDEX_ID="gpr" if "i" in operand else None,
|
||||||
PRE_INDEXED = True if "r" in operand else False,
|
SCALE_ID=8 if "s" in operand else 1,
|
||||||
POST_INDEXED = True if "p" in operand else False)
|
PRE_INDEXED=True if "r" in operand else False,
|
||||||
|
POST_INDEXED=True if "p" in operand else False,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Parameter {} is not a valid operand code".format(operand))
|
raise ValueError("Parameter {} is not a valid operand code".format(operand))
|
||||||
|
|
||||||
@@ -511,10 +537,12 @@ class MachineModel(object):
|
|||||||
elif operand == "i":
|
elif operand == "i":
|
||||||
return ImmediateOperand(TYPE_ID="int")
|
return ImmediateOperand(TYPE_ID="int")
|
||||||
elif operand.startswith("m"):
|
elif operand.startswith("m"):
|
||||||
return MemoryOperand(BASE_ID = "gpr" if "b" in operand else None,
|
return MemoryOperand(
|
||||||
OFFSET_ID = "imd" if "o" in operand else None,
|
BASE_ID="gpr" if "b" in operand else None,
|
||||||
INDEX_ID = "gpr" if "i" in operand else None,
|
OFFSET_ID="imd" if "o" in operand else None,
|
||||||
SCALE_ID = 8 if "s" in operand else 1,)
|
INDEX_ID="gpr" if "i" in operand else None,
|
||||||
|
SCALE_ID=8 if "s" in operand else 1,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Parameter {} is not a valid operand code".format(operand))
|
raise ValueError("Parameter {} is not a valid operand code".format(operand))
|
||||||
|
|
||||||
@@ -553,10 +581,10 @@ class MachineModel(object):
|
|||||||
def _check_operands(self, i_operand, operand):
|
def _check_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."""
|
||||||
# check for wildcard
|
# check for wildcard
|
||||||
if (isinstance(operand, Operand) and operand.name == self.WILDCARD) or (not isinstance(operand, Operand) and self.WILDCARD in operand):
|
if (isinstance(operand, Operand) and operand.name == self.WILDCARD) or (
|
||||||
if (
|
not isinstance(operand, Operand) and self.WILDCARD in operand
|
||||||
isinstance(i_operand, RegisterOperand)
|
):
|
||||||
):
|
if isinstance(i_operand, RegisterOperand):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@@ -626,8 +654,8 @@ class MachineModel(object):
|
|||||||
|
|
||||||
def _check_x86_operands(self, i_operand, operand):
|
def _check_x86_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.name:
|
# if "class" in operand.name:
|
||||||
# compare two DB entries
|
# compare two DB entries
|
||||||
# return self._compare_db_entries(i_operand, operand)
|
# return self._compare_db_entries(i_operand, operand)
|
||||||
# register
|
# register
|
||||||
if isinstance(operand, RegisterOperand):
|
if isinstance(operand, RegisterOperand):
|
||||||
@@ -641,7 +669,7 @@ class MachineModel(object):
|
|||||||
return self._is_x86_mem_type(i_operand, operand)
|
return self._is_x86_mem_type(i_operand, operand)
|
||||||
# immediate
|
# immediate
|
||||||
if isinstance(operand, ImmediateOperand):
|
if isinstance(operand, ImmediateOperand):
|
||||||
#if "immediate" in operand.name or operand.value != None:
|
# if "immediate" in operand.name or operand.value != None:
|
||||||
return i_operand["class"] == "immediate" and i_operand["imd"] == "int"
|
return i_operand["class"] == "immediate" and i_operand["imd"] == "int"
|
||||||
# identifier (e.g., labels)
|
# identifier (e.g., labels)
|
||||||
if isinstance(operand, IdentifierOperand):
|
if isinstance(operand, IdentifierOperand):
|
||||||
@@ -733,10 +761,7 @@ class MachineModel(object):
|
|||||||
# one instruction is missing zeroing while the other has it
|
# one instruction is missing zeroing while the other has it
|
||||||
zero_ok = False
|
zero_ok = False
|
||||||
# check for wildcard
|
# check for wildcard
|
||||||
if (
|
if i_reg.zeroing == self.WILDCARD or reg.zeroing == self.WILDCARD:
|
||||||
i_reg.zeroing == self.WILDCARD
|
|
||||||
or reg.zeroing == self.WILDCARD
|
|
||||||
):
|
|
||||||
zero_ok = True
|
zero_ok = True
|
||||||
if not mask_ok or not zero_ok:
|
if not mask_ok or not zero_ok:
|
||||||
return False
|
return False
|
||||||
@@ -766,11 +791,7 @@ class MachineModel(object):
|
|||||||
and "identifier" in mem.offset
|
and "identifier" in mem.offset
|
||||||
and i_mem.offset == "identifier"
|
and i_mem.offset == "identifier"
|
||||||
)
|
)
|
||||||
or (
|
or (mem.offset is not None and "value" in mem.offset and i_mem.offset == "imd")
|
||||||
mem.offset is not None
|
|
||||||
and "value" in mem.offset
|
|
||||||
and i_mem.offset == "imd"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
# check index
|
# check index
|
||||||
and (
|
and (
|
||||||
@@ -778,7 +799,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"].prefix!=None
|
and mem["index"].prefix != None
|
||||||
and mem.index["prefix"] == i_mem.index
|
and mem.index["prefix"] == i_mem.index
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -790,13 +811,12 @@ class MachineModel(object):
|
|||||||
)
|
)
|
||||||
# check pre-indexing
|
# check pre-indexing
|
||||||
and (
|
and (
|
||||||
i_mem.pre-indexed == self.WILDCARD
|
i_mem.pre - indexed == self.WILDCARD or (mempre - indexed) == (i_mem.pre - indexed)
|
||||||
or (mempre-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
|
||||||
@@ -828,11 +848,7 @@ class MachineModel(object):
|
|||||||
or (i_mem.offset is None and mem.offset["value"] == "0")
|
or (i_mem.offset is None and mem.offset["value"] == "0")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
or (
|
or (mem.offset is not None and "identifier" in mem.offset and i_mem.offset == "id")
|
||||||
mem.offset is not None
|
|
||||||
and "identifier" in mem.offset
|
|
||||||
and i_mem.offset == "id"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
# check index
|
# check index
|
||||||
and (
|
and (
|
||||||
@@ -840,7 +856,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,7 +182,7 @@ 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:
|
||||||
@@ -194,7 +194,7 @@ class ISASemantics(object):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ class ISASemantics(object):
|
|||||||
"ISA information for pre-indexed instruction {!r} has operation set."
|
"ISA information for pre-indexed instruction {!r} has operation set."
|
||||||
"This is currently not supprted.".format(instruction_form.line)
|
"This is currently not supprted.".format(instruction_form.line)
|
||||||
)
|
)
|
||||||
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
|
||||||
reg_operand_names = {base_name: "op1"}
|
reg_operand_names = {base_name: "op1"}
|
||||||
operand_state = {"op1": {"name": base_name, "value": o.offset["value"]}}
|
operand_state = {"op1": {"name": base_name, "value": o.offset["value"]}}
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ class ISASemantics(object):
|
|||||||
for i, o in enumerate(instruction_form.operands):
|
for i, o in enumerate(instruction_form.operands):
|
||||||
operand_name = "op{}".format(i + 1)
|
operand_name = "op{}".format(i + 1)
|
||||||
if isinstance(o, RegisterOperand):
|
if isinstance(o, RegisterOperand):
|
||||||
o_reg_name = o.prefix if o.prefix!=None else "" + o.name
|
o_reg_name = o.prefix if o.prefix != None else "" + o.name
|
||||||
reg_operand_names[o_reg_name] = operand_name
|
reg_operand_names[o_reg_name] = operand_name
|
||||||
operand_state[operand_name] = {"name": o_reg_name, "value": 0}
|
operand_state[operand_name] = {"name": o_reg_name, "value": 0}
|
||||||
elif "immediate" in o:
|
elif "immediate" in o:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from osaca.parser.memory import MemoryOperand
|
|||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import RegisterOperand
|
||||||
from osaca.parser.immediate import ImmediateOperand
|
from osaca.parser.immediate import ImmediateOperand
|
||||||
|
|
||||||
|
|
||||||
class KernelDG(nx.DiGraph):
|
class KernelDG(nx.DiGraph):
|
||||||
# threshold for checking dependency graph sequential or in parallel
|
# threshold for checking dependency graph sequential or in parallel
|
||||||
INSTRUCTION_THRESHOLD = 50
|
INSTRUCTION_THRESHOLD = 50
|
||||||
@@ -285,9 +286,9 @@ class KernelDG(nx.DiGraph):
|
|||||||
if isinstance(dst, RegisterOperand):
|
if isinstance(dst, RegisterOperand):
|
||||||
# read of register
|
# read of register
|
||||||
if self.is_read(dst, instr_form):
|
if self.is_read(dst, instr_form):
|
||||||
#if dst.pre_indexed or dst.post_indexed:
|
# if dst.pre_indexed or dst.post_indexed:
|
||||||
#yield instr_form, ["p_indexed"]
|
# yield instr_form, ["p_indexed"]
|
||||||
#else:
|
# else:
|
||||||
yield instr_form, []
|
yield instr_form, []
|
||||||
# write to register -> abort
|
# write to register -> abort
|
||||||
if self.is_written(dst, instr_form):
|
if self.is_written(dst, instr_form):
|
||||||
@@ -410,7 +411,7 @@ class KernelDG(nx.DiGraph):
|
|||||||
# Here we check for mem dependecies only
|
# Here we check for mem dependecies only
|
||||||
if not isinstance(src, MemoryOperand):
|
if not isinstance(src, MemoryOperand):
|
||||||
continue
|
continue
|
||||||
#src = src.memory
|
# src = src.memory
|
||||||
|
|
||||||
# determine absolute address change
|
# determine absolute address change
|
||||||
addr_change = 0
|
addr_change = 0
|
||||||
@@ -420,13 +421,20 @@ class KernelDG(nx.DiGraph):
|
|||||||
addr_change -= mem.offset["value"]
|
addr_change -= mem.offset["value"]
|
||||||
if mem.base and src.base:
|
if mem.base and src.base:
|
||||||
base_change = register_changes.get(
|
base_change = register_changes.get(
|
||||||
src.base.prefix if src.base.prefix!=None else "" + src.base.name,
|
src.base.prefix if src.base.prefix != None else "" + src.base.name,
|
||||||
{"name": src.base.prefix if src.base.prefix!=None else "" + src.base.name, "value": 0},
|
{
|
||||||
|
"name": src.base.prefix if src.base.prefix != None else "" + src.base.name,
|
||||||
|
"value": 0,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if base_change is None:
|
if base_change is None:
|
||||||
# Unknown change occurred
|
# Unknown change occurred
|
||||||
continue
|
continue
|
||||||
if mem.base.prefix if mem.base.prefix!=None else "" + mem.base.name != base_change["name"]:
|
if (
|
||||||
|
mem.base.prefix
|
||||||
|
if mem.base.prefix != None
|
||||||
|
else "" + mem.base.name != base_change["name"]
|
||||||
|
):
|
||||||
# base registers do not match
|
# base registers do not match
|
||||||
continue
|
continue
|
||||||
addr_change += base_change["value"]
|
addr_change += base_change["value"]
|
||||||
@@ -444,7 +452,11 @@ class KernelDG(nx.DiGraph):
|
|||||||
if mem.scale != src.scale:
|
if mem.scale != src.scale:
|
||||||
# scale factors do not match
|
# scale factors do not match
|
||||||
continue
|
continue
|
||||||
if mem.index.prefix if mem.index.prefix!=None else "" + mem.index.name != index_change["name"]:
|
if (
|
||||||
|
mem.index.prefix
|
||||||
|
if mem.index.prefix != None
|
||||||
|
else "" + mem.index.name != index_change["name"]
|
||||||
|
):
|
||||||
# index registers do not match
|
# index registers do not match
|
||||||
continue
|
continue
|
||||||
addr_change += index_change["value"] * src.scale
|
addr_change += index_change["value"] * src.scale
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
instr7 = "fadd v17.2d, v16.2d, v1.2d"
|
instr7 = "fadd v17.2d, v16.2d, v1.2d"
|
||||||
instr8 = "mov.d x0, v16.d[1]"
|
instr8 = "mov.d x0, v16.d[1]"
|
||||||
instr9 = "ccmp x0, x1, #4, cc"
|
instr9 = "ccmp x0, x1, #4, cc"
|
||||||
|
|
||||||
parsed_1 = self.parser.parse_instruction(instr1)
|
parsed_1 = self.parser.parse_instruction(instr1)
|
||||||
parsed_2 = self.parser.parse_instruction(instr2)
|
parsed_2 = self.parser.parse_instruction(instr2)
|
||||||
parsed_3 = self.parser.parse_instruction(instr3)
|
parsed_3 = self.parser.parse_instruction(instr3)
|
||||||
@@ -104,19 +104,19 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
parsed_7 = self.parser.parse_instruction(instr7)
|
parsed_7 = self.parser.parse_instruction(instr7)
|
||||||
parsed_8 = self.parser.parse_instruction(instr8)
|
parsed_8 = self.parser.parse_instruction(instr8)
|
||||||
parsed_9 = self.parser.parse_instruction(instr9)
|
parsed_9 = self.parser.parse_instruction(instr9)
|
||||||
|
|
||||||
self.assertEqual(parsed_1.instruction, "vcvt.F32.S32")
|
self.assertEqual(parsed_1.instruction, "vcvt.F32.S32")
|
||||||
self.assertEqual(parsed_1.operands[0].name, "1")
|
self.assertEqual(parsed_1.operands[0].name, "1")
|
||||||
self.assertEqual(parsed_1.operands[0].prefix, "w")
|
self.assertEqual(parsed_1.operands[0].prefix, "w")
|
||||||
self.assertEqual(parsed_1.operands[1].name, "2")
|
self.assertEqual(parsed_1.operands[1].name, "2")
|
||||||
self.assertEqual(parsed_1.operands[1].prefix, "w")
|
self.assertEqual(parsed_1.operands[1].prefix, "w")
|
||||||
self.assertEqual(parsed_1.comment, "12.27")
|
self.assertEqual(parsed_1.comment, "12.27")
|
||||||
|
|
||||||
self.assertEqual(parsed_2.instruction, "b.lo")
|
self.assertEqual(parsed_2.instruction, "b.lo")
|
||||||
self.assertEqual(parsed_2.operands[0]['identifier']['name'], "..B1.4")
|
self.assertEqual(parsed_2.operands[0]["identifier"]["name"], "..B1.4")
|
||||||
self.assertEqual(len(parsed_2.operands), 1)
|
self.assertEqual(len(parsed_2.operands), 1)
|
||||||
self.assertIsNone(parsed_2.comment)
|
self.assertIsNone(parsed_2.comment)
|
||||||
|
|
||||||
self.assertEqual(parsed_3.instruction, "mov")
|
self.assertEqual(parsed_3.instruction, "mov")
|
||||||
self.assertEqual(parsed_3.operands[0].name, "2")
|
self.assertEqual(parsed_3.operands[0].name, "2")
|
||||||
self.assertEqual(parsed_3.operands[0].prefix, "x")
|
self.assertEqual(parsed_3.operands[0].prefix, "x")
|
||||||
@@ -127,8 +127,8 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
self.assertIsNone(parsed_4.operands[1].offset)
|
self.assertIsNone(parsed_4.operands[1].offset)
|
||||||
self.assertEqual(parsed_4.operands[1].base.name, "sp")
|
self.assertEqual(parsed_4.operands[1].base.name, "sp")
|
||||||
self.assertEqual(parsed_4.operands[1].base.prefix, "x")
|
self.assertEqual(parsed_4.operands[1].base.prefix, "x")
|
||||||
self.assertEqual(parsed_4.operands[1].index['name'], "1")
|
self.assertEqual(parsed_4.operands[1].index["name"], "1")
|
||||||
self.assertEqual(parsed_4.operands[1].index['prefix'], "x")
|
self.assertEqual(parsed_4.operands[1].index["prefix"], "x")
|
||||||
self.assertEqual(parsed_4.operands[1].scale, 16)
|
self.assertEqual(parsed_4.operands[1].scale, 16)
|
||||||
self.assertEqual(parsed_4.operands[0].name, "28")
|
self.assertEqual(parsed_4.operands[0].name, "28")
|
||||||
self.assertEqual(parsed_4.operands[0].prefix, "x")
|
self.assertEqual(parsed_4.operands[0].prefix, "x")
|
||||||
@@ -137,8 +137,8 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
self.assertEqual(parsed_5.instruction, "ldr")
|
self.assertEqual(parsed_5.instruction, "ldr")
|
||||||
self.assertEqual(parsed_5.operands[0].name, "0")
|
self.assertEqual(parsed_5.operands[0].name, "0")
|
||||||
self.assertEqual(parsed_5.operands[0].prefix, "x")
|
self.assertEqual(parsed_5.operands[0].prefix, "x")
|
||||||
self.assertEqual(parsed_5.operands[1].offset['identifier']['name'], "q2c")
|
self.assertEqual(parsed_5.operands[1].offset["identifier"]["name"], "q2c")
|
||||||
self.assertEqual(parsed_5.operands[1].offset['identifier']['relocation'], ":got_lo12:")
|
self.assertEqual(parsed_5.operands[1].offset["identifier"]["relocation"], ":got_lo12:")
|
||||||
self.assertEqual(parsed_5.operands[1].base.name, "0")
|
self.assertEqual(parsed_5.operands[1].base.name, "0")
|
||||||
self.assertEqual(parsed_5.operands[1].base.prefix, "x")
|
self.assertEqual(parsed_5.operands[1].base.prefix, "x")
|
||||||
self.assertIsNone(parsed_5.operands[1].index)
|
self.assertIsNone(parsed_5.operands[1].index)
|
||||||
@@ -147,8 +147,8 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
self.assertEqual(parsed_6.instruction, "adrp")
|
self.assertEqual(parsed_6.instruction, "adrp")
|
||||||
self.assertEqual(parsed_6.operands[0].name, "0")
|
self.assertEqual(parsed_6.operands[0].name, "0")
|
||||||
self.assertEqual(parsed_6.operands[0].prefix, "x")
|
self.assertEqual(parsed_6.operands[0].prefix, "x")
|
||||||
self.assertEqual(parsed_6.operands[1]['identifier']['relocation'], ":got:")
|
self.assertEqual(parsed_6.operands[1]["identifier"]["relocation"], ":got:")
|
||||||
self.assertEqual(parsed_6.operands[1]['identifier']['name'], "visited")
|
self.assertEqual(parsed_6.operands[1]["identifier"]["name"], "visited")
|
||||||
|
|
||||||
self.assertEqual(parsed_7.instruction, "fadd")
|
self.assertEqual(parsed_7.instruction, "fadd")
|
||||||
self.assertEqual(parsed_7.operands[0].name, "17")
|
self.assertEqual(parsed_7.operands[0].name, "17")
|
||||||
@@ -168,8 +168,7 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
self.assertEqual(parsed_9.instruction, "ccmp")
|
self.assertEqual(parsed_9.instruction, "ccmp")
|
||||||
self.assertEqual(parsed_9.operands[0].name, "0")
|
self.assertEqual(parsed_9.operands[0].name, "0")
|
||||||
self.assertEqual(parsed_9.operands[0].prefix, "x")
|
self.assertEqual(parsed_9.operands[0].prefix, "x")
|
||||||
self.assertEqual(parsed_9.operands[3]['condition'], "CC")
|
self.assertEqual(parsed_9.operands[3]["condition"], "CC")
|
||||||
|
|
||||||
|
|
||||||
def test_parse_line(self):
|
def test_parse_line(self):
|
||||||
line_comment = "// -- Begin main"
|
line_comment = "// -- Begin main"
|
||||||
@@ -216,7 +215,7 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
RegisterOperand(PREFIX_ID="s", NAME_ID="0"),
|
RegisterOperand(PREFIX_ID="s", NAME_ID="0"),
|
||||||
MemoryOperand(
|
MemoryOperand(
|
||||||
OFFSET_ID=None,
|
OFFSET_ID=None,
|
||||||
BASE_ID=RegisterOperand(PREFIX_ID = "x", NAME_ID ="11"),
|
BASE_ID=RegisterOperand(PREFIX_ID="x", NAME_ID="11"),
|
||||||
INDEX_ID={
|
INDEX_ID={
|
||||||
"prefix": "w",
|
"prefix": "w",
|
||||||
"name": "10",
|
"name": "10",
|
||||||
@@ -239,7 +238,7 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
{"prfop": {"type": ["PLD"], "target": ["L1"], "policy": ["KEEP"]}},
|
{"prfop": {"type": ["PLD"], "target": ["L1"], "policy": ["KEEP"]}},
|
||||||
MemoryOperand(
|
MemoryOperand(
|
||||||
OFFSET_ID={"value": 2048},
|
OFFSET_ID={"value": 2048},
|
||||||
BASE_ID=RegisterOperand(PREFIX_ID = "x", NAME_ID ="26"),
|
BASE_ID=RegisterOperand(PREFIX_ID="x", NAME_ID="26"),
|
||||||
INDEX_ID=None,
|
INDEX_ID=None,
|
||||||
SCALE_ID=1,
|
SCALE_ID=1,
|
||||||
),
|
),
|
||||||
@@ -257,7 +256,7 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
RegisterOperand(PREFIX_ID="x", NAME_ID="30"),
|
RegisterOperand(PREFIX_ID="x", NAME_ID="30"),
|
||||||
MemoryOperand(
|
MemoryOperand(
|
||||||
OFFSET_ID={"value": -16},
|
OFFSET_ID={"value": -16},
|
||||||
BASE_ID=RegisterOperand(NAME_ID = "sp", PREFIX_ID = "x"),
|
BASE_ID=RegisterOperand(NAME_ID="sp", PREFIX_ID="x"),
|
||||||
INDEX_ID=None,
|
INDEX_ID=None,
|
||||||
SCALE_ID=1,
|
SCALE_ID=1,
|
||||||
PRE_INDEXED=True,
|
PRE_INDEXED=True,
|
||||||
@@ -276,7 +275,7 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
RegisterOperand(PREFIX_ID="q", NAME_ID="3"),
|
RegisterOperand(PREFIX_ID="q", NAME_ID="3"),
|
||||||
MemoryOperand(
|
MemoryOperand(
|
||||||
OFFSET_ID=None,
|
OFFSET_ID=None,
|
||||||
BASE_ID=RegisterOperand(NAME_ID = "11", PREFIX_ID = "x"),
|
BASE_ID=RegisterOperand(NAME_ID="11", PREFIX_ID="x"),
|
||||||
INDEX_ID=None,
|
INDEX_ID=None,
|
||||||
SCALE_ID=1,
|
SCALE_ID=1,
|
||||||
POST_INDEXED={"value": 64},
|
POST_INDEXED={"value": 64},
|
||||||
@@ -317,7 +316,7 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
LINE="ccmn x11, #1, #3, eq",
|
LINE="ccmn x11, #1, #3, eq",
|
||||||
LINE_NUMBER=9,
|
LINE_NUMBER=9,
|
||||||
)
|
)
|
||||||
|
|
||||||
parsed_1 = self.parser.parse_line(line_comment, 1)
|
parsed_1 = self.parser.parse_line(line_comment, 1)
|
||||||
parsed_2 = self.parser.parse_line(line_label, 2)
|
parsed_2 = self.parser.parse_line(line_label, 2)
|
||||||
parsed_3 = self.parser.parse_line(line_directive, 3)
|
parsed_3 = self.parser.parse_line(line_directive, 3)
|
||||||
@@ -337,7 +336,6 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
self.assertEqual(parsed_7, instruction_form_7)
|
self.assertEqual(parsed_7, instruction_form_7)
|
||||||
self.assertEqual(parsed_8, instruction_form_8)
|
self.assertEqual(parsed_8, instruction_form_8)
|
||||||
self.assertEqual(parsed_9, instruction_form_9)
|
self.assertEqual(parsed_9, instruction_form_9)
|
||||||
|
|
||||||
|
|
||||||
def test_parse_file(self):
|
def test_parse_file(self):
|
||||||
parsed = self.parser.parse_file(self.triad_code)
|
parsed = self.parser.parse_file(self.triad_code)
|
||||||
@@ -399,22 +397,22 @@ class TestParserAArch64(unittest.TestCase):
|
|||||||
# self.assertEqual(p_single.operands, reg_list_single)
|
# self.assertEqual(p_single.operands, reg_list_single)
|
||||||
|
|
||||||
def test_reg_dependency(self):
|
def test_reg_dependency(self):
|
||||||
reg_1_1 = RegisterOperand(PREFIX_ID = "b", NAME_ID = "1")
|
reg_1_1 = RegisterOperand(PREFIX_ID="b", NAME_ID="1")
|
||||||
reg_1_2 = RegisterOperand(PREFIX_ID = "h", NAME_ID = "1")
|
reg_1_2 = RegisterOperand(PREFIX_ID="h", NAME_ID="1")
|
||||||
reg_1_3 = RegisterOperand(PREFIX_ID = "s", NAME_ID = "1")
|
reg_1_3 = RegisterOperand(PREFIX_ID="s", NAME_ID="1")
|
||||||
reg_1_4 = RegisterOperand(PREFIX_ID = "d", NAME_ID = "1")
|
reg_1_4 = RegisterOperand(PREFIX_ID="d", NAME_ID="1")
|
||||||
reg_1_4 = RegisterOperand(PREFIX_ID = "q", NAME_ID = "1")
|
reg_1_4 = RegisterOperand(PREFIX_ID="q", NAME_ID="1")
|
||||||
reg_2_1 = RegisterOperand(PREFIX_ID = "w", NAME_ID = "2")
|
reg_2_1 = RegisterOperand(PREFIX_ID="w", NAME_ID="2")
|
||||||
reg_2_2 = RegisterOperand(PREFIX_ID = "x", NAME_ID = "2")
|
reg_2_2 = RegisterOperand(PREFIX_ID="x", NAME_ID="2")
|
||||||
reg_v1_1 = RegisterOperand(PREFIX_ID = "v", NAME_ID = "11", LANES = "16", SHAPE = "b")
|
reg_v1_1 = RegisterOperand(PREFIX_ID="v", NAME_ID="11", LANES="16", SHAPE="b")
|
||||||
reg_v1_2 = RegisterOperand(PREFIX_ID = "v", NAME_ID = "11", LANES = "8", SHAPE = "h")
|
reg_v1_2 = RegisterOperand(PREFIX_ID="v", NAME_ID="11", LANES="8", SHAPE="h")
|
||||||
reg_v1_3 = RegisterOperand(PREFIX_ID = "v", NAME_ID = "11", LANES = "4", SHAPE = "s")
|
reg_v1_3 = RegisterOperand(PREFIX_ID="v", NAME_ID="11", LANES="4", SHAPE="s")
|
||||||
reg_v1_4 = RegisterOperand(PREFIX_ID = "v", NAME_ID = "11", LANES = "2", SHAPE = "d")
|
reg_v1_4 = RegisterOperand(PREFIX_ID="v", NAME_ID="11", LANES="2", SHAPE="d")
|
||||||
|
|
||||||
reg_b5 = RegisterOperand(PREFIX_ID = "b", NAME_ID = "5")
|
reg_b5 = RegisterOperand(PREFIX_ID="b", NAME_ID="5")
|
||||||
reg_q15 = RegisterOperand(PREFIX_ID = "q", NAME_ID = "15")
|
reg_q15 = RegisterOperand(PREFIX_ID="q", NAME_ID="15")
|
||||||
reg_v10 = RegisterOperand(PREFIX_ID = "v", NAME_ID = "10", LANES = "2", SHAPE = "s")
|
reg_v10 = RegisterOperand(PREFIX_ID="v", NAME_ID="10", LANES="2", SHAPE="s")
|
||||||
reg_v20 = RegisterOperand(PREFIX_ID = "v", NAME_ID = "20", LANES = "2", SHAPE = "d")
|
reg_v20 = RegisterOperand(PREFIX_ID="v", NAME_ID="20", LANES="2", SHAPE="d")
|
||||||
|
|
||||||
reg_1 = [reg_1_1, reg_1_2, reg_1_3, reg_1_4]
|
reg_1 = [reg_1_1, reg_1_2, reg_1_3, reg_1_4]
|
||||||
reg_2 = [reg_2_1, reg_2_2]
|
reg_2 = [reg_2_1, reg_2_2]
|
||||||
|
|||||||
@@ -259,22 +259,22 @@ class TestParserX86ATT(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_reg_dependency(self):
|
def test_reg_dependency(self):
|
||||||
reg_a1 = RegisterOperand(NAME_ID = "rax")
|
reg_a1 = RegisterOperand(NAME_ID="rax")
|
||||||
reg_a2 = RegisterOperand(NAME_ID = "eax")
|
reg_a2 = RegisterOperand(NAME_ID="eax")
|
||||||
reg_a3 = RegisterOperand(NAME_ID = "ax")
|
reg_a3 = RegisterOperand(NAME_ID="ax")
|
||||||
reg_a4 = RegisterOperand(NAME_ID = "al")
|
reg_a4 = RegisterOperand(NAME_ID="al")
|
||||||
reg_r11 = RegisterOperand(NAME_ID = "r11")
|
reg_r11 = RegisterOperand(NAME_ID="r11")
|
||||||
reg_r11b = RegisterOperand(NAME_ID = "r11b")
|
reg_r11b = RegisterOperand(NAME_ID="r11b")
|
||||||
reg_r11d = RegisterOperand(NAME_ID = "r11d")
|
reg_r11d = RegisterOperand(NAME_ID="r11d")
|
||||||
reg_r11w = RegisterOperand(NAME_ID = "r11w")
|
reg_r11w = RegisterOperand(NAME_ID="r11w")
|
||||||
reg_xmm1 = RegisterOperand(NAME_ID = "xmm1")
|
reg_xmm1 = RegisterOperand(NAME_ID="xmm1")
|
||||||
reg_ymm1 = RegisterOperand(NAME_ID = "ymm1")
|
reg_ymm1 = RegisterOperand(NAME_ID="ymm1")
|
||||||
reg_zmm1 = RegisterOperand(NAME_ID = "zmm1")
|
reg_zmm1 = RegisterOperand(NAME_ID="zmm1")
|
||||||
|
|
||||||
reg_b1 = RegisterOperand(NAME_ID = "rbx")
|
reg_b1 = RegisterOperand(NAME_ID="rbx")
|
||||||
reg_r15 = RegisterOperand(NAME_ID = "r15")
|
reg_r15 = RegisterOperand(NAME_ID="r15")
|
||||||
reg_xmm2 = RegisterOperand(NAME_ID = "xmm2")
|
reg_xmm2 = RegisterOperand(NAME_ID="xmm2")
|
||||||
reg_ymm3 = RegisterOperand(NAME_ID = "ymm3")
|
reg_ymm3 = RegisterOperand(NAME_ID="ymm3")
|
||||||
|
|
||||||
reg_a = [reg_a1, reg_a2, reg_a3, reg_a4]
|
reg_a = [reg_a1, reg_a2, reg_a3, reg_a4]
|
||||||
reg_r = [reg_r11, reg_r11b, reg_r11d, reg_r11w]
|
reg_r = [reg_r11, reg_r11b, reg_r11d, reg_r11w]
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from osaca.semantics import (
|
|||||||
from osaca.parser.register import RegisterOperand
|
from osaca.parser.register import RegisterOperand
|
||||||
from osaca.parser.memory import MemoryOperand
|
from osaca.parser.memory import MemoryOperand
|
||||||
|
|
||||||
|
|
||||||
class TestSemanticTools(unittest.TestCase):
|
class TestSemanticTools(unittest.TestCase):
|
||||||
MODULE_DATA_DIR = os.path.join(
|
MODULE_DATA_DIR = os.path.join(
|
||||||
os.path.dirname(os.path.split(os.path.abspath(__file__))[0]), "osaca/data/"
|
os.path.dirname(os.path.split(os.path.abspath(__file__))[0]), "osaca/data/"
|
||||||
@@ -117,14 +118,14 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
###########
|
###########
|
||||||
# Tests
|
# Tests
|
||||||
###########
|
###########
|
||||||
|
|
||||||
def test_creation_by_name(self):
|
def test_creation_by_name(self):
|
||||||
try:
|
try:
|
||||||
tmp_mm = MachineModel(arch="CSX")
|
tmp_mm = MachineModel(arch="CSX")
|
||||||
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:
|
||||||
@@ -184,8 +185,9 @@ 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(
|
||||||
@@ -246,7 +248,8 @@ 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:
|
||||||
with self.subTest(instruction_form=instruction_form):
|
with self.subTest(instruction_form=instruction_form):
|
||||||
@@ -272,7 +275,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.assertTrue(instruction_form.latency != None)
|
self.assertTrue(instruction_form.latency != None)
|
||||||
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_tp_lt_assignment_AArch64(self):
|
def test_tp_lt_assignment_AArch64(self):
|
||||||
self.assertTrue("ports" in self.machine_model_tx2)
|
self.assertTrue("ports" in self.machine_model_tx2)
|
||||||
port_num = len(self.machine_model_tx2["ports"])
|
port_num = len(self.machine_model_tx2["ports"])
|
||||||
@@ -282,7 +285,8 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.assertTrue(instruction_form.latency != None)
|
self.assertTrue(instruction_form.latency != None)
|
||||||
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)
|
||||||
@@ -392,7 +396,8 @@ 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(
|
||||||
self.kernel_aarch64_SVE,
|
self.kernel_aarch64_SVE,
|
||||||
@@ -401,7 +406,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.semantics_a64fx,
|
self.semantics_a64fx,
|
||||||
)
|
)
|
||||||
# TODO check for correct analysis
|
# TODO check for correct analysis
|
||||||
|
|
||||||
def test_hidden_load(self):
|
def test_hidden_load(self):
|
||||||
machine_model_hld = MachineModel(
|
machine_model_hld = MachineModel(
|
||||||
path_to_yaml=self._find_file("hidden_load_machine_model.yml")
|
path_to_yaml=self._find_file("hidden_load_machine_model.yml")
|
||||||
@@ -422,7 +427,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
self.assertEqual(num_hidden_loads, 1)
|
self.assertEqual(num_hidden_loads, 1)
|
||||||
self.assertEqual(num_hidden_loads_2, 0)
|
self.assertEqual(num_hidden_loads_2, 0)
|
||||||
self.assertEqual(num_hidden_loads_3, 1)
|
self.assertEqual(num_hidden_loads_3, 1)
|
||||||
|
|
||||||
def test_cyclic_dag(self):
|
def test_cyclic_dag(self):
|
||||||
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
|
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
|
||||||
dg.dg.add_edge(100, 101, latency=1.0)
|
dg.dg.add_edge(100, 101, latency=1.0)
|
||||||
@@ -432,7 +437,8 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
dg.get_critical_path()
|
dg.get_critical_path()
|
||||||
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,
|
||||||
@@ -534,12 +540,13 @@ 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
|
||||||
dag = KernelDG(self.kernel_x86, self.parser_x86, None, None)
|
dag = KernelDG(self.kernel_x86, self.parser_x86, None, None)
|
||||||
reg_rcx = RegisterOperand(NAME_ID = "rcx")
|
reg_rcx = RegisterOperand(NAME_ID="rcx")
|
||||||
reg_ymm1 = RegisterOperand(NAME_ID = "ymm1")
|
reg_ymm1 = RegisterOperand(NAME_ID="ymm1")
|
||||||
|
|
||||||
instr_form_r_c = self.parser_x86.parse_line("vmovsd %xmm0, (%r15,%rcx,8)")
|
instr_form_r_c = self.parser_x86.parse_line("vmovsd %xmm0, (%r15,%rcx,8)")
|
||||||
self.semantics_csx.assign_src_dst(instr_form_r_c)
|
self.semantics_csx.assign_src_dst(instr_form_r_c)
|
||||||
@@ -569,11 +576,11 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
def test_is_read_is_written_AArch64(self):
|
def test_is_read_is_written_AArch64(self):
|
||||||
# independent form HW model
|
# independent form HW model
|
||||||
dag = KernelDG(self.kernel_AArch64, self.parser_AArch64, None, None)
|
dag = KernelDG(self.kernel_AArch64, self.parser_AArch64, None, None)
|
||||||
reg_x1 = RegisterOperand(PREFIX_ID="x",NAME_ID="1")
|
reg_x1 = RegisterOperand(PREFIX_ID="x", NAME_ID="1")
|
||||||
reg_w1 = RegisterOperand(PREFIX_ID="w",NAME_ID="1")
|
reg_w1 = RegisterOperand(PREFIX_ID="w", NAME_ID="1")
|
||||||
reg_d1 = RegisterOperand(PREFIX_ID="d",NAME_ID="1")
|
reg_d1 = RegisterOperand(PREFIX_ID="d", NAME_ID="1")
|
||||||
reg_q1 = RegisterOperand(PREFIX_ID="q",NAME_ID="1")
|
reg_q1 = RegisterOperand(PREFIX_ID="q", NAME_ID="1")
|
||||||
reg_v1 = RegisterOperand(PREFIX_ID="v",NAME_ID="1",LANES="2",SHAPE="d")
|
reg_v1 = RegisterOperand(PREFIX_ID="v", NAME_ID="1", LANES="2", SHAPE="d")
|
||||||
regs = [reg_d1, reg_q1, reg_v1]
|
regs = [reg_d1, reg_q1, reg_v1]
|
||||||
regs_gp = [reg_w1, reg_x1]
|
regs_gp = [reg_w1, reg_x1]
|
||||||
|
|
||||||
@@ -596,7 +603,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
|
|
||||||
for reg in regs:
|
for reg in regs:
|
||||||
with self.subTest(reg=reg):
|
with self.subTest(reg=reg):
|
||||||
#self.assertTrue(dag.is_read(reg, instr_form_r_1))
|
# self.assertTrue(dag.is_read(reg, instr_form_r_1))
|
||||||
self.assertTrue(dag.is_read(reg, instr_form_r_2))
|
self.assertTrue(dag.is_read(reg, instr_form_r_2))
|
||||||
self.assertTrue(dag.is_read(reg, instr_form_rw_1))
|
self.assertTrue(dag.is_read(reg, instr_form_rw_1))
|
||||||
self.assertFalse(dag.is_read(reg, instr_form_rw_2))
|
self.assertFalse(dag.is_read(reg, instr_form_rw_2))
|
||||||
@@ -638,7 +645,12 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
|
|
||||||
def test_MachineModel_getter(self):
|
def test_MachineModel_getter(self):
|
||||||
sample_operands = [
|
sample_operands = [
|
||||||
MemoryOperand(OFFSET_ID=None,BASE_ID=RegisterOperand(NAME_ID = "r12"), INDEX_ID=RegisterOperand(NAME_ID="rcx"),SCALE_ID=8)
|
MemoryOperand(
|
||||||
|
OFFSET_ID=None,
|
||||||
|
BASE_ID=RegisterOperand(NAME_ID="r12"),
|
||||||
|
INDEX_ID=RegisterOperand(NAME_ID="rcx"),
|
||||||
|
SCALE_ID=8,
|
||||||
|
)
|
||||||
]
|
]
|
||||||
self.assertIsNone(self.machine_model_csx.get_instruction("GETRESULT", sample_operands))
|
self.assertIsNone(self.machine_model_csx.get_instruction("GETRESULT", sample_operands))
|
||||||
self.assertIsNone(self.machine_model_tx2.get_instruction("GETRESULT", sample_operands))
|
self.assertIsNone(self.machine_model_tx2.get_instruction("GETRESULT", sample_operands))
|
||||||
@@ -675,4 +687,4 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestSemanticTools)
|
suite = unittest.TestLoader().loadTestsFromTestCase(TestSemanticTools)
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||||
|
|||||||
Reference in New Issue
Block a user