Commit Lab 5a

This commit is contained in:
Rémi Di Guardia
2022-10-19 09:50:20 +02:00
parent deb7cc0b54
commit 5e8c7214d9
46 changed files with 2421 additions and 55 deletions
+70
View File
@@ -0,0 +1,70 @@
"""
CAP, SSA Intro, Elimination and Optimisations
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.PhiNode import PhiNode
from Lib.Dominators import computeDom, computeDT, computeDF
def insertPhis(cfg: CFG, DF: Dict[Block, Set[Block]]) -> None:
"""
`insertPhis(CFG, DF)` inserts phi nodes in `cfg` where needed.
At this point, phi nodes will look like `temp_x = φ(temp_x, ..., temp_x)`.
This is an helper function called during SSA entry.
"""
for var, defs in cfg.gather_defs().items():
has_phi: Set[Block] = set()
queue: List[Block] = list(defs)
while queue:
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")
def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Block) -> None:
"""
Rename variables from block b.
This is an auxiliary function for `rename_variables`.
"""
renamer = renamer.copy()
for i in b.get_all_statements():
if isinstance(i, Instruction | PhiNode):
i.rename(renamer)
for succ in cfg.out_blocks(b):
for i in succ._phis:
assert (isinstance(i, PhiNode))
i.rename_from(renamer, b.get_label())
# TODO recursive call(s) of rename_block (Lab 5a, Exercise 5)
def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None:
"""
Rename variables in the CFG, to transform `temp_x = φ(temp_x, ..., temp_x)`
into `temp_x = φ(temp_0, ... temp_n)`.
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)
def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
"""
Convert the CFG `cfg` into SSA Form:
compute the dominance frontier, then insert phi nodes and finally
rename variables accordingly.
`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")
+48
View File
@@ -0,0 +1,48 @@
"""
CAP, SSA Intro, Elimination and Optimisations
Functions to convert a CFG out of SSA Form.
"""
from typing import cast, List, Set, Tuple
from Lib import RiscV
from Lib.Graphes import DiGraph
from Lib.CFG import Block, BlockInstr, CFG
from Lib.Operands import (
Register, DataLocation,
Temporary)
from Lib.Statement import AbsoluteJump
from Lib.Terminator import BranchingTerminator, Return
from Lib.PhiNode import PhiNode
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._phis) # Use cast for Pyright
b._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")
+1
View File
@@ -0,0 +1 @@
Add your own tests in this directory.