From abcc75cdd417013a647149971afc15ace177808d Mon Sep 17 00:00:00 2001 From: augustin64 Date: Mon, 18 Nov 2024 13:55:36 +0100 Subject: [PATCH] TP05a --- MiniC/TP05/EnterSSA.py | 27 +++++++++++++++++++-------- MiniC/TP05/ExitSSA.py | 34 ++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/MiniC/TP05/EnterSSA.py b/MiniC/TP05/EnterSSA.py index 757c702..15be737 100644 --- a/MiniC/TP05/EnterSSA.py +++ b/MiniC/TP05/EnterSSA.py @@ -5,8 +5,8 @@ Functions to convert a CFG into SSA Form. from typing import List, Dict, Set from Lib.CFG import Block, CFG -from Lib.Operands import Renamer -from Lib.Statement import Instruction +from Lib.Operands import Renamer, Operand +from Lib.Statement import Instruction, Label from Lib.PhiNode import PhiNode from Lib.Dominators import computeDom, computeDT, computeDF @@ -25,8 +25,14 @@ def insertPhis(cfg: CFG, DF: Dict[Block, Set[Block]]) -> None: d = queue.pop(0) for b in DF[d]: if b not in has_phi: - # TODO add a phi node in block `b` (Lab 5a, Exercise 4) - raise NotImplementedError("insertPhis") + srcs: Dict[Label, Operand] = { + x.get_label(): var for x in b.get_in() + } + phi = PhiNode(var, srcs) + b.add_phi(phi) + + queue.append(b) + has_phi.add(b) def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Block) -> None: @@ -43,7 +49,8 @@ def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Blo for i in succ.get_phis(): assert (isinstance(i, PhiNode)) i.rename_from(renamer, b.get_label()) - # TODO recursive call(s) of rename_block (Lab 5a, Exercise 5) + for succ in DT[b]: + rename_block(cfg, DT, renamer, succ) def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None: @@ -54,7 +61,8 @@ def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None: This is an helper function called during SSA entry. """ renamer = Renamer(cfg.fdata._pool) - # TODO initial call(s) to rename_block (Lab 5a, Exercise 5) + for b in cfg.get_entries(): + rename_block(cfg, DT, renamer, b) def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None: @@ -66,5 +74,8 @@ def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None: `dom_graphs` indicates if we have to print the domination graphs. `basename` is used for the names of the produced graphs. """ - # TODO implement this function (Lab 5a, Exercise 2) - raise NotImplementedError("enter_ssa") + dom = computeDom(cfg) + DT = computeDT(cfg, dom, dom_graphs, basename) + DF = computeDF(cfg, dom, DT, dom_graphs, basename) + insertPhis(cfg, DF) + rename_variables(cfg, DT) \ No newline at end of file diff --git a/MiniC/TP05/ExitSSA.py b/MiniC/TP05/ExitSSA.py index d705e86..bf7209e 100644 --- a/MiniC/TP05/ExitSSA.py +++ b/MiniC/TP05/ExitSSA.py @@ -7,7 +7,7 @@ from typing import cast, List from Lib import RiscV from Lib.CFG import Block, BlockInstr, CFG from Lib.Operands import Temporary -from Lib.Statement import AbsoluteJump +from Lib.Statement import AbsoluteJump, Label from Lib.Terminator import BranchingTerminator, Return from Lib.PhiNode import PhiNode from TP05.SequentializeMoves import sequentialize_moves @@ -21,10 +21,13 @@ def generate_moves_from_phis(phis: List[PhiNode], parent: Block) -> List[BlockIn This is an helper function called during SSA exit. """ - moves: List[BlockInstr] = [] - # TODO compute 'moves', a list of 'mv' instructions to insert under parent # (Lab 5a, Exercise 6) - return moves + return [ + RiscV.mv( + phi.defined()[0], + phi.get_srcs()[parent.get_label()] + ) for phi in phis if parent.get_label() in phi.get_srcs() + ] def exit_ssa(cfg: CFG, is_smart: bool) -> None: @@ -38,7 +41,22 @@ def exit_ssa(cfg: CFG, is_smart: bool) -> None: b.remove_all_phis() # Remove all phi nodes in the block parents: List[Block] = b.get_in().copy() # Copy as we modify it by adding blocks for parent in parents: - moves = generate_moves_from_phis(phis, parent) - # TODO Add the block containing 'moves' to 'cfg' - # and update edges and jumps accordingly (Lab 5a, Exercise 6) - raise NotImplementedError("exit_ssa") + # Add the block containing 'moves' to 'cfg' + moves_label = cfg.fdata.fresh_label("merge_phi") + block_moves = Block(moves_label, generate_moves_from_phis(phis, parent), AbsoluteJump(b.get_label())) + cfg.add_block(block_moves) + + # Update parent terminator + j = parent.get_terminator() + match j: + case AbsoluteJump(): + new_terminator = AbsoluteJump(moves_label) + case BranchingTerminator(): + lbl_else : Label = moves_label if (j.label_else == b.get_label()) else j.label_else + lbl_then : Label = moves_label if (j.label_then == b.get_label()) else j.label_then + new_terminator = BranchingTerminator(j.cond, j.op1, j.op2, lbl_else, lbl_then) + case Return(): + new_terminator = AbsoluteJump(moves_label) + block_moves.set_terminator(Return()) + + parent.set_terminator(new_terminator)