45 lines
1.6 KiB
Python
45 lines
1.6 KiB
Python
"""
|
|
CAP, SSA Intro, Elimination and Optimisations
|
|
Functions to convert a CFG out of SSA Form.
|
|
"""
|
|
|
|
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.Terminator import BranchingTerminator, Return
|
|
from Lib.PhiNode import PhiNode
|
|
from TP05.SequentializeMoves import sequentialize_moves
|
|
|
|
|
|
def generate_moves_from_phis(phis: List[PhiNode], parent: Block) -> List[BlockInstr]:
|
|
"""
|
|
`generate_moves_from_phis(phis, parent)` builds a list of move instructions
|
|
to be inserted in a new block between `parent` and the block with phi nodes
|
|
`phis`.
|
|
|
|
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
|
|
|
|
|
|
def exit_ssa(cfg: CFG, is_smart: bool) -> None:
|
|
"""
|
|
`exit_ssa(cfg)` replaces phi nodes with move instructions to exit SSA form.
|
|
|
|
`is_smart` is set to true when smart register allocation is enabled (Lab 5b).
|
|
"""
|
|
for b in cfg.get_blocks():
|
|
phis = cast(List[PhiNode], b.get_phis()) # Use cast for Pyright
|
|
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")
|