This commit is contained in:
augustin64 2024-11-18 13:55:36 +01:00
parent 874b1e9b39
commit abcc75cdd4
2 changed files with 45 additions and 16 deletions

View File

@ -5,8 +5,8 @@ Functions to convert a CFG into SSA Form.
from typing import List, Dict, Set from typing import List, Dict, Set
from Lib.CFG import Block, CFG from Lib.CFG import Block, CFG
from Lib.Operands import Renamer from Lib.Operands import Renamer, Operand
from Lib.Statement import Instruction from Lib.Statement import Instruction, Label
from Lib.PhiNode import PhiNode from Lib.PhiNode import PhiNode
from Lib.Dominators import computeDom, computeDT, computeDF 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) d = queue.pop(0)
for b in DF[d]: for b in DF[d]:
if b not in has_phi: if b not in has_phi:
# TODO add a phi node in block `b` (Lab 5a, Exercise 4) srcs: Dict[Label, Operand] = {
raise NotImplementedError("insertPhis") 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: 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(): for i in succ.get_phis():
assert (isinstance(i, PhiNode)) assert (isinstance(i, PhiNode))
i.rename_from(renamer, b.get_label()) 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: 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. This is an helper function called during SSA entry.
""" """
renamer = Renamer(cfg.fdata._pool) 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: 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. `dom_graphs` indicates if we have to print the domination graphs.
`basename` is used for the names of the produced graphs. `basename` is used for the names of the produced graphs.
""" """
# TODO implement this function (Lab 5a, Exercise 2) dom = computeDom(cfg)
raise NotImplementedError("enter_ssa") DT = computeDT(cfg, dom, dom_graphs, basename)
DF = computeDF(cfg, dom, DT, dom_graphs, basename)
insertPhis(cfg, DF)
rename_variables(cfg, DT)

View File

@ -7,7 +7,7 @@ from typing import cast, List
from Lib import RiscV from Lib import RiscV
from Lib.CFG import Block, BlockInstr, CFG from Lib.CFG import Block, BlockInstr, CFG
from Lib.Operands import Temporary from Lib.Operands import Temporary
from Lib.Statement import AbsoluteJump from Lib.Statement import AbsoluteJump, Label
from Lib.Terminator import BranchingTerminator, Return from Lib.Terminator import BranchingTerminator, Return
from Lib.PhiNode import PhiNode from Lib.PhiNode import PhiNode
from TP05.SequentializeMoves import sequentialize_moves 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. 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) # (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: 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 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 parents: List[Block] = b.get_in().copy() # Copy as we modify it by adding blocks
for parent in parents: for parent in parents:
moves = generate_moves_from_phis(phis, parent) # Add the block containing 'moves' to 'cfg'
# TODO Add the block containing 'moves' to 'cfg' moves_label = cfg.fdata.fresh_label("merge_phi")
# and update edges and jumps accordingly (Lab 5a, Exercise 6) block_moves = Block(moves_label, generate_moves_from_phis(phis, parent), AbsoluteJump(b.get_label()))
raise NotImplementedError("exit_ssa") 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)