From a5f9c1581319a032cf498ffaf84e6e27e8638143 Mon Sep 17 00:00:00 2001 From: alexcere <48130030+alexcere@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:33:16 +0100 Subject: [PATCH] Pretty generation of intermediate artifacts --- src/execution/main_execution.py | 12 +++++------- src/liveness/layout_generation.py | 30 +++++++++++++++++++----------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/execution/main_execution.py b/src/execution/main_execution.py index 1c3c1f9..9fc8456 100644 --- a/src/execution/main_execution.py +++ b/src/execution/main_execution.py @@ -70,11 +70,13 @@ def yul_cfg_dict_from_format(input_format: str, filename: str, contract: Optiona raise ValueError(f"Input format {input_format} not recognized.") -def analyze_single_cfg(cfg: CFG, final_dir: Path, dot_file_dir: Path, args: argparse.Namespace): +def analyze_single_cfg(cfg: CFG, final_dir: Path, args: argparse.Namespace): + dot_file_dir = final_dir.joinpath("liveness") + dot_file_dir.mkdir(exist_ok=True, parents=True) tags_dict = preprocess_cfg(cfg, dot_file_dir, args.visualize) x = dtimer() - jsons_list = layout_generation(cfg, dot_file_dir) + jsons_list = layout_generation(cfg, final_dir.joinpath("stack_layouts")) sfs_final_dir = final_dir.joinpath("sfs") sfs_final_dir.mkdir(exist_ok=True, parents=True) @@ -136,11 +138,7 @@ def main(): for cfg_name, cfg in cfgs.items(): cfg_dir = final_dir.joinpath(cfg_name) - - dot_file_dir = cfg_dir.joinpath("liveness") - dot_file_dir.mkdir(exist_ok=True, parents=True) - - json_asm_contract = analyze_single_cfg(cfg, cfg_dir, dot_file_dir, args) + json_asm_contract = analyze_single_cfg(cfg, cfg_dir, args) asm_output = asm_output | json_asm_contract diff --git a/src/liveness/layout_generation.py b/src/liveness/layout_generation.py index a3140c8..992aa2f 100644 --- a/src/liveness/layout_generation.py +++ b/src/liveness/layout_generation.py @@ -248,19 +248,27 @@ def __init__(self, object_id: str, block_list: CFGBlockList, liveness_info: Dict self._start = block_list.start_block + _tree_dir = name.joinpath("tree") + _tree_dir.mkdir(exist_ok=True, parents=True) + immediate_dominators = nx.immediate_dominators(self._cfg_graph, self._start) self._dominance_tree = nx.DiGraph([v, u] for u, v in immediate_dominators.items() if u != self._start) self._dominance_tree.add_node(self._start) - nx.nx_agraph.write_dot(self._dominance_tree, name) + nx.nx_agraph.write_dot(self._dominance_tree, _tree_dir.joinpath(f"{object_id}.dot")) self._block_order = list(nx.topological_sort(self._dominance_tree)) self._variable_order = compute_variable_depth(liveness_info, self._block_order) renamed_graph = information_on_graph(self._cfg_graph, {name: var_order_repr(name, assignments) for name, assignments in self._variable_order.items()}) - nx.nx_agraph.write_dot(renamed_graph, Path(name.parent).joinpath(name.stem + "_vars.dot")) - self._dir = name + _var_dir = name.joinpath("var_order") + _var_dir.mkdir(exist_ok=True, parents=True) + nx.nx_agraph.write_dot(renamed_graph, _var_dir.joinpath(f"{object_id}.dot")) + + self._layout_dir = name.joinpath("layouts") + self._layout_dir.mkdir(exist_ok=True, parents=True) + # Guess: we need to traverse the code following the dominance tree in topological order # This is because in the dominance tree together with the SSA, all the nodes @@ -301,7 +309,6 @@ def _construct_code_from_block(self, block: CFGBlock, input_stacks: Dict[str, Li # a stack, we need to assign the same stack next_block_id, elements_to_unify, phi_instructions = self._unification_dict.get(block_id, (None, [], [])) output_stack = None - print(block_id, comes_from, elements_to_unify) if len(elements_to_unify) > 1: @@ -338,7 +345,6 @@ def _construct_code_from_block(self, block: CFGBlock, input_stacks: Dict[str, Li output_stacks[block_id] = output_stack # We build the corresponding specification - print(block_id) block_json = block.build_spec(input_stack, output_stack) return block_json @@ -388,14 +394,13 @@ def build_layout(self): Builds the layout of the blocks from the given representation """ json_info = self._construct_code_from_block_list() - print(json_info.keys()) renamed_graph = information_on_graph(self._cfg_graph, {block_name: print_stacks(block_name, json_info[block_name]) for block_name in self._block_list.blocks}) - nx.nx_agraph.write_dot(renamed_graph, Path(self._dir.parent).joinpath(self._dir.stem + "_stacks.dot")) + nx.nx_agraph.write_dot(renamed_graph, self._layout_dir.joinpath(f"{self._component_id}.dot")) return json_info @@ -419,7 +424,7 @@ def layout_generation_cfg(cfg: CFG, final_dir: Path = Path(".")) -> Dict[str, SM short_component_name = shorten_name(component_name) layout = LayoutGeneration(component_name, component2block_list[component_name], liveness, component2inputs, - final_dir.joinpath(f"{short_component_name}_dominated.dot"), digraph) + final_dir, digraph) layout_blocks = layout.build_layout() jsons.update(layout_blocks) @@ -427,13 +432,16 @@ def layout_generation_cfg(cfg: CFG, final_dir: Path = Path(".")) -> Dict[str, SM return jsons -def layout_generation(cfg: CFG, final_dir: Path = Path(".")) -> List[Dict[str, SMS_T]]: +def layout_generation(cfg: CFG, final_dir: Path = Path("."), position: int = 0) -> List[Dict[str, SMS_T]]: """ Returns the information from the liveness analysis and also stores a dot file for each analyzed structure in "final_dir" """ - layouts_per_cfg = [layout_generation_cfg(cfg, final_dir)] + layout_dir = final_dir.joinpath(str(position)) + layout_dir.mkdir(parents=True, exist_ok=True) + + layouts_per_cfg = [layout_generation_cfg(cfg, layout_dir)] if cfg.subObjects is not None: - layouts_per_cfg.extend(layout_generation(cfg.subObjects, final_dir)) + layouts_per_cfg.extend(layout_generation(cfg.subObjects, final_dir, position + 1)) return layouts_per_cfg