diff --git a/MiniC/Makefile b/MiniC/Makefile index fbab1e0..e180631 100644 --- a/MiniC/Makefile +++ b/MiniC/Makefile @@ -2,7 +2,7 @@ MYNAME = AugustinLucas PACKAGE = MiniC # Example: stop at the first failed test: # make PYTEST_OPTS=-x test -PYTEST_OPTS = +PYTEST_OPTS = # Run the whole test infrastructure for a subset of test files e.g. # make FILTER='TP03/**/bad*.c' test ifdef FILTER diff --git a/MiniC/test_codegen.py b/MiniC/test_codegen.py index 05228cb..75e961e 100755 --- a/MiniC/test_codegen.py +++ b/MiniC/test_codegen.py @@ -85,6 +85,7 @@ ALL_IN_MEM_FILES.sort() ALL_FILES = list(set(ALL_FILES)) ALL_FILES.sort() + class TestCodeGen(TestExpectPragmas, TestCompiler): DISABLE_CODEGEN = DISABLE_CODEGEN SKIP_NOT_IMPLEMENTED = SKIP_NOT_IMPLEMENTED diff --git a/PLANNING.md b/PLANNING.md index a60874f..b46b3b8 100644 --- a/PLANNING.md +++ b/PLANNING.md @@ -66,7 +66,7 @@ _Academic first semester 2024-2025_ # Week 6: -- :hammer: Lab 4b: Thursday 14/10/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino) +- :hammer: Lab 4b: Monday 14/10/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino) * Control Flow Graph [TP04b](TP04/tp4b.pdf). * Code in [MiniC/TP04/](MiniC/TP04/). @@ -75,3 +75,11 @@ _Academic first semester 2024-2025_ - :book: Course: Thursday 17/10/2024, 10h15-12h15. Amphi L (Gabriel Radanne) * Register allocation [slides in english](course/cap_cours07_regalloc.pdf). + +# Week 7: + +- :hammer: Lab 5a: Monday 21/10/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino) + + * Control Flow Graph under SSA Form [TP05a](TP05/tp5a.pdf). + * Code in [MiniC/TP05/](MiniC/TP05/). + * Documentation (updated) [here](docs/html/index.html). diff --git a/TP05/tp5a.pdf b/TP05/tp5a.pdf new file mode 100644 index 0000000..2f7a693 Binary files /dev/null and b/TP05/tp5a.pdf differ diff --git a/docs/html/_modules/Lib/Allocator.html b/docs/html/_modules/Lib/Allocator.html index 07b9b12..0abe9c5 100644 --- a/docs/html/_modules/Lib/Allocator.html +++ b/docs/html/_modules/Lib/Allocator.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/Lib/CFG.html b/docs/html/_modules/Lib/CFG.html index c9a0886..6764529 100644 --- a/docs/html/_modules/Lib/CFG.html +++ b/docs/html/_modules/Lib/CFG.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/Lib/Dominators.html b/docs/html/_modules/Lib/Dominators.html new file mode 100644 index 0000000..657816f --- /dev/null +++ b/docs/html/_modules/Lib/Dominators.html @@ -0,0 +1,239 @@ + + + + + + Lib.Dominators — MiniC documentation + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Source code for Lib.Dominators

    +"""
    +Utility functions to work with dominators in a :py:class:`CFG <Lib.CFG.CFG>`.
    +
    +Do not hesitate to look at the source of the functions
    +to get a better understanding of the algorithms.
    +"""
    +
    +from typing import Dict, Set
    +from graphviz import Digraph
    +from Lib.CFG import Block, CFG
    +
    +
    +
    [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. + + This is an helper function called during SSA entry. + """ + all_blocks: Set[Block] = set(cfg.get_blocks()) + dominators: Dict[Block, Set[Block]] = dict() + for b in all_blocks: + if b.get_in(): # If b has some predecessor + dominators[b] = all_blocks + else: # If b has no predecessors + dominators[b] = {b} + new_dominators: Dict[Block, Set[Block]] = dict() + while True: + for b in all_blocks: + if b.get_in(): + dom_preds = [dominators[b2] for b2 in b.get_in()] + new_dominators[b] = {b}.union(set.intersection(*dom_preds)) + else: + new_dominators[b] = {b} + if dominators == new_dominators: + break + else: + dominators = new_dominators + new_dominators = dict() + return dominators
    + + +
    [docs]def printDT(filename: str, graph: Dict[Block, Set[Block]]) -> None: # pragma: no cover + """Display a graphical rendering of the given domination tree.""" + dot = Digraph() + for k in graph: + dot.node(str(k.get_label())) + for k in graph: + for v in graph[k]: + dot.edge(str(k.get_label()), str(v.get_label())) + dot.render(filename, view=True)
    + + +
    [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 + in the dominator tree. + + This is an helper function called during SSA entry. + """ + # First, compute the immediate dominators + idominators: Dict[Block, Block] = {} + for b, doms in dominators.items(): + # The immediate dominator of b is the unique vertex n ≠ b + # which dominates b and is dominated by all vertices in Dom(b) − b. + strict_doms = doms - {b} + idoms = set() + for n in strict_doms: + if strict_doms.issubset(dominators[n]): + idoms.add(n) + if idoms: + assert (len(idoms) == 1) + idominators[b] = idoms.pop() + # Then, simply inverse the relation to obtain the domination tree + DT = {b: set() for b in cfg.get_blocks()} + for i, idominator in idominators.items(): + DT[idominator].add(i) + # Print the domination tree if asked + if dom_graphs: + s = "{}.{}.ssa.DT.dot".format(basename, cfg.fdata.get_name()) + print("SSA - domination tree graph:", s) + printDT(s, DT) + return DT
    + + +def _computeDF_at_block( + cfg: CFG, + dominators: Dict[Block, Set[Block]], + 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`. + + This is an helper function called during SSA entry. + """ + S: Set[Block] = {succ for succ in cfg.out_blocks(b) if succ not in DT[b]} + for b_succ in DT[b]: + _computeDF_at_block(cfg, dominators, DT, b_succ, DF) + for b_frontier in DF[b_succ]: + if b not in (dominators[b_frontier] - {b_frontier}): + S.add(b_frontier) + DF[b] = S + + +
    [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. + + This is an helper function called during SSA entry. + """ + DF: Dict[Block, Set[Block]] = dict() + for b_entry in cfg.get_entries(): + _computeDF_at_block(cfg, dominators, DT, b_entry, DF) + # Print the domination frontier on the CFG if asked + if dom_graphs: + s = "{}.{}.ssa.DF.dot".format(basename, cfg.fdata.get_name()) + print("SSA - dominance frontier graph:", s) + cfg.print_dot(s, DF, True) + return DF
    +
    + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/_modules/Lib/Errors.html b/docs/html/_modules/Lib/Errors.html index 6d661b7..8b2c260 100644 --- a/docs/html/_modules/Lib/Errors.html +++ b/docs/html/_modules/Lib/Errors.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/Lib/FunctionData.html b/docs/html/_modules/Lib/FunctionData.html index c0e5908..ef804b1 100644 --- a/docs/html/_modules/Lib/FunctionData.html +++ b/docs/html/_modules/Lib/FunctionData.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/Lib/Graphes.html b/docs/html/_modules/Lib/Graphes.html new file mode 100644 index 0000000..8530b26 --- /dev/null +++ b/docs/html/_modules/Lib/Graphes.html @@ -0,0 +1,423 @@ + + + + + + Lib.Graphes — MiniC documentation + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Source code for Lib.Graphes

    +""" Python Classes for Oriented and Non Oriented Graphs
    +"""
    +
    +from graphviz import Digraph  # for dot output
    +from typing import List, Dict, Set, Tuple, Any
    +
    +
    +
    [docs]class GraphError(Exception): + """Exception raised for self loops. + """ + + message: str + + def __init__(self, message: str): + self.message = message
    + + +
    [docs]class GeneralGraph(object): + """ + General class regrouping similarities + between directed and non oriented graphs. + The only differences between the two are: + + - how to compute the set of edges + - how to add an edge + - how to print the graph + - how to delete a vertex + - how to delete an edge + - we only color undirected graphs + """ + + 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. + """ + if graph_dict is None: + graph_dict = {} + self.graph_dict = graph_dict + +
    [docs] def vertices(self) -> List[Any]: + """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. + Otherwise nothing has to be done. + """ + if vertex not in self.graph_dict: + self.graph_dict[vertex] = set()
    + +
    [docs] def edges(self) -> List[Set]: + """Return the edges of the graph.""" + return []
    + + def __str__(self): + res = "vertices: " + for k in self.graph_dict: + res += str(k) + " " + res += "\nedges: " + for edge in self.edges(): + res += str(edge) + " " + return res + +
    [docs] def dfs_traversal(self, root: Any) -> List[Any]: + """ + Compute a depth first search of the graph, + from the vertex root. + """ + seen: List[Any] = [] + todo: List[Any] = [root] + while len(todo) > 0: # while todo ... + current = todo.pop() + seen.append(current) + for neighbour in self.graph_dict[current]: + if neighbour not in seen: + todo.append(neighbour) + return seen
    + +
    [docs] def is_reachable_from(self, v1: Any, v2: Any) -> bool: + """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. + """ + components: List[List[Any]] = [] + done: List[Any] = [] + for v in self.vertices(): + if v not in done: + v_comp = self.dfs_traversal(v) + components.append(v_comp) + done.extend(v_comp) + return components
    + +
    [docs] def bfs_traversal(self, root: Any) -> List[Any]: + """ + Compute a breadth first search of the graph, + from the vertex root. + """ + seen: List[Any] = [] + todo: List[Any] = [root] + while len(todo) > 0: # while todo ... + current = todo.pop(0) # list.pop(0): for dequeuing (on the left...) ! + seen.append(current) + for neighbour in self.graph_dict[current]: + if neighbour not in seen: + todo.append(neighbour) + return seen
    + + +
    [docs]class Graph(GeneralGraph): + """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. + """ + edges = [] + for vertex in self.graph_dict: + for neighbour in self.graph_dict[vertex]: + if {neighbour, vertex} not in edges: + edges.append({vertex, neighbour}) + 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))) + """ + (vertex1, vertex2) = edge + if vertex1 == vertex2: + raise GraphError("Cannot add a self loop on vertex {} in an unoriented graph.".format( + str(vertex1))) + if vertex1 in self.graph_dict: + self.graph_dict[vertex1].add(vertex2) + else: + self.graph_dict[vertex1] = {vertex2} + if vertex2 in self.graph_dict: + self.graph_dict[vertex2].add(vertex1) + else: + self.graph_dict[vertex2] = {vertex1}
    + +
    [docs] def print_dot(self, name: str, colors={}) -> None: + """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', + 'parallelogram', 'house', 'triangle', 'pentagon', 'hexagon', + 'septagon', 'octagon'] + dot = Digraph(comment='Conflict Graph') + for k in self.graph_dict: + shape = None + if not colors: + color = "red" # Graph not colored: red for everyone + elif k not in colors: + color = "grey" # Node not colored: grey + else: + n = colors[k] + if n < len(color_names): + color = color_names[colors[k]] + else: + color = "black" # Too many colors anyway, it won't be readable. + shape = color_shapes[n % len(color_shapes)] + dot.node(str(k), color=color, shape=shape) + for (v1, v2) in self.edges(): + dot.edge(str(v1), str(v2), dir="none") + # print(dot.source) + dot.render(name, view=True) # print in pdf
    + +
    [docs] def delete_vertex(self, vertex: Any) -> None: + """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.""" + (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, ...). + """ + coloring, _, _ = self.color_with_k_colors() + return coloring
    + + # 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: + + - a dict vertex -> color + - a Boolean, True if the coloring succeeded + - the set of nodes actually colored + + Do not color vertices belonging to avoidingnodes. + + Continue even if the algo fails. + """ + if K is None: + K = len(self.graph_dict) + todo_vertices = [] + is_total = True + gcopy = Graph(self.graph_dict.copy()) + # suppress nodes that are not to be considered. + for node in avoidingnodes: + gcopy.delete_vertex(node) + # append nodes in the list according to their degree and node number: + while gcopy.graph_dict: + todo = list(gcopy.graph_dict) + todo.sort(key=lambda v: (len(gcopy.graph_dict[v]), str(v))) + lower = todo[0] + todo_vertices.append(lower) + gcopy.delete_vertex(lower) + # Now reverse the list: first elements are those with higher degree + # print(todo_vertices) + todo_vertices.reverse() # in place reversal + # print(todo_vertices) + coloring = {} + colored_nodes = [] + # gdict will be the coloring map to return + gdict = self.graph_dict + for v in todo_vertices: + seen_neighbours = [x for x in gdict[v] if x in coloring] + choose_among = [i for i in range(K) if not ( + i in [coloring[v1] for v1 in seen_neighbours])] + if choose_among: + # if the node can be colored, I choose the minimal color. + color = min(choose_among) + coloring[v] = color + colored_nodes.append(v) + else: + # if I cannot color some node, the coloring is not Total + # but I continue + is_total = False + return (coloring, is_total, colored_nodes)
    + + +
    [docs]class DiGraph(GeneralGraph): + """Class for directed graphs.""" + +
    [docs] def pred(self, v: Any) -> Set: + """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 list(self.graph_dict.items())
    + +
    [docs] def edges(self) -> List[Set]: + """ A static method generating the set of edges""" + edges = [] + for vertex in self.graph_dict: + for neighbour in self.graph_dict[vertex]: + edges.append((vertex, neighbour)) + 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))) + """ + (vertex1, vertex2) = edge + if vertex1 in self.graph_dict: + self.graph_dict[vertex1].add(vertex2) + else: + self.graph_dict[vertex1] = {vertex2} + if vertex2 not in self.graph_dict: + self.graph_dict[vertex2] = set()
    + +
    [docs] def print_dot(self, name: str) -> None: + """Print the graph.""" + dot = Digraph(comment='Conflict Graph') + for k in self.graph_dict: + shape = None + color = "grey" + dot.node(str(k), color=color, shape=shape) + for (v1, v2) in self.edges(): + dot.edge(str(v1), str(v2), dir="none") + # print(dot.source) + dot.render(name, view=True) # print in pdf
    + +
    [docs] def delete_vertex(self, vertex: Any) -> None: + """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.""" + (v1, v2) = edge + self.graph_dict[v1].remove(v2)
    +
    + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/_modules/Lib/LinearCode.html b/docs/html/_modules/Lib/LinearCode.html index af2b72f..cc12086 100644 --- a/docs/html/_modules/Lib/LinearCode.html +++ b/docs/html/_modules/Lib/LinearCode.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/Lib/Operands.html b/docs/html/_modules/Lib/Operands.html index befdd1f..e2aead9 100644 --- a/docs/html/_modules/Lib/Operands.html +++ b/docs/html/_modules/Lib/Operands.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/Lib/PhiNode.html b/docs/html/_modules/Lib/PhiNode.html new file mode 100644 index 0000000..6165fcc --- /dev/null +++ b/docs/html/_modules/Lib/PhiNode.html @@ -0,0 +1,173 @@ + + + + + + Lib.PhiNode — MiniC documentation + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    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 relies for each precedent block in the CFG, identified with its label, + 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)
    +
    + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/_modules/Lib/RiscV.html b/docs/html/_modules/Lib/RiscV.html index 9ecc4f4..6e3ca50 100644 --- a/docs/html/_modules/Lib/RiscV.html +++ b/docs/html/_modules/Lib/RiscV.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/Lib/Statement.html b/docs/html/_modules/Lib/Statement.html index 66469b0..d8435b7 100644 --- a/docs/html/_modules/Lib/Statement.html +++ b/docs/html/_modules/Lib/Statement.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/Lib/Terminator.html b/docs/html/_modules/Lib/Terminator.html index 80942ff..2194c58 100644 --- a/docs/html/_modules/Lib/Terminator.html +++ b/docs/html/_modules/Lib/Terminator.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • diff --git a/docs/html/_modules/index.html b/docs/html/_modules/index.html index 2c66b33..b5eeb28 100644 --- a/docs/html/_modules/index.html +++ b/docs/html/_modules/index.html @@ -45,10 +45,13 @@
  • Base library - RISC-V instructions
  • Base library - Operands
  • Base library - Function data
  • +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • @@ -77,10 +80,13 @@

    All modules for which code is available

    diff --git a/docs/html/api/Lib.FunctionData.html b/docs/html/api/Lib.FunctionData.html index ee298fd..1da9c94 100644 --- a/docs/html/api/Lib.FunctionData.html +++ b/docs/html/api/Lib.FunctionData.html @@ -18,7 +18,7 @@ - + @@ -59,10 +59,13 @@ +
  • Base library - Graphs
  • Linear intermediate representation
  • Temporary allocation
  • Control Flow Graph - CFG and Basic blocks
  • Control Flow Graph - Terminators
  • +
  • SSA form - Dominance frontier
  • +
  • SSA form - Phi Nodes
  • @@ -151,7 +154,7 @@ Offsets are decreasing relative to FP.