From 1c0708e750c5f08bf5edc5f9b18a4cacc2437fe0 Mon Sep 17 00:00:00 2001 From: stefandesouza Date: Tue, 27 Feb 2024 14:47:55 +0100 Subject: [PATCH] Added updated files --- osaca/frontend.py | 8 +++--- osaca/semantics/arch_semantics.py | 46 +++++++++++++++---------------- osaca/semantics/isa_semantics.py | 42 ++++++++++++++-------------- osaca/semantics/kernel_dg.py | 4 +-- osaca/semantics/marker_utils.py | 17 ++++++------ tests/test_frontend.py | 4 +-- tests/test_parser_AArch64.py | 2 +- 7 files changed, 61 insertions(+), 62 deletions(-) diff --git a/osaca/frontend.py b/osaca/frontend.py index 135e41b..ae21752 100644 --- a/osaca/frontend.py +++ b/osaca/frontend.py @@ -53,7 +53,7 @@ class Frontend(object): :type instruction_form: `dict` :returns: `True` if comment line, `False` otherwise """ - return instruction_form.comment is not None and instruction_form.instruction is None + return instruction_form.comment is not None and instruction_form.mnemonic is None def throughput_analysis(self, kernel, show_lineno=False, show_cmnts=True): """ @@ -86,7 +86,7 @@ class Frontend(object): instruction_form.port_pressure, port_len, separator=sep_list ), self._get_flag_symbols(instruction_form.flags) - if instruction_form.instruction is not None + if instruction_form.mnemonic is not None else " ", instruction_form.line.strip().replace("\t", " "), ) @@ -256,7 +256,7 @@ class Frontend(object): "Line": re.sub(r"\s+", " ", x.line.strip()), "LineNumber": x.line_number, "Flags": list(x.flags), - "Instruction": x.instruction, + "Instruction": x.mnemonic, "Operands": x.operands, "SemanticOperands": x.semantic_operands, "Label": x.label, @@ -367,7 +367,7 @@ class Frontend(object): lcd_lines.get(line_number), ), self._get_flag_symbols(instruction_form.flags) - if instruction_form.instruction is not None + if instruction_form.mnemonic is not None else " ", instruction_form.line.strip().replace("\t", " "), ) diff --git a/osaca/semantics/arch_semantics.py b/osaca/semantics/arch_semantics.py index 966816b..b11e09a 100644 --- a/osaca/semantics/arch_semantics.py +++ b/osaca/semantics/arch_semantics.py @@ -178,7 +178,7 @@ class ArchSemantics(ISASemantics): """Assign throughput and latency to an instruction form.""" flags = [] port_number = len(self._machine_model["ports"]) - if instruction_form.instruction is None: + if instruction_form.mnemonic is None: # No instruction (label, comment, ...) --> ignore throughput = 0.0 latency = 0.0 @@ -187,26 +187,26 @@ class ArchSemantics(ISASemantics): instruction_form.port_uops = [] else: instruction_data = self._machine_model.get_instruction( - instruction_form.instruction, instruction_form.operands + instruction_form.mnemonic, instruction_form.operands ) if ( not instruction_data and self._isa == "x86" - and instruction_form.instruction[-1] in self.GAS_SUFFIXES + and instruction_form.mnemonic[-1] in self.GAS_SUFFIXES ): # check for instruction without GAS suffix instruction_data = self._machine_model.get_instruction( - instruction_form.instruction[:-1], instruction_form.operands + instruction_form.mnemonic[:-1], instruction_form.operands ) if ( instruction_data is None and self._isa == "aarch64" - and "." in instruction_form.instruction + and "." in instruction_form.mnemonic ): # Check for instruction without shape/cc suffix - suffix_start = instruction_form.instruction.index(".") + suffix_start = instruction_form.mnemonic.index(".") instruction_data = self._machine_model.get_instruction( - instruction_form.instruction[:suffix_start], instruction_form.operands + instruction_form.mnemonic[:suffix_start], instruction_form.operands ) if instruction_data: # instruction form in DB @@ -230,26 +230,26 @@ class ArchSemantics(ISASemantics): # substitute mem and look for reg-only variant operands = self.substitute_mem_address(instruction_form.operands) instruction_data_reg = self._machine_model.get_instruction( - instruction_form.instruction, operands + instruction_form.mnemonic, operands ) if ( not instruction_data_reg and self._isa == "x86" - and instruction_form.instruction[-1] in self.GAS_SUFFIXES + and instruction_form.mnemonic[-1] in self.GAS_SUFFIXES ): # check for instruction without GAS suffix instruction_data_reg = self._machine_model.get_instruction( - instruction_form.instruction[:-1], operands + instruction_form.mnemonic[:-1], operands ) if ( instruction_data_reg is None and self._isa == "aarch64" - and "." in instruction_form.instruction + and "." in instruction_form.mnemonic ): # Check for instruction without shape/cc suffix - suffix_start = instruction_form.instruction.index(".") + suffix_start = instruction_form.mnemonic.index(".") instruction_data_reg = self._machine_model.get_instruction( - instruction_form.instruction[:suffix_start], operands + instruction_form.mnemonic[:suffix_start], operands ) if instruction_data_reg: assign_unknown = False @@ -270,19 +270,19 @@ class ArchSemantics(ISASemantics): for x in instruction_form.semantic_operands["source"] + instruction_form.semantic_operands["src_dst"] if isinstance(x, MemoryOperand) - ][0] + ] ) # if multiple options, choose based on reg type data_port_uops = [ - ldp.port_pressure + ldp[1] for ldp in load_perf_data - if ldp.dst is not None + if ldp[0].dst is not None and self._machine_model._check_operands( - dummy_reg, RegisterOperand(name=ldp.dst) + dummy_reg, RegisterOperand(name=ldp[0].dst) ) ] if len(data_port_uops) < 1: - data_port_uops = load_perf_data[0].port_pressure + data_port_uops = load_perf_data[0][1] else: data_port_uops = data_port_uops[0] data_port_pressure = self._machine_model.average_port_pressure( @@ -303,7 +303,7 @@ class ArchSemantics(ISASemantics): [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][1] # zero data port pressure and remove HAS_ST flag if # - no mem operand in dst && @@ -439,15 +439,15 @@ class ArchSemantics(ISASemantics): flags.append(INSTR_FLAGS.LD) return throughput, port_pressure, latency, latency_wo_load - def convert_op_to_reg(self, reg_type, reg_id="0"): + def convert_op_to_reg(self, reg_type, regtype="0"): """Create register operand for a memory addressing operand""" if self._isa == "x86": if reg_type == "gpr": - register = RegisterOperand(name="r" + str(int(reg_id) + 9)) + register = RegisterOperand(name="r" + str(int(regtype) + 9)) else: - register = RegisterOperand(name=reg_type + reg_id) + register = RegisterOperand(name=reg_type + regtype) elif self._isa == "aarch64": - register = RegisterOperand(name=reg_id, prefix_id=reg_type) + register = RegisterOperand(name=regtype, prefix=reg_type) return register def _nullify_data_ports(self, port_pressure): diff --git a/osaca/semantics/isa_semantics.py b/osaca/semantics/isa_semantics.py index a0eb1d2..31be19c 100644 --- a/osaca/semantics/isa_semantics.py +++ b/osaca/semantics/isa_semantics.py @@ -49,28 +49,28 @@ class ISASemantics(object): def assign_src_dst(self, instruction_form): """Update instruction form dictionary with source, destination and flag information.""" # if the instruction form doesn't have operands or is None, there's nothing to do - if instruction_form.operands is None or instruction_form.instruction is None: + if instruction_form.operands is None or instruction_form.mnemonic is None: instruction_form.semantic_operands = {"source": [], "destination": [], "src_dst": []} return # check if instruction form is in ISA yaml, otherwise apply standard operand assignment # (one dest, others source) isa_data = self._isa_model.get_instruction( - instruction_form.instruction, instruction_form.operands + instruction_form.mnemonic, instruction_form.operands ) if ( isa_data is None and self._isa == "x86" - and instruction_form.instruction[-1] in self.GAS_SUFFIXES + and instruction_form.mnemonic[-1] in self.GAS_SUFFIXES ): # Check for instruction without GAS suffix isa_data = self._isa_model.get_instruction( - instruction_form.instruction[:-1], instruction_form.operands + instruction_form.mnemonic[:-1], instruction_form.operands ) - if isa_data is None and self._isa == "aarch64" and "." in instruction_form.instruction: + if isa_data is None and self._isa == "aarch64" and "." in instruction_form.mnemonic: # Check for instruction without shape/cc suffix - suffix_start = instruction_form.instruction.index(".") + suffix_start = instruction_form.mnemonic.index(".") isa_data = self._isa_model.get_instruction( - instruction_form.instruction[:suffix_start], instruction_form.operands + instruction_form.mnemonic[:suffix_start], instruction_form.operands ) operands = instruction_form.operands op_dict = {} @@ -86,26 +86,26 @@ class ISASemantics(object): if any([isinstance(op, MemoryOperand) for op in operands]): operands_reg = self.substitute_mem_address(instruction_form.operands) isa_data_reg = self._isa_model.get_instruction( - instruction_form.instruction, operands_reg + instruction_form.mnemonic, operands_reg ) if ( isa_data_reg is None and self._isa == "x86" - and instruction_form.instruction[-1] in self.GAS_SUFFIXES + and instruction_form.mnemonic[-1] in self.GAS_SUFFIXES ): # Check for instruction without GAS suffix isa_data_reg = self._isa_model.get_instruction( - instruction_form.instruction[:-1], operands_reg + instruction_form.mnemonic[:-1], operands_reg ) if ( isa_data_reg is None and self._isa == "aarch64" - and "." in instruction_form.instruction + and "." in instruction_form.mnemonic ): # Check for instruction without shape/cc suffix - suffix_start = instruction_form.instruction.index(".") + suffix_start = instruction_form.mnemonic.index(".") isa_data_reg = self._isa_model.get_instruction( - instruction_form.instruction[:suffix_start], operands_reg + instruction_form.mnemonic[:suffix_start], operands_reg ) if isa_data_reg: assign_default = False @@ -161,7 +161,7 @@ class ISASemantics(object): Empty dict if no changes of registers occured. None for registers with unknown changes. If only_postindexed is True, only considers changes due to post_indexed memory references. """ - if instruction_form.instruction is None: + if instruction_form.mnemonic is None: return {} dest_reg_names = [ (op.prefix if op.prefix is not None else "") + op.name @@ -172,22 +172,22 @@ class ISASemantics(object): if isinstance(op, RegisterOperand) ] isa_data = self._isa_model.get_instruction( - instruction_form.instruction, instruction_form.operands + instruction_form.mnemonic, instruction_form.operands ) if ( isa_data is None and self._isa == "x86" - and instruction_form.instruction[-1] in self.GAS_SUFFIXES + and instruction_form.mnemonic[-1] in self.GAS_SUFFIXES ): # Check for instruction without GAS suffix isa_data = self._isa_model.get_instruction( - instruction_form.instruction[:-1], instruction_form.operands + instruction_form.mnemonic[:-1], instruction_form.operands ) - if isa_data is None and self._isa == "aarch64" and "." in instruction_form.instruction: + if isa_data is None and self._isa == "aarch64" and "." in instruction_form.mnemonic: # Check for instruction without shape/cc suffix - suffix_start = instruction_form.instruction.index(".") + suffix_start = instruction_form.mnemonic.index(".") isa_data = self._isa_model.get_instruction( - instruction_form.instruction[:suffix_start], instruction_form.operands + instruction_form.mnemonic[:suffix_start], instruction_form.operands ) if only_postindexed: @@ -262,7 +262,7 @@ class ISASemantics(object): op_dict["src_dst"] = [] # handle dependency breaking instructions - if isa_data.breaks_dep and operands[1:] == operands[:-1]: + if isa_data.breaks_dependency_on_equal_operands and operands[1:] == operands[:-1]: op_dict["destination"] += operands if isa_data.hidden_operands != []: op_dict["destination"] += [hop for hop in isa_data.hidden_operands] diff --git a/osaca/semantics/kernel_dg.py b/osaca/semantics/kernel_dg.py index fe6b45a..464a6ef 100644 --- a/osaca/semantics/kernel_dg.py +++ b/osaca/semantics/kernel_dg.py @@ -592,8 +592,8 @@ class KernelDG(nx.DiGraph): graph.nodes[n]["fontsize"] = 11.0 else: node = graph.nodes[n]["instruction_form"] - if node.instruction is not None: - mapping[n] = "{}: {}".format(n, node.instruction) + if node.mnemonic is not None: + mapping[n] = "{}: {}".format(n, node.mnemonic) else: label = "label" if node.label is not None else None label = "directive" if node.directive is not None else label diff --git a/osaca/semantics/marker_utils.py b/osaca/semantics/marker_utils.py index 9ee3ddb..5f2eb4a 100644 --- a/osaca/semantics/marker_utils.py +++ b/osaca/semantics/marker_utils.py @@ -136,13 +136,13 @@ def find_marked_section( index_end = -1 for i, line in enumerate(lines): try: - if line.instruction is None and comments is not None and line.comment is not None: + if line.mnemonic is None and comments is not None and line.comment is not None: if comments["start"] == line.comment: index_start = i + 1 elif comments["end"] == line.comment: index_end = i elif ( - line.instruction in mov_instr + line.mnemonic in mov_instr and len(lines) > i + 1 and lines[i + 1].directive is not None ): @@ -172,8 +172,7 @@ def find_marked_section( # return line of the marker index_end = i except TypeError: - pass - # print("TESTER",i, line) + print(i, line) if index_start != -1 and index_end != -1: break return index_start, index_end @@ -226,9 +225,9 @@ def find_jump_labels(lines): for label in list(labels): if all( [ - line.instruction.startswith(".") + line.mnemonic.startswith(".") for line in lines[labels[label][0] : labels[label][1]] - if line.instruction is not None + if line.mnemonic is not None ] ): del labels[label] @@ -255,7 +254,7 @@ def find_basic_blocks(lines): terminate = False blocks[label].append(line) # Find end of block by searching for references to valid jump labels - if line.instruction is not None and line.operands != []: + if line.mnemonic is not None and line.operands != []: for operand in [o for o in line.operands if isinstance(o, IdentifierOperand)]: if operand.name in valid_jump_labels: terminate = True @@ -284,11 +283,11 @@ def find_basic_loop_bodies(lines): terminate = False current_block.append(line) # Find end of block by searching for references to valid jump labels - if line.instruction is not None and line.operands != []: + if line.mnemonic is not None and line.operands != []: # Ignore `b.none` instructions (relevant von ARM SVE code) # This branch instruction is often present _within_ inner loop blocks, but usually # do not terminate - if line.instruction == "b.none": + if line.mnemonic == "b.none": continue for operand in [o for o in line.operands if isinstance(o, IdentifierOperand)]: if operand.name in valid_jump_labels: diff --git a/tests/test_frontend.py b/tests/test_frontend.py index 4a0f33f..1436bd0 100755 --- a/tests/test_frontend.py +++ b/tests/test_frontend.py @@ -96,7 +96,7 @@ class TestFrontend(unittest.TestCase): line.latency_wo_load, analysis_dict["Kernel"][i]["LatencyWithoutLoad"] ) self.assertEqual(line.latency_cp, analysis_dict["Kernel"][i]["LatencyCP"]) - self.assertEqual(line.instruction, analysis_dict["Kernel"][i]["Instruction"]) + self.assertEqual(line.mnemonic, analysis_dict["Kernel"][i]["Instruction"]) self.assertEqual(len(line.operands), len(analysis_dict["Kernel"][i]["Operands"])) self.assertEqual( len(line.semantic_operands["source"]), @@ -133,7 +133,7 @@ class TestFrontend(unittest.TestCase): line.latency_wo_load, analysis_dict["Kernel"][i]["LatencyWithoutLoad"] ) self.assertEqual(line.latency_cp, analysis_dict["Kernel"][i]["LatencyCP"]) - self.assertEqual(line.instruction, analysis_dict["Kernel"][i]["Instruction"]) + self.assertEqual(line.mnemonic, analysis_dict["Kernel"][i]["Instruction"]) self.assertEqual(len(line.operands), len(analysis_dict["Kernel"][i]["Operands"])) self.assertEqual( len(line.semantic_operands["source"]), diff --git a/tests/test_parser_AArch64.py b/tests/test_parser_AArch64.py index b1e0350..0fa8985 100755 --- a/tests/test_parser_AArch64.py +++ b/tests/test_parser_AArch64.py @@ -203,7 +203,7 @@ class TestParserAArch64(unittest.TestCase): instruction_form_3 = InstructionForm( mnemonic=None, operands_id=[], - directive_id=DirectiveOperand(name="cfi_def_cfa", parameter_id=["w29", "-16"]), + directive_id=DirectiveOperand(name="cfi_def_cfa", parameters=["w29", "-16"]), comment_id=None, label_id=None, line=".cfi_def_cfa w29, -16",