Source code for Lib.PhiNode

"""
Classes for φ nodes in a RiscV CFG :py:class:`CFG <Lib.CFG.CFG>` under SSA Form:
:py:class:`PhiNode` for a statement of the form temp_x = φ(temp_0, ..., temp_n).
These particular kinds of statements are expected to be in the field
b._phis for a :py:class:`Block <Lib.CFG.Block>` b.
"""

from dataclasses import dataclass
from typing import List, Dict

from Lib.Operands import Operand, Temporary, DataLocation, Renamer
from Lib.Statement import Statement, Label


[docs]@dataclass class PhiNode(Statement): """ A φ node is a renaming in the CFG, of the form temp_x = φ(temp_0, ..., temp_n). The field var contains the variable temp_x. The field srcs links each corresponding predecessor in the CFG ---identified by its label---, to the variable temp_i of the φ node. """ var: DataLocation srcs: Dict[Label, Operand]
[docs] def defined(self) -> List[Operand]: """Return the variable defined by the φ node.""" return [self.var]
[docs] def get_srcs(self) -> Dict[Label, Operand]: """ Return the dictionnary associating for each previous block the corresponding variable. """ return self.srcs
[docs] def used(self) -> List[Operand]: """Return the variables used by the statement.""" return list(self.srcs.values())
[docs] def rename(self, renamer: Renamer) -> None: """Rename the variable defined by the φ node with a fresh name.""" if isinstance(self.var, Temporary): self.var = renamer.fresh(self.var)
[docs] def rename_from(self, renamer: Renamer, label: Label) -> None: """Rename the variable associated to the block identified by `label`.""" if label in self.srcs: t = self.srcs[label] if isinstance(t, Temporary): if renamer.defined(t): self.srcs[label] = renamer.replace(t) else: del self.srcs[label]
def __str__(self): return "{} = φ({})".format(self.var, self.srcs) def __hash__(self): return hash((self.var, *self.srcs.items()))
[docs] def printIns(self, stream): print(' # ' + str(self), file=stream)