Commit TP5b

This commit is contained in:
Rémi Di Guardia 2022-10-26 09:44:46 +02:00
parent 1c151ffe93
commit a89ae6ffb7
20 changed files with 269 additions and 21 deletions

View File

@ -84,6 +84,14 @@ class Block:
cast(List[Statement], self._instructions) +
[self.get_terminator()])
def get_body_and_terminator(self) -> List[Statement]:
"""
Return all statements of the block, except phi-nodes
(and the label of the block).
"""
return (cast(List[Statement], self._instructions) +
[self.get_terminator()])
def get_label(self) -> Label:
"""Return the label of the block."""
return self._label
@ -259,7 +267,6 @@ class CFG:
# nodes
for name, blk in self._blocks.items():
if DF is not None:
print(str(name), blk._label)
df_str = "{}" if blk not in DF or not len(DF[blk]) else str(DF[blk])
df_lab = blk.to_dot() + "\n\nDominance frontier:\n" + df_str
else:

View File

@ -156,7 +156,9 @@ class Graph(GeneralGraph):
"""Print the graph."""
color_names = ['red', 'blue', 'green', 'yellow', 'cyan', 'magenta'] + \
[f"grey{i}" for i in range(0, 100, 10)]
color_shapes = ['ellipse', 'polygon', 'box', 'circle', 'egg', 'pentagon', 'hexagon']
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
@ -255,6 +257,10 @@ class Graph(GeneralGraph):
class DiGraph(GeneralGraph):
"""Class for directed graphs."""
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}
def neighbourhoods(self) -> List[Tuple[Any, Set]]:
"""Return all neighbourhoods in the graph."""
return list(self.graph_dict.items())

View File

@ -52,6 +52,9 @@ class Return(Statement):
.format(self))
return self
def is_read_only(self):
return True
@dataclass(init=False)
class BranchingTerminator(Instruction):
@ -126,7 +129,7 @@ def jump2terminator(j: ConditionalJump | AbsoluteJump | None,
return BranchingTerminator(j.cond, j.op1, j.op2, j.label, label_else)
case AbsoluteJump():
return AbsoluteJump(label=j.label)
case None:
case _:
if next_label:
return AbsoluteJump(next_label)
else:

99
MiniC/TP05/LivenessSSA.py Normal file
View File

@ -0,0 +1,99 @@
from typing import Dict, Set, Tuple
from Lib.Operands import Temporary
from Lib.Statement import Statement, regset_to_string
from Lib.CFG import Block, CFG
from Lib.PhiNode import PhiNode
class LivenessSSA:
"""Liveness Analysis on a CFG under SSA Form."""
def __init__(self, cfg: CFG, debug=False):
self._cfg: CFG = cfg
self._debug: bool = debug
# Temporary already propagated, by Block
self._seen: Dict[Block, Set[Temporary]] = dict()
# Live Temporary at outputs of Statement
self._liveout: Dict[Statement, Set[Temporary]] = dict()
def run(self) -> None:
"""Compute the liveness."""
# Initialization
for block in self._cfg.get_blocks():
self._seen[block] = set()
for instr in block.get_all_statements():
self._liveout[instr] = set()
# Start the use-def chains
for var, uses in self.gather_uses().items():
for block, pos, instr in uses:
self.live_start(block, pos, instr, var)
# Add conflicts on phis
self.conflict_on_phis()
# Final debugging print
if self._debug:
self.print_map_in_out()
def live_start(self, block: Block, pos: int | None,
s: Statement, var: Temporary) -> None:
"""Start backward propagation of liveness information."""
if isinstance(s, PhiNode):
assert(pos is None)
for label, var_phi in s.used().items():
if var_phi == var:
prev_block = self._cfg.get_block(label)
self.liveout_at_block(prev_block, var)
else:
assert(pos is not None)
self.livein_at_instruction(block, pos, var)
def liveout_at_block(self, block: Block, var: Temporary) -> None:
"""Backward propagation of liveness information at a block."""
raise NotImplementedError("LivenessSSA") # TODO (Lab 5b, Exercise 1)
def liveout_at_instruction(self, block: Block, pos: int, var: Temporary) -> None:
"""Backward propagation of liveness information at a non-phi instruction."""
instr = block.get_body_and_terminator()[pos]
raise NotImplementedError("LivenessSSA") # TODO (Lab 5b, Exercise 1)
def livein_at_instruction(self, block: Block, pos: int, var: Temporary) -> None:
"""Backward propagation of liveness information at a non-phi instruction."""
raise NotImplementedError("LivenessSSA") # TODO (Lab 5b, Exercise 1)
def gather_uses(self) -> Dict[Temporary, Set[Tuple[Block, int | None, Statement]]]:
"""
Return a dictionnary giving for each variable the set of statements using it,
with additionnaly for each statement, the block of the statement and its position inside.
Phi instructions have position None in their block, while a Terminaor is at the last
position of its block.
"""
uses: Dict[Temporary, Set[Tuple[Block, int | None, Statement]]] = dict()
for block in self._cfg.get_blocks():
# Look inside the phi node
for instr in block._phis:
assert (isinstance(instr, PhiNode))
for var in instr.used().values():
if isinstance(var, Temporary):
var_uses = uses.get(var, set())
uses[var] = var_uses.union({(block, None, instr)})
# Look inside the body and the terminator
for pos, instr in enumerate(block.get_body_and_terminator()):
for var in instr.used():
if isinstance(var, Temporary):
var_uses = uses.get(var, set())
uses[var] = var_uses.union({(block, pos, instr)})
return uses
def conflict_on_phis(self) -> None:
"""Ensures that variables defined by phi instructions are in conflict with one-another."""
raise NotImplementedError("LivenessSSA") # TODO (Lab 5b, Exercise 1)
def print_map_in_out(self) -> None: # pragma: no cover
"""Print live out sets at each instruction, group by block, useful for debugging!"""
print("Liveout: [")
for block in self._cfg.get_blocks():
print("Block " + str(block.get_label()) + ": {\n "
+ ",\n ".join("\"{}\": {}"
.format(instr, regset_to_string(self._liveout[instr]))
for instr in block.get_all_statements()) +
"}")
print("]")

View File

@ -0,0 +1,99 @@
from typing import List, Dict
from Lib.Errors import MiniCInternalError
from Lib.Operands import Temporary, Operand, S, Register, Offset, DataLocation, GP_REGS
from Lib.Statement import Instruction
from Lib.Allocator import Allocator
from Lib.FunctionData import FunctionData
from Lib import RiscV
from Lib.Graphes import Graph # For Graph coloring utility functions
class SmartAllocator(Allocator):
_igraph: Graph # interference graph
def __init__(self, fdata: FunctionData, basename: str, liveness,
debug=False, debug_graphs=False):
self._liveness = liveness
self._basename: str = basename
self._debug: bool = debug
self._debug_graphs: bool = debug_graphs
super().__init__(fdata)
def replace(self, old_instr: Instruction) -> List[Instruction]:
"""
Replace Temporary operands with the corresponding allocated
physical register (Register) OR memory location (Offset).
"""
before: List[Instruction] = []
after: List[Instruction] = []
subst: Dict[Operand, Operand] = {}
# TODO (lab5): Compute before, after, subst. This is similar to what
# TODO (lab5): replace from the Naive and AllInMem Allocators do (Lab 4).
raise NotImplementedError("Smart Replace (lab5)") # TODO
# And now return the new list!
instr = old_instr.substitute(subst)
return before + [instr] + after
def prepare(self) -> None:
"""
Perform all preparatory steps related to smart register allocation:
- Dataflow analysis to compute the liveness range of each
temporary.
- Interference graph construction.
- Graph coloring.
- Associating temporaries with actual locations.
"""
# Liveness analysis
self._liveness.run()
# Interference graph
self.build_interference_graph()
if self._debug_graphs:
print("Printing the interference graph")
self._igraph.print_dot(self._basename + "interference.dot")
# Smart Allocation via graph coloring
self.smart_alloc()
def build_interference_graph(self) -> None:
"""
Build the interference graph (in self._igraph).
Vertices of the graph are temporaries,
and an edge exists between temporaries iff they are in conflict.
"""
self._igraph: Graph = Graph()
# Create a vertex for every temporary
# There may be temporaries the code does not use anymore,
# but it does not matter as they interfere with no one.
for v in self._fdata._pool.get_all_temps():
self._igraph.add_vertex(v)
# Iterate over self._liveness._liveout (dictionary containing all
# live out temporaries for each instruction), and for each conflict use
# self._igraph.add_edge((t1, t2)) to add the corresponding edge.
raise NotImplementedError("build_interference_graph (lab5)") # TODO
def smart_alloc(self) -> None:
"""
Allocates all temporaries via graph coloring.
Prints the colored graph if self._debug_graphs is True.
Precondition: the interference graph _igraph must have been built.
"""
# Checking the interference graph has been built
if not self._igraph:
raise MiniCInternalError("Empty interference graph in the Smart Allocator")
# Coloring of the interference graph
coloringreg: Dict[Temporary, int] = self._igraph.color()
if self._debug_graphs:
print("coloring = " + str(coloringreg))
self._igraph.print_dot(self._basename + "_colored.dot", coloringreg)
# Temporary -> DataLocation (Register or Offset) dictionary,
# specifying where a given Temporary should be allocated:
alloc_dict: Dict[Temporary, DataLocation] = dict()
# Use the coloring `coloringreg` to fill `alloc_dict`.
# Our version is less than 5 lines of code.
raise NotImplementedError("Allocation based on graph coloring (lab5)") # TODO
if self._debug:
print("Allocation:")
print(alloc_dict)
self._fdata._pool.set_temp_allocation(alloc_dict)

BIN
MiniC/TP05/tp5b.pdf Normal file

Binary file not shown.

View File

@ -129,11 +129,8 @@ class TestCodeGen(TestExpectPragmas):
if "AllocationError" in result.output:
if reg_alloc == 'naive':
pytest.skip("Too big for the naive allocator")
elif reg_alloc == 'all-in-mem':
pytest.skip("Too big for the all in memory allocator")
else:
raise Exception("AllocationError should only happen "
"for reg_alloc='naive' or reg_alloc='all_in_mem'")
pytest.skip("Offsets too big to be manipulated")
elif ("NotImplementedError" in result.output and
SKIP_NOT_IMPLEMENTED):
pytest.skip("Feature not implemented in this compiler")

View File

@ -90,3 +90,10 @@ _Academic first semester 2022-2023_
* Code in [MiniC/TP05/](MiniC/TP05/).
* Documentation (updated) [here](docs/index.html).
# Week 8:
- :hammer: Lab 5b (1/2): Wednesday 26/10/2021, 10h15-12h15. Rooms A1 (Nicolas Chappe) & B2 (Rémi Di Guardia)
* Smart Register Allocation [TP05b](MiniC/TP05/tp5b.pdf)
* Code in [MiniC/TP05/](MiniC/TP05/).

View File

@ -162,6 +162,14 @@
<span class="n">cast</span><span class="p">(</span><span class="n">List</span><span class="p">[</span><span class="n">Statement</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">_instructions</span><span class="p">)</span> <span class="o">+</span>
<span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">get_terminator</span><span class="p">()])</span></div>
<div class="viewcode-block" id="Block.get_body_and_terminator"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.get_body_and_terminator">[docs]</a> <span class="k">def</span> <span class="nf">get_body_and_terminator</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">Statement</span><span class="p">]:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return all statements of the block, except phi-nodes</span>
<span class="sd"> (and the label of the block).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">(</span><span class="n">cast</span><span class="p">(</span><span class="n">List</span><span class="p">[</span><span class="n">Statement</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">_instructions</span><span class="p">)</span> <span class="o">+</span>
<span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">get_terminator</span><span class="p">()])</span></div>
<div class="viewcode-block" id="Block.get_label"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.get_label">[docs]</a> <span class="k">def</span> <span class="nf">get_label</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Label</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Return the label of the block.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_label</span></div>

View File

@ -234,7 +234,9 @@
<span class="sd">&quot;&quot;&quot;Print the graph.&quot;&quot;&quot;</span>
<span class="n">color_names</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;red&#39;</span><span class="p">,</span> <span class="s1">&#39;blue&#39;</span><span class="p">,</span> <span class="s1">&#39;green&#39;</span><span class="p">,</span> <span class="s1">&#39;yellow&#39;</span><span class="p">,</span> <span class="s1">&#39;cyan&#39;</span><span class="p">,</span> <span class="s1">&#39;magenta&#39;</span><span class="p">]</span> <span class="o">+</span> \
<span class="p">[</span><span class="sa">f</span><span class="s2">&quot;grey</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">10</span><span class="p">)]</span>
<span class="n">color_shapes</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;ellipse&#39;</span><span class="p">,</span> <span class="s1">&#39;polygon&#39;</span><span class="p">,</span> <span class="s1">&#39;box&#39;</span><span class="p">,</span> <span class="s1">&#39;circle&#39;</span><span class="p">,</span> <span class="s1">&#39;egg&#39;</span><span class="p">,</span> <span class="s1">&#39;pentagon&#39;</span><span class="p">,</span> <span class="s1">&#39;hexagon&#39;</span><span class="p">]</span>
<span class="n">color_shapes</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;ellipse&#39;</span><span class="p">,</span> <span class="s1">&#39;box&#39;</span><span class="p">,</span> <span class="s1">&#39;diamond&#39;</span><span class="p">,</span> <span class="s1">&#39;trapezium&#39;</span><span class="p">,</span> <span class="s1">&#39;egg&#39;</span><span class="p">,</span>
<span class="s1">&#39;parallelogram&#39;</span><span class="p">,</span> <span class="s1">&#39;house&#39;</span><span class="p">,</span> <span class="s1">&#39;triangle&#39;</span><span class="p">,</span> <span class="s1">&#39;pentagon&#39;</span><span class="p">,</span> <span class="s1">&#39;hexagon&#39;</span><span class="p">,</span>
<span class="s1">&#39;septagon&#39;</span><span class="p">,</span> <span class="s1">&#39;octagon&#39;</span><span class="p">]</span>
<span class="n">dot</span> <span class="o">=</span> <span class="n">Digraph</span><span class="p">(</span><span class="n">comment</span><span class="o">=</span><span class="s1">&#39;Conflict Graph&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">:</span>
<span class="n">shape</span> <span class="o">=</span> <span class="kc">None</span>
@ -333,6 +335,10 @@
<div class="viewcode-block" id="DiGraph"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.DiGraph">[docs]</a><span class="k">class</span> <span class="nc">DiGraph</span><span class="p">(</span><span class="n">GeneralGraph</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Class for directed graphs.&quot;&quot;&quot;</span>
<div class="viewcode-block" id="DiGraph.pred"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.DiGraph.pred">[docs]</a> <span class="k">def</span> <span class="nf">pred</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">v</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Set</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Return all predecessors of the vertex `v` in the graph.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{</span><span class="n">src</span> <span class="k">for</span> <span class="n">src</span><span class="p">,</span> <span class="n">dests</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">dests</span><span class="p">}</span></div>
<div class="viewcode-block" id="DiGraph.neighbourhoods"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.DiGraph.neighbourhoods">[docs]</a> <span class="k">def</span> <span class="nf">neighbourhoods</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">Tuple</span><span class="p">[</span><span class="n">Any</span><span class="p">,</span> <span class="n">Set</span><span class="p">]]:</span>
<span class="sd">&quot;&quot;&quot;Return all neighbourhoods in the graph.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="o">.</span><span class="n">items</span><span class="p">())</span></div>

View File

@ -131,10 +131,8 @@
<div class="viewcode-block" id="LinearCode.iter_statements"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.iter_statements">[docs]</a> <span class="k">def</span> <span class="nf">iter_statements</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Iterate over instructions.</span>
<span class="sd"> For each real instruction (not label or comment), call f,</span>
<span class="sd"> which must return either None or a list of instruction. If it</span>
<span class="sd"> returns None, nothing happens. If it returns a list, then the</span>
<span class="sd"> instruction is replaced by this list.</span>
<span class="sd"> For each real instruction i (not label or comment), replace it</span>
<span class="sd"> with the list of instructions given by f(i).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span> <span class="o">=</span> <span class="n">_iter_statements</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span></div>
@ -153,7 +151,7 @@
<div class="viewcode-block" id="LinearCode.add_instruction_PRINTLN_INT"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.add_instruction_PRINTLN_INT">[docs]</a> <span class="k">def</span> <span class="nf">add_instruction_PRINTLN_INT</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">reg</span><span class="p">:</span> <span class="n">DataLocation</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Print integer value, with newline. (see Expand)&quot;&quot;&quot;</span>
<span class="c1"># a print instruction generates the temp it prints.</span>
<span class="c1"># A print instruction generates the temp it prints.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_instruction</span><span class="p">(</span><span class="n">mv</span><span class="p">(</span><span class="n">A0</span><span class="p">,</span> <span class="n">reg</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_instruction</span><span class="p">(</span><span class="n">call</span><span class="p">(</span><span class="n">Function</span><span class="p">(</span><span class="s1">&#39;println_int&#39;</span><span class="p">)))</span></div>

View File

@ -146,7 +146,10 @@
<div class="viewcode-block" id="xor"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.xor">[docs]</a><span class="k">def</span> <span class="nf">xor</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Instru3A</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">&quot;xor&quot;</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sr2orimm7</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">&quot;xori&quot;</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">&quot;xor&quot;</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
<div class="viewcode-block" id="li"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.li">[docs]</a><span class="k">def</span> <span class="nf">li</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">imm7</span><span class="p">:</span> <span class="n">Immediate</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Instru3A</span><span class="p">:</span>

View File

@ -91,7 +91,7 @@
<span class="kn">from</span> <span class="nn">Lib.Errors</span> <span class="kn">import</span> <span class="n">MiniCInternalError</span>
<div class="viewcode-block" id="regset_to_string"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.regset_to_string">[docs]</a><span class="k">def</span> <span class="nf">regset_to_string</span><span class="p">(</span><span class="n">registerset</span><span class="p">):</span>
<div class="viewcode-block" id="regset_to_string"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.regset_to_string">[docs]</a><span class="k">def</span> <span class="nf">regset_to_string</span><span class="p">(</span><span class="n">registerset</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Utility function: pretty-prints a set of locations.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="s2">&quot;{&quot;</span> <span class="o">+</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">registerset</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;}&quot;</span></div>

View File

@ -115,6 +115,13 @@ See the documentation for <code class="xref py py-class docutils literal notrans
(including phi-nodes and the terminator, but not the label of the block).</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="Lib.CFG.Block.get_body_and_terminator">
<span class="sig-name descname"><span class="pre">get_body_and_terminator</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Statement" title="Lib.Statement.Statement"><span class="pre">Statement</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#Block.get_body_and_terminator"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.get_body_and_terminator" title="Permalink to this definition"></a></dt>
<dd><p>Return all statements of the block, except phi-nodes
(and the label of the block).</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="Lib.CFG.Block.get_label">
<span class="sig-name descname"><span class="pre">get_label</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Label</span></a></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#Block.get_label"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.get_label" title="Permalink to this definition"></a></dt>

View File

@ -230,6 +230,12 @@ Return a dict vertex -&gt; color, where color is an integer (0, 1, …).</p>
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Graphes.</span></span><span class="sig-name descname"><span class="pre">DiGraph</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">graph_dict</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Graphes.html#DiGraph"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Graphes.DiGraph" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <a class="reference internal" href="#Lib.Graphes.GeneralGraph" title="Lib.Graphes.GeneralGraph"><code class="xref py py-class docutils literal notranslate"><span class="pre">GeneralGraph</span></code></a></p>
<p>Class for directed graphs.</p>
<dl class="py method">
<dt class="sig sig-object py" id="Lib.Graphes.DiGraph.pred">
<span class="sig-name descname"><span class="pre">pred</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">v</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Any</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">Set</span></span></span><a class="reference internal" href="../_modules/Lib/Graphes.html#DiGraph.pred"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Graphes.DiGraph.pred" title="Permalink to this definition"></a></dt>
<dd><p>Return all predecessors of the vertex <cite>v</cite> in the graph.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="Lib.Graphes.DiGraph.neighbourhoods">
<span class="sig-name descname"><span class="pre">neighbourhoods</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><span class="pre">Tuple</span><span class="p"><span class="pre">[</span></span><span class="pre">Any</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Set</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/Graphes.html#DiGraph.neighbourhoods"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Graphes.DiGraph.neighbourhoods" title="Permalink to this definition"></a></dt>

View File

@ -110,10 +110,8 @@ the RiscV program to a file.</p>
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.iter_statements">
<span class="sig-name descname"><span class="pre">iter_statements</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">f</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.iter_statements"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.iter_statements" title="Permalink to this definition"></a></dt>
<dd><p>Iterate over instructions.
For each real instruction (not label or comment), call f,
which must return either None or a list of instruction. If it
returns None, nothing happens. If it returns a list, then the
instruction is replaced by this list.</p>
For each real instruction i (not label or comment), replace it
with the list of instructions given by f(i).</p>
</dd></dl>
<dl class="py method">

View File

@ -88,7 +88,7 @@ is inherited by <a class="reference internal" href="#Lib.Statement.Instru3A" tit
<a class="reference internal" href="#Lib.Statement.AbsoluteJump" title="Lib.Statement.AbsoluteJump"><code class="xref py py-class docutils literal notranslate"><span class="pre">AbsoluteJump</span></code></a> and <a class="reference internal" href="#Lib.Statement.ConditionalJump" title="Lib.Statement.ConditionalJump"><code class="xref py py-class docutils literal notranslate"><span class="pre">ConditionalJump</span></code></a>.</p>
<dl class="py function">
<dt class="sig sig-object py" id="Lib.Statement.regset_to_string">
<span class="sig-prename descclassname"><span class="pre">Lib.Statement.</span></span><span class="sig-name descname"><span class="pre">regset_to_string</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">registerset</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Statement.html#regset_to_string"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Statement.regset_to_string" title="Permalink to this definition"></a></dt>
<span class="sig-prename descclassname"><span class="pre">Lib.Statement.</span></span><span class="sig-name descname"><span class="pre">regset_to_string</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">registerset</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="reference internal" href="../_modules/Lib/Statement.html#regset_to_string"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Statement.regset_to_string" title="Permalink to this definition"></a></dt>
<dd><p>Utility function: pretty-prints a set of locations.</p>
</dd></dl>

View File

@ -325,6 +325,8 @@
<li><a href="api/Lib.CFG.html#Lib.CFG.CFG.get_blocks">get_blocks() (Lib.CFG.CFG method)</a>
</li>
<li><a href="api/Lib.CFG.html#Lib.CFG.Block.get_body">get_body() (Lib.CFG.Block method)</a>
</li>
<li><a href="api/Lib.CFG.html#Lib.CFG.Block.get_body_and_terminator">get_body_and_terminator() (Lib.CFG.Block method)</a>
</li>
<li><a href="api/Lib.CFG.html#Lib.CFG.CFG.get_end">get_end() (Lib.CFG.CFG method)</a>
</li>
@ -635,6 +637,8 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api/Lib.PhiNode.html#Lib.PhiNode.PhiNode">PhiNode (class in Lib.PhiNode)</a>
</li>
<li><a href="api/Lib.Graphes.html#Lib.Graphes.DiGraph.pred">pred() (Lib.Graphes.DiGraph method)</a>
</li>
<li><a href="api/Lib.Allocator.html#Lib.Allocator.Allocator.prepare">prepare() (Lib.Allocator.Allocator method)</a>

Binary file not shown.

File diff suppressed because one or more lines are too long