diff --git a/PLANNING.md b/PLANNING.md index 6d9724e..355ddc7 100644 --- a/PLANNING.md +++ b/PLANNING.md @@ -105,4 +105,11 @@ _Academic first semester 2024-2025_ # Week 10: -- :notebook: TD: Thursday 25/11/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino) +- :notebook: TD: Monday 25/11/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino) + +# Week 11: + +- :hammer: Choice Lab (1/3): Monday 02/12/2024, 8h00-13h30. Room E001 (Samuel Humeau & Emma Nardino) + + * Optimisations under SSA form [TP5c](TP05/tp5c.pdf), code in [MiniC/TPoptim/](MiniC/TPoptim/). + * Other possibilities next week. diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo index f2ba597..1f994e9 100644 --- a/docs/html/.buildinfo +++ b/docs/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 33a23b4514891ef44049bf19634072fc +config: 486d1ff73ffb3f41d31651516deff8a8 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/html/_modules/Lib/Allocator.html b/docs/html/_modules/Lib/Allocator.html index 2c64d77..0abe9c5 100644 --- a/docs/html/_modules/Lib/Allocator.html +++ b/docs/html/_modules/Lib/Allocator.html @@ -92,7 +92,7 @@
[docs]class Allocator(): - """General base class for Naive, AllInMem and Smart Allocators. + """General base class for Naive, AllInMem and Smart Allocators. Replace all temporaries in the code with actual data locations. Allocation is done in two steps: @@ -118,23 +118,23 @@ pass
[docs] def replace(self, old_instr: Instruction) -> List[Instruction]: - """Transform an instruction with temporaries into a list of instructions.""" + """Transform an instruction with temporaries into a list of instructions.""" return [old_instr]
[docs] def rewriteCode(self, listcode) -> None: - """Modify the code to replace temporaries with + """Modify the code to replace temporaries with registers or memory locations. """ listcode.iter_statements(self.replace)
[docs]class NaiveAllocator(Allocator): - """Naive Allocator: try to assign a register to each temporary, + """Naive Allocator: try to assign a register to each temporary, fails if there are more temporaries than registers. """
[docs] def replace(self, old_instr: Instruction) -> List[Instruction]: - """Replace Temporary operands with the corresponding allocated Register.""" + """Replace Temporary operands with the corresponding allocated Register.""" new_args: List[Operand] = [] for arg in old_instr.args(): if isinstance(arg, Temporary): @@ -145,7 +145,7 @@ return [new_instr]
[docs] def prepare(self) -> None: - """Allocate all temporaries to registers. + """Allocate all temporaries to registers. Fail if there are too many temporaries.""" regs = list(GP_REGS) # Get a writable copy temp_allocation: Dict[Temporary, DataLocation] = dict() diff --git a/docs/html/_modules/Lib/CFG.html b/docs/html/_modules/Lib/CFG.html index 12e2257..6764529 100644 --- a/docs/html/_modules/Lib/CFG.html +++ b/docs/html/_modules/Lib/CFG.html @@ -102,7 +102,7 @@
[docs]class Block: - """ + """ A basic block of a :py:class:`CFG` is made of three main parts: - a start :py:class:`label <Lib.Statement.Label>` that uniquely identifies the block in the CFG @@ -138,7 +138,7 @@ return s
[docs] def to_dot(self) -> str: # pragma: no cover - """Outputs all statements of the block as a string.""" + """Outputs all statements of the block as a string.""" # dot is weird: lines ending with \l instead of \n are left-aligned. NEWLINE = '\\l ' instr = [] @@ -153,11 +153,11 @@ return str(self._label)
[docs] def get_body(self) -> List[BlockInstr]: - """Return the statements in the body of the block (no phi-node nor the terminator).""" + """Return the statements in the body of the block (no phi-node nor the terminator).""" return self._instructions
[docs] def get_all_statements(self) -> List[Statement]: - """ + """ Return all statements of the block (including phi-nodes and the terminator, but not the label of the block). """ @@ -166,7 +166,7 @@ [self.get_terminator()])
[docs] def get_body_and_terminator(self) -> List[Statement]: - """ + """ Return all statements of the block, except phi-nodes (and the label of the block). """ @@ -174,39 +174,39 @@ [self.get_terminator()])
[docs] def get_label(self) -> Label: - """Return the label of the block.""" + """Return the label of the block.""" return self._label
[docs] def get_in(self) -> List['Block']: - """Return the list of blocks with an edge to the considered block.""" + """Return the list of blocks with an edge to the considered block.""" return self._in
[docs] def get_terminator(self) -> Terminator: - """Return the terminator of the block.""" + """Return the terminator of the block.""" return self._terminator
[docs] def set_terminator(self, term: Terminator) -> None: - """Set the terminator of the block.""" + """Set the terminator of the block.""" self._terminator = term
[docs] def get_phis(self) -> List[Statement]: - """Return the list of all φ instructions of the block.""" + """Return the list of all φ instructions of the block.""" return self._phis
[docs] def add_phi(self, phi: Statement) -> None: - """Add a φ instruction to the block.""" + """Add a φ instruction to the block.""" self._phis.append(phi)
[docs] def set_phis(self, phis: List[Statement]) -> None: - """Replace the φ instructions in the block by the given list `phis`.""" + """Replace the φ instructions in the block by the given list `phis`.""" self._phis = phis
[docs] def remove_all_phis(self) -> None: - """Remove all φ instructions in the block.""" + """Remove all φ instructions in the block.""" self._phis = []
[docs] def iter_statements(self, f) -> None: - """Iterate over instructions. + """Iterate over instructions. For each real instruction i (not label or comment), replace it with the list of instructions given by f(i). @@ -225,12 +225,12 @@ .format(self.get_terminator(), end_statements))
[docs] def add_instruction(self, instr: BlockInstr) -> None: - """Add an instruction to the body of the block.""" + """Add an instruction to the body of the block.""" self._instructions.append(instr)
[docs]class CFG: - """ + """ A complete control-flow graph representing a function. This class is mainly made of a list of basic :py:class:`Block`, a label indicating the :py:meth:`entry point of the function <get_start>`, @@ -254,7 +254,7 @@ self._end = self.fdata.fresh_label("end") def _init_blks(self) -> None: - """Add a block for division by 0.""" + """Add a block for division by 0.""" # Label for the address of the error message # This address is added by print_code label_div_by_zero_msg = Label(self.fdata._label_div_by_zero.name + "_msg") @@ -267,53 +267,53 @@ self.add_block(blk)
[docs] def get_start(self) -> Label: - """Return the entry label of the CFG.""" + """Return the entry label of the CFG.""" return self._start
[docs] def set_start(self, start: Label) -> None: - """Set the entry label of the CFG.""" + """Set the entry label of the CFG.""" assert (start in self._blocks) self._start = start
[docs] def get_end(self) -> Label: - """Return the exit label of the CFG.""" + """Return the exit label of the CFG.""" return self._end
[docs] def add_block(self, blk: Block) -> None: - """Add a new block to the CFG.""" + """Add a new block to the CFG.""" self._blocks[blk._label] = blk
[docs] def get_block(self, name: Label) -> Block: - """Return the block with label `name`.""" + """Return the block with label `name`.""" return self._blocks[name]
[docs] def get_blocks(self) -> List[Block]: - """Return all the blocks.""" + """Return all the blocks.""" return [b for b in self._blocks.values()]
[docs] def get_entries(self) -> List[Block]: - """Return all the blocks with no predecessors.""" + """Return all the blocks with no predecessors.""" return [b for b in self._blocks.values() if not b.get_in()]
[docs] def add_edge(self, src: Block, dest: Block) -> None: - """Add the edge src -> dest in the control flow graph.""" + """Add the edge src -> dest in the control flow graph.""" dest.get_in().append(src)
# assert (dest.get_label() in src.get_terminator().targets())
[docs] def remove_edge(self, src: Block, dest: Block) -> None: - """Remove the edge src -> dest in the control flow graph.""" + """Remove the edge src -> dest in the control flow graph.""" dest.get_in().remove(src)
# assert (dest.get_label() not in src.get_terminator().targets())
[docs] def out_blocks(self, block: Block) -> List[Block]: - """ + """ Return the list of blocks in the CFG targeted by the Terminator of Block block. """ return [self.get_block(dest) for dest in block.get_terminator().targets()]
[docs] def gather_defs(self) -> Dict[Any, Set[Block]]: - """ + """ Return a dictionary associating variables to all the blocks containing one of their definitions. """ @@ -328,12 +328,12 @@ return defs
[docs] def iter_statements(self, f) -> None: - """Apply f to all instructions in all the blocks.""" + """Apply f to all instructions in all the blocks.""" for b in self.get_blocks(): b.iter_statements(f)
[docs] def linearize_naive(self) -> Iterator[Statement]: - """ + """ Linearize the given control flow graph as a list of instructions. Naive procedure that adds jumps everywhere. """ @@ -353,13 +353,13 @@
[docs] def print_code(self, output, linearize=(lambda cfg: list(cfg.linearize_naive())), comment=None) -> None: - """Print the linearization of the CFG.""" + """Print the linearization of the CFG.""" statements = linearize(self) _print_code(statements, self.fdata, output, init_label=self._start, fin_label=self._end, fin_div0=False, comment=comment)
[docs] def print_dot(self, filename, DF=None, view=False) -> None: # pragma: no cover - """Print the CFG as a graph.""" + """Print the CFG as a graph.""" graph = Digraph() # nodes for name, blk in self._blocks.items(): diff --git a/docs/html/_modules/Lib/Dominators.html b/docs/html/_modules/Lib/Dominators.html index 7c2f30f..657816f 100644 --- a/docs/html/_modules/Lib/Dominators.html +++ b/docs/html/_modules/Lib/Dominators.html @@ -92,7 +92,7 @@
[docs]def computeDom(cfg: CFG) -> Dict[Block, Set[Block]]: - """ + """ `computeDom(cfg)` computes the table associating blocks to their dominators in `cfg`. It works by solving the equation system. @@ -123,7 +123,7 @@
[docs]def printDT(filename: str, graph: Dict[Block, Set[Block]]) -> None: # pragma: no cover - """Display a graphical rendering of the given domination tree.""" + """Display a graphical rendering of the given domination tree.""" dot = Digraph() for k in graph: dot.node(str(k.get_label())) @@ -135,7 +135,7 @@
[docs]def computeDT(cfg: CFG, dominators: Dict[Block, Set[Block]], dom_graphs: bool, basename: str) -> Dict[Block, Set[Block]]: - """ + """ `computeDT(cfg, dominators)` computes the domination tree of `cfg` using the previously computed `dominators`. It returns `DT`, a dictionary which associates a block with its children @@ -174,7 +174,7 @@ DT: Dict[Block, Set[Block]], b: Block, DF: Dict[Block, Set[Block]]) -> None: - """ + """ `_computeDF_at_block(...)` computes the dominance frontier at the given block, by updating `DF`. @@ -192,7 +192,7 @@
[docs]def computeDF(cfg: CFG, dominators: Dict[Block, Set[Block]], DT: Dict[Block, Set[Block]], dom_graphs: bool, basename: str ) -> Dict[Block, Set[Block]]: - """ + """ `computeDF(...)` computes the dominance frontier of a CFG. It returns `DF` which associates a block to its frontier. diff --git a/docs/html/_modules/Lib/FunctionData.html b/docs/html/_modules/Lib/FunctionData.html index d4179ba..ef804b1 100644 --- a/docs/html/_modules/Lib/FunctionData.html +++ b/docs/html/_modules/Lib/FunctionData.html @@ -94,7 +94,7 @@
[docs]class FunctionData: - """ + """ Stores some metadata on a RiscV function: name of the function, label names, temporary variables (using :py:class:`Lib.Operands.TemporaryPool`), @@ -119,18 +119,18 @@ self._label_div_by_zero = self.fresh_label("div_by_zero")
[docs] def get_name(self) -> str: - """Return the name of the function.""" + """Return the name of the function.""" return self._name
[docs] def fresh_tmp(self) -> Temporary: - """ + """ Return a new fresh Temporary, which is added to the pool. """ return self._pool.fresh_tmp()
[docs] def fresh_offset(self) -> Offset: - """ + """ Return a new offset in the memory stack. Offsets are decreasing relative to FP. """ @@ -144,20 +144,20 @@ return Offset(FP, -8 * self._dec)
[docs] def get_offset(self) -> int: - """ + """ Return the current offset in the memory stack. """ return self._dec
def _fresh_label_name(self, name) -> str: - """ + """ Return a new unique label name based on the given string. """ self._nblabel = self._nblabel + 1 return name + "_" + str(self._nblabel) + "_" + self._name
[docs] def fresh_label(self, name) -> Label: - """ + """ Return a new label, with a unique name based on the given string. """ return Label(self._fresh_label_name(name))
@@ -171,7 +171,7 @@ def _iter_statements( listIns: List[_T], f: Callable[[_T], List[_T]]) -> List[_T | Comment]: - """Iterate over instructions. + """Iterate over instructions. For each real instruction i (not label or comment), replace it with the list of instructions given by f(i). """ @@ -191,7 +191,7 @@ def _print_code(listIns: List, fdata: FunctionData, output, init_label=None, fin_label=None, fin_div0=False, comment=None) -> None: - """ + """ Please use print_code from LinearCode or CFG, not directly this one. Print the instructions from listIns, forming fdata, on output. @@ -214,9 +214,9 @@ # We use t0 because it is caller-saved output.write(""" .text - .globl {0} + .globl {0} {0}: - li t0, {1} + li t0, {1} sub sp, sp, t0 sd ra, 0(sp) sd fp, 8(sp) @@ -226,7 +226,7 @@ if init_label is not None: # Add a jump to init_label before the generated code. output.write(""" - j {0} + j {0} """.format(init_label)) output.write("\n\n##Generated Code\n") # Generated code @@ -243,7 +243,7 @@ output.write(""" ld ra, 0(sp) ld fp, 8(sp) - li t0, {0} + li t0, {0} add sp, sp, t0 ret """.format(cardoffset)) diff --git a/docs/html/_modules/Lib/Graphes.html b/docs/html/_modules/Lib/Graphes.html index 049b6c4..8530b26 100644 --- a/docs/html/_modules/Lib/Graphes.html +++ b/docs/html/_modules/Lib/Graphes.html @@ -87,7 +87,7 @@
[docs]class GraphError(Exception): - """Exception raised for self loops. + """Exception raised for self loops. """ message: str @@ -97,7 +97,7 @@
[docs]class GeneralGraph(object): - """ + """ General class regrouping similarities between directed and non oriented graphs. The only differences between the two are: @@ -113,7 +113,7 @@ graph_dict: Dict[Any, Set] def __init__(self, graph_dict=None): - """ + """ Initializes a graph object. If no dictionary or None is given, an empty dictionary will be used. @@ -123,11 +123,11 @@ self.graph_dict = graph_dict
[docs] def vertices(self) -> List[Any]: - """Return the vertices of a graph.""" + """Return the vertices of a graph.""" return list(self.graph_dict.keys())
[docs] def add_vertex(self, vertex: Any) -> None: - """ + """ If the vertex "vertex" is not in self.graph_dict, a key "vertex" with an empty list as a value is added to the dictionary. @@ -137,7 +137,7 @@ self.graph_dict[vertex] = set()
[docs] def edges(self) -> List[Set]: - """Return the edges of the graph.""" + """Return the edges of the graph.""" return []
def __str__(self): @@ -150,7 +150,7 @@ return res
[docs] def dfs_traversal(self, root: Any) -> List[Any]: - """ + """ Compute a depth first search of the graph, from the vertex root. """ @@ -165,11 +165,11 @@ return seen
[docs] def is_reachable_from(self, v1: Any, v2: Any) -> bool: - """True if there is a path from v1 to v2.""" + """True if there is a path from v1 to v2.""" return v2 in self.dfs_traversal(v1)
[docs] def connected_components(self) -> List[List[Any]]: - """ + """ Compute the list of all connected components of the graph, each component being a list of vetices. """ @@ -183,7 +183,7 @@ return components
[docs] def bfs_traversal(self, root: Any) -> List[Any]: - """ + """ Compute a breadth first search of the graph, from the vertex root. """ @@ -199,10 +199,10 @@
[docs]class Graph(GeneralGraph): - """Class for non oriented graphs.""" + """Class for non oriented graphs."""
[docs] def edges(self) -> List[Set]: - """ + """ A static method generating the set of edges (they appear twice in the dictionnary). Return a list of sets. @@ -215,7 +215,7 @@ return edges
[docs] def add_edge(self, edge: Tuple[Any, Any]) -> None: - """ + """ Add an edge in the graph. edge should be a pair and not (c,c) (we call g.add_edge((v1,v2))) @@ -234,7 +234,7 @@ self.graph_dict[vertex2] = {vertex1}
[docs] def print_dot(self, name: str, colors={}) -> None: - """Print the graph.""" + """Print the graph.""" color_names = ['red', 'blue', 'green', 'yellow', 'cyan', 'magenta'] + \ [f"grey{i}" for i in range(0, 100, 10)] color_shapes = ['ellipse', 'box', 'diamond', 'trapezium', 'egg', @@ -261,20 +261,20 @@ dot.render(name, view=True) # print in pdf
[docs] def delete_vertex(self, vertex: Any) -> None: - """Delete a vertex and all the adjacent edges.""" + """Delete a vertex and all the adjacent edges.""" gdict = self.graph_dict for neighbour in gdict[vertex]: gdict[neighbour].remove(vertex) del gdict[vertex]
[docs] def delete_edge(self, edge: Tuple[Any, Any]): - """Delete an edge.""" + """Delete an edge.""" (v1, v2) = edge self.graph_dict[v1].remove(v2) self.graph_dict[v2].remove(v1)
[docs] def color(self) -> Dict[Any, int]: - """ + """ Color the graph with an unlimited number of colors. Return a dict vertex -> color, where color is an integer (0, 1, ...). """ @@ -283,7 +283,7 @@ # see algo of the course
[docs] def color_with_k_colors(self, K=None, avoidingnodes=()) -> Tuple[Dict[Any, int], bool, List]: - """ + """ Color with <= K colors (if K is unspecified, use unlimited colors). Return 3 values: @@ -336,18 +336,18 @@
[docs]class DiGraph(GeneralGraph): - """Class for directed graphs.""" + """Class for directed graphs."""
[docs] def pred(self, v: Any) -> Set: - """Return all predecessors of the vertex `v` in the graph.""" + """Return all predecessors of the vertex `v` in the graph.""" return {src for src, dests in self.graph_dict.items() if v in dests}
[docs] def neighbourhoods(self) -> List[Tuple[Any, Set]]: - """Return all neighbourhoods in the graph.""" + """Return all neighbourhoods in the graph.""" return list(self.graph_dict.items())
[docs] def edges(self) -> List[Set]: - """ A static method generating the set of edges""" + """ A static method generating the set of edges""" edges = [] for vertex in self.graph_dict: for neighbour in self.graph_dict[vertex]: @@ -355,7 +355,7 @@ return edges
[docs] def add_edge(self, edge: Tuple[Any, Any]) -> None: - """ + """ Add an edge in the graph. edge should be a pair and not (c,c) (we call g.add_edge((v1,v2))) @@ -369,7 +369,7 @@ self.graph_dict[vertex2] = set()
[docs] def print_dot(self, name: str) -> None: - """Print the graph.""" + """Print the graph.""" dot = Digraph(comment='Conflict Graph') for k in self.graph_dict: shape = None @@ -381,14 +381,14 @@ dot.render(name, view=True) # print in pdf
[docs] def delete_vertex(self, vertex: Any) -> None: - """Delete a vertex and all the adjacent edges.""" + """Delete a vertex and all the adjacent edges.""" for node, neighbours in self.graph_dict.items(): if vertex in neighbours: neighbours.remove(vertex) del self.graph_dict[vertex]
[docs] def delete_edge(self, edge: Tuple[Any, Any]) -> None: - """Delete an edge.""" + """Delete an edge.""" (v1, v2) = edge self.graph_dict[v1].remove(v2)
diff --git a/docs/html/_modules/Lib/LinearCode.html b/docs/html/_modules/Lib/LinearCode.html index 63046f3..cc12086 100644 --- a/docs/html/_modules/Lib/LinearCode.html +++ b/docs/html/_modules/Lib/LinearCode.html @@ -97,7 +97,7 @@
[docs]class LinearCode: - """ + """ Representation of a RiscV program as a list of instructions. :py:meth:`add_instruction` is repeatedly called in the codegen visitor @@ -111,7 +111,7 @@ the RiscV program to a file. """ - """ + """ The :py:attr:`fdata` member variable contains some meta-information on the program, for instance to allocate a new temporary. See :py:class:`Lib.FunctionData.FunctionData`. @@ -125,7 +125,7 @@ self.fdata = FunctionData(name)
[docs] def add_instruction(self, i: CodeStatement) -> None: - """ + """ Utility function to add an instruction in the program. See also :py:mod:`Lib.RiscV` to generate relevant instructions. @@ -133,7 +133,7 @@ self._listIns.append(i)
[docs] def iter_statements(self, f) -> None: - """Iterate over instructions. + """Iterate over instructions. For each real instruction i (not label or comment), replace it with the list of instructions given by f(i). """ @@ -144,20 +144,20 @@ self._listIns = new_list_ins
[docs] def get_instructions(self) -> List[CodeStatement]: - """Return the list of instructions of the program.""" + """Return the list of instructions of the program.""" return self._listIns
# each instruction has its own "add in list" version
[docs] def add_label(self, s: Label) -> None: - """Add a label in the program.""" + """Add a label in the program.""" return self.add_instruction(s)
[docs] def add_comment(self, s: str) -> None: - """Add a comment in the program.""" + """Add a comment in the program.""" self.add_instruction(Comment(s))
[docs] def add_instruction_PRINTLN_INT(self, reg: DataLocation) -> None: - """Print integer value, with newline. (see Expand)""" + """Print integer value, with newline. (see Expand)""" # A print instruction generates the temp it prints. self.add_instruction(mv(A0, reg)) self.add_instruction(call(Function('println_int')))
@@ -166,12 +166,12 @@ return '\n'.join(map(str, self._listIns))
[docs] def print_code(self, output, comment=None) -> None: - """Outputs the RiscV program as text to a file at the given path.""" + """Outputs the RiscV program as text to a file at the given path.""" _print_code(self._listIns, self.fdata, output, init_label=None, fin_label=None, fin_div0=True, comment=comment)
[docs] def print_dot(self, filename: str, DF=None, view=False) -> None: # pragma: no cover - """Outputs the RiscV program as graph to a file at the given path.""" + """Outputs the RiscV program as graph to a file at the given path.""" # import graphviz here so that students who don't have it can still work on lab4 from graphviz import Digraph graph = Digraph() diff --git a/docs/html/_modules/Lib/Operands.html b/docs/html/_modules/Lib/Operands.html index 16ce5a7..e2aead9 100644 --- a/docs/html/_modules/Lib/Operands.html +++ b/docs/html/_modules/Lib/Operands.html @@ -118,7 +118,7 @@
[docs]class Condition(Operand): - """Condition, i.e. comparison operand for a CondJump. + """Condition, i.e. comparison operand for a CondJump. Example usage : @@ -144,7 +144,7 @@ raise MiniCInternalError(f"Unsupported comparison operator {optype}")
[docs] def negate(self) -> 'Condition': - """Return the opposite condition.""" + """Return the opposite condition.""" return Condition(opnot_dict[self._op])
def __str__(self): @@ -152,7 +152,7 @@
[docs]class Function(Operand): - """Operand for build-in function call.""" + """Operand for build-in function call.""" _name: str @@ -164,7 +164,7 @@
[docs]class DataLocation(Operand): - """ A Data Location is either a register, a temporary + """ A Data Location is either a register, a temporary or a place in memory (offset). """ @@ -181,7 +181,7 @@
[docs]class Register(DataLocation): - """ A (physical) register.""" + """ A (physical) register.""" _number: int @@ -234,7 +234,7 @@
[docs]class Offset(DataLocation): - """ Offset = address in memory computed with base + offset.""" + """ Offset = address in memory computed with base + offset.""" _basereg: Register _offset: int @@ -247,12 +247,12 @@ return ("{}({})".format(self._offset, self._basereg))
[docs] def get_offset(self) -> int: - """Return the value of the offset.""" + """Return the value of the offset.""" return self._offset
[docs]class Immediate(DataLocation): - """Immediate operand (integer).""" + """Immediate operand (integer).""" _val: int @@ -264,7 +264,7 @@
[docs]class Temporary(DataLocation): - """Temporary, a location that has not been allocated yet. + """Temporary, a location that has not been allocated yet. It will later be mapped to a physical register (Register) or to a memory location (Offset). """ @@ -279,12 +279,12 @@ return ("temp_{}".format(str(self._number)))
[docs] def get_alloced_loc(self) -> DataLocation: - """Return the DataLocation allocated to this Temporary.""" + """Return the DataLocation allocated to this Temporary.""" return self._pool.get_alloced_loc(self)
[docs]class TemporaryPool: - """Manage a pool of temporaries.""" + """Manage a pool of temporaries.""" _all_temps: List[Temporary] _current_num: int @@ -296,20 +296,20 @@ self._allocation = dict()
[docs] def get_all_temps(self) -> List[Temporary]: - """Return all the temporaries of the pool.""" + """Return all the temporaries of the pool.""" return self._all_temps
[docs] def get_alloced_loc(self, t: Temporary) -> DataLocation: - """Get the actual DataLocation allocated for the temporary t.""" + """Get the actual DataLocation allocated for the temporary t.""" return self._allocation[t]
[docs] def add_tmp(self, t: Temporary): - """Add a temporary to the pool.""" + """Add a temporary to the pool.""" self._all_temps.append(t) self._allocation[t] = t # While no allocation, return the temporary itself
[docs] def set_temp_allocation(self, allocation: Dict[Temporary, DataLocation]) -> None: - """Give a mapping from temporaries to actual registers. + """Give a mapping from temporaries to actual registers. The argument allocation must be a dict from Temporary to DataLocation other than Temporary (typically Register or Offset). Typing enforces that keys are Temporary and values are Datalocation. @@ -322,7 +322,7 @@ self._allocation = allocation
[docs] def fresh_tmp(self) -> Temporary: - """Give a new fresh Temporary and add it to the pool.""" + """Give a new fresh Temporary and add it to the pool.""" t = Temporary(self._current_num, self) self._current_num += 1 self.add_tmp(t) @@ -330,7 +330,7 @@
[docs]class Renamer: - """Manage a renaming of temporaries.""" + """Manage a renaming of temporaries.""" _pool: TemporaryPool _env: Dict[Temporary, Temporary] @@ -340,21 +340,21 @@ self._env = dict()
[docs] def fresh(self, t: Temporary) -> Temporary: - """Give a fresh rename for a Temporary.""" + """Give a fresh rename for a Temporary.""" new_t = self._pool.fresh_tmp() self._env[t] = new_t return new_t
[docs] def replace(self, t: Temporary) -> Temporary: - """Give the rename for a Temporary (which is itself if it is not renamed).""" + """Give the rename for a Temporary (which is itself if it is not renamed).""" return self._env.get(t, t)
[docs] def defined(self, t: Temporary) -> bool: - """True if the Temporary is renamed.""" + """True if the Temporary is renamed.""" return t in self._env
[docs] def copy(self): - """Give a copy of the Renamer.""" + """Give a copy of the Renamer.""" r = Renamer(self._pool) r._env = self._env.copy() return r
diff --git a/docs/html/_modules/Lib/PhiNode.html b/docs/html/_modules/Lib/PhiNode.html index 3f607ff..c3b36b5 100644 --- a/docs/html/_modules/Lib/PhiNode.html +++ b/docs/html/_modules/Lib/PhiNode.html @@ -95,7 +95,7 @@
[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 @@ -106,26 +106,26 @@ srcs: Dict[Label, Operand]
[docs] def defined(self) -> List[Operand]: - """Return the variable defined by the φ node.""" + """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 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.""" + """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`.""" + """Rename the variable associated to the block identified by `label`.""" if label in self.srcs: t = self.srcs[label] if isinstance(t, Temporary): diff --git a/docs/html/_modules/Lib/RiscV.html b/docs/html/_modules/Lib/RiscV.html index fa3caf5..6e3ca50 100644 --- a/docs/html/_modules/Lib/RiscV.html +++ b/docs/html/_modules/Lib/RiscV.html @@ -90,17 +90,17 @@
[docs]def call(function: Function) -> Instru3A: - """Function call.""" + """Function call.""" return Instru3A('call', function)
[docs]def jump(label: Label) -> AbsoluteJump: - """Unconditional jump to label.""" + """Unconditional jump to label.""" return AbsoluteJump(label)
[docs]def conditional_jump(label: Label, op1: Operand, cond: Condition, op2: Operand): - """Add a conditional jump to the code. + """Add a conditional jump to the code. This is a wrapper around bge, bgt, beq, ... c is a Condition, like Condition('bgt'), Condition(MiniCParser.EQ), ... """ @@ -141,12 +141,12 @@
[docs]def land(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A: - """And instruction (cannot be called `and` due to Python and).""" + """And instruction (cannot be called `and` due to Python and).""" return Instru3A("and", dr, sr1, sr2orimm7)
[docs]def lor(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A: - """Or instruction (cannot be called `or` due to Python or).""" + """Or instruction (cannot be called `or` due to Python or).""" return Instru3A("or", dr, sr1, sr2orimm7)
diff --git a/docs/html/_modules/Lib/Statement.html b/docs/html/_modules/Lib/Statement.html index 04ea512..d8435b7 100644 --- a/docs/html/_modules/Lib/Statement.html +++ b/docs/html/_modules/Lib/Statement.html @@ -95,7 +95,7 @@
[docs]def regset_to_string(registerset) -> str: - """Utility function: pretty-prints a set of locations.""" + """Utility function: pretty-prints a set of locations.""" return "{" + ",".join(str(x) for x in registerset) + "}"
@@ -105,32 +105,32 @@
[docs]@dataclass(unsafe_hash=True) class Statement: - """A Statement, which is an instruction, a comment or a label.""" + """A Statement, which is an instruction, a comment or a label."""
[docs] def defined(self) -> List[Operand]: - """Operands defined (written) in this instruction""" + """Operands defined (written) in this instruction""" return []
[docs] def used(self) -> List[Operand]: - """Operands used (read) in this instruction""" + """Operands used (read) in this instruction""" return []
[docs] def substitute(self: TStatement, subst: Dict[Operand, Operand]) -> TStatement: - """Return a new instruction, cloned from this one, replacing operands + """Return a new instruction, cloned from this one, replacing operands that appear as key in subst by their value.""" raise Exception( "substitute: Operands {} are not present in instruction {}" .format(subst, self))
[docs] def with_args(self: TStatement, new_args: List[Operand]) -> TStatement: - """Return a new instruction, cloned from this one, where operands have + """Return a new instruction, cloned from this one, where operands have been replaced by new_args.""" raise Exception( "substitute: Operands {} are not present in instruction {}" .format(new_args, self))
[docs] def printIns(self, stream): - """ + """ Print the statement on the given output. Should never be called on the base class. """ @@ -139,7 +139,7 @@
[docs]@dataclass(unsafe_hash=True) class Comment(Statement): - """A comment.""" + """A comment.""" comment: str def __str__(self): # use only for print_dot ! @@ -151,7 +151,7 @@
[docs]@dataclass(unsafe_hash=True) class Label(Statement, Operand): - """A label is both a Statement and an Operand.""" + """A label is both a Statement and an Operand.""" name: str def __str__(self): @@ -170,7 +170,7 @@ _read_only: bool
[docs] def is_read_only(self): - """ + """ True if the instruction only reads from its operands. Otherwise, the first operand is considered as the destination @@ -182,7 +182,7 @@ raise NotImplementedError
[docs] def args(self) -> List[Operand]: - """List of operands the instruction takes""" + """List of operands the instruction takes""" raise NotImplementedError
[docs] def defined(self): @@ -214,7 +214,7 @@ return hash((self.ins, *self.args()))
[docs] def printIns(self, stream): - """Print the instruction on the given output.""" + """Print the instruction on the given output.""" print(' ', str(self), file=stream)
@@ -273,7 +273,7 @@
[docs]@dataclass(init=False) class AbsoluteJump(Instruction): - """ An Absolute Jump is a specific kind of instruction""" + """ An Absolute Jump is a specific kind of instruction""" ins = "j" label: Label _read_only = True @@ -305,13 +305,13 @@ return hash(super)
[docs] def targets(self) -> List[Label]: - """Return the labels targetted by the AbsoluteJump.""" + """Return the labels targetted by the AbsoluteJump.""" return [self.label]
[docs]@dataclass(init=False) class ConditionalJump(Instruction): - """ A Conditional Jump is a specific kind of instruction""" + """ A Conditional Jump is a specific kind of instruction""" cond: Condition label: Label op1: Operand diff --git a/docs/html/_modules/Lib/Terminator.html b/docs/html/_modules/Lib/Terminator.html index f0c0dc8..2194c58 100644 --- a/docs/html/_modules/Lib/Terminator.html +++ b/docs/html/_modules/Lib/Terminator.html @@ -108,7 +108,7 @@
[docs]@dataclass(unsafe_hash=True) class Return(Statement): - """A terminator that marks the end of the function.""" + """A terminator that marks the end of the function.""" def __str__(self): return ("return") @@ -117,7 +117,7 @@ print("return", file=stream)
[docs] def targets(self) -> List[Label]: - """Return the labels targetted by the Return terminator.""" + """Return the labels targetted by the Return terminator.""" return []
[docs] def args(self) -> List[Operand]: @@ -146,7 +146,7 @@
[docs]@dataclass(init=False) class BranchingTerminator(Instruction): - """A terminating statement with a condition.""" + """A terminating statement with a condition.""" #: The condition of the branch cond: Condition @@ -173,7 +173,7 @@ return [self.op1, self.op2, self.label_then, self.label_else]
[docs] def targets(self) -> List[Label]: - """Return the labels targetted by the Branching terminator.""" + """Return the labels targetted by the Branching terminator.""" return [self.label_then, self.label_else]
[docs] def rename(self, renamer: Renamer): @@ -213,7 +213,7 @@
[docs]def jump2terminator(j: ConditionalJump | AbsoluteJump | None, next_label: Label | None) -> Terminator: - """ + """ Construct the Terminator associated to the potential jump j to the potential label next_label. """ @@ -227,7 +227,7 @@ return BranchingTerminator(j.cond, j.op1, j.op2, j.label, label_else) case AbsoluteJump(): return AbsoluteJump(label=j.label) - case _: + case _: if next_label: return AbsoluteJump(next_label) else: diff --git a/docs/html/api/Lib.Allocator.html b/docs/html/api/Lib.Allocator.html index 585183a..a9bb12c 100644 --- a/docs/html/api/Lib.Allocator.html +++ b/docs/html/api/Lib.Allocator.html @@ -1,7 +1,7 @@ - + Lib.Allocator module — MiniC documentation diff --git a/docs/html/api/Lib.CFG.html b/docs/html/api/Lib.CFG.html index f978664..68bbd2c 100644 --- a/docs/html/api/Lib.CFG.html +++ b/docs/html/api/Lib.CFG.html @@ -1,7 +1,7 @@ - + Lib.CFG module — MiniC documentation diff --git a/docs/html/api/Lib.Dominators.html b/docs/html/api/Lib.Dominators.html index be0cfe3..9fe1b1f 100644 --- a/docs/html/api/Lib.Dominators.html +++ b/docs/html/api/Lib.Dominators.html @@ -1,7 +1,7 @@ - + Lib.Dominators module — MiniC documentation diff --git a/docs/html/api/Lib.Errors.html b/docs/html/api/Lib.Errors.html index f1c4dd0..b0f8251 100644 --- a/docs/html/api/Lib.Errors.html +++ b/docs/html/api/Lib.Errors.html @@ -1,7 +1,7 @@ - + Lib.Errors module — MiniC documentation diff --git a/docs/html/api/Lib.FunctionData.html b/docs/html/api/Lib.FunctionData.html index b713ba6..1da9c94 100644 --- a/docs/html/api/Lib.FunctionData.html +++ b/docs/html/api/Lib.FunctionData.html @@ -1,7 +1,7 @@ - + Lib.FunctionData module — MiniC documentation diff --git a/docs/html/api/Lib.Graphes.html b/docs/html/api/Lib.Graphes.html index 8715b63..e917ae8 100644 --- a/docs/html/api/Lib.Graphes.html +++ b/docs/html/api/Lib.Graphes.html @@ -1,7 +1,7 @@ - + Lib.Graphes module — MiniC documentation diff --git a/docs/html/api/Lib.LinearCode.html b/docs/html/api/Lib.LinearCode.html index 135da3e..428159c 100644 --- a/docs/html/api/Lib.LinearCode.html +++ b/docs/html/api/Lib.LinearCode.html @@ -1,7 +1,7 @@ - + Lib.LinearCode module — MiniC documentation diff --git a/docs/html/api/Lib.Operands.html b/docs/html/api/Lib.Operands.html index 77fd567..c6babbb 100644 --- a/docs/html/api/Lib.Operands.html +++ b/docs/html/api/Lib.Operands.html @@ -1,7 +1,7 @@ - + Lib.Operands module — MiniC documentation diff --git a/docs/html/api/Lib.PhiNode.html b/docs/html/api/Lib.PhiNode.html index 30d9044..22ab0ee 100644 --- a/docs/html/api/Lib.PhiNode.html +++ b/docs/html/api/Lib.PhiNode.html @@ -1,7 +1,7 @@ - + Lib.PhiNode module — MiniC documentation diff --git a/docs/html/api/Lib.RiscV.html b/docs/html/api/Lib.RiscV.html index 43d0bb6..db2c035 100644 --- a/docs/html/api/Lib.RiscV.html +++ b/docs/html/api/Lib.RiscV.html @@ -1,7 +1,7 @@ - + Lib.RiscV module — MiniC documentation diff --git a/docs/html/api/Lib.Statement.html b/docs/html/api/Lib.Statement.html index 5372635..b67d408 100644 --- a/docs/html/api/Lib.Statement.html +++ b/docs/html/api/Lib.Statement.html @@ -1,7 +1,7 @@ - + Lib.Statement module — MiniC documentation diff --git a/docs/html/api/Lib.Terminator.html b/docs/html/api/Lib.Terminator.html index b1bac9f..769a35a 100644 --- a/docs/html/api/Lib.Terminator.html +++ b/docs/html/api/Lib.Terminator.html @@ -1,7 +1,7 @@ - + Lib.Terminator module — MiniC documentation diff --git a/docs/html/api/Lib.html b/docs/html/api/Lib.html index 56b21c3..7870a6f 100644 --- a/docs/html/api/Lib.html +++ b/docs/html/api/Lib.html @@ -1,7 +1,7 @@ - + Lib package — MiniC documentation diff --git a/docs/html/api/modules.html b/docs/html/api/modules.html index e20adb6..013bbb6 100644 --- a/docs/html/api/modules.html +++ b/docs/html/api/modules.html @@ -1,7 +1,7 @@ - + MiniC — MiniC documentation diff --git a/docs/html/index.html b/docs/html/index.html index 18c304a..7868ea9 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -1,7 +1,7 @@ - + Welcome to MiniC’s documentation! — MiniC documentation