Commit TP5b
This commit is contained in:
parent
1c151ffe93
commit
a89ae6ffb7
@ -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:
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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
99
MiniC/TP05/LivenessSSA.py
Normal 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("]")
|
||||
99
MiniC/TP05/SmartAllocator.py
Normal file
99
MiniC/TP05/SmartAllocator.py
Normal 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
BIN
MiniC/TP05/tp5b.pdf
Normal file
Binary file not shown.
@ -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")
|
||||
|
||||
@ -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/).
|
||||
|
||||
|
||||
@ -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">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Statement</span><span class="p">]:</span>
|
||||
<span class="sd">"""</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"> """</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">-></span> <span class="n">Label</span><span class="p">:</span>
|
||||
<span class="sd">"""Return the label of the block."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_label</span></div>
|
||||
|
||||
@ -234,7 +234,9 @@
|
||||
<span class="sd">"""Print the graph."""</span>
|
||||
<span class="n">color_names</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'red'</span><span class="p">,</span> <span class="s1">'blue'</span><span class="p">,</span> <span class="s1">'green'</span><span class="p">,</span> <span class="s1">'yellow'</span><span class="p">,</span> <span class="s1">'cyan'</span><span class="p">,</span> <span class="s1">'magenta'</span><span class="p">]</span> <span class="o">+</span> \
|
||||
<span class="p">[</span><span class="sa">f</span><span class="s2">"grey</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">"</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">'ellipse'</span><span class="p">,</span> <span class="s1">'polygon'</span><span class="p">,</span> <span class="s1">'box'</span><span class="p">,</span> <span class="s1">'circle'</span><span class="p">,</span> <span class="s1">'egg'</span><span class="p">,</span> <span class="s1">'pentagon'</span><span class="p">,</span> <span class="s1">'hexagon'</span><span class="p">]</span>
|
||||
<span class="n">color_shapes</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'ellipse'</span><span class="p">,</span> <span class="s1">'box'</span><span class="p">,</span> <span class="s1">'diamond'</span><span class="p">,</span> <span class="s1">'trapezium'</span><span class="p">,</span> <span class="s1">'egg'</span><span class="p">,</span>
|
||||
<span class="s1">'parallelogram'</span><span class="p">,</span> <span class="s1">'house'</span><span class="p">,</span> <span class="s1">'triangle'</span><span class="p">,</span> <span class="s1">'pentagon'</span><span class="p">,</span> <span class="s1">'hexagon'</span><span class="p">,</span>
|
||||
<span class="s1">'septagon'</span><span class="p">,</span> <span class="s1">'octagon'</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">'Conflict Graph'</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">"""Class for directed graphs."""</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">-></span> <span class="n">Set</span><span class="p">:</span>
|
||||
<span class="sd">"""Return all predecessors of the vertex `v` in the graph."""</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">-></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">"""Return all neighbourhoods in the graph."""</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>
|
||||
|
||||
@ -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">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""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"> """</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">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Print integer value, with newline. (see Expand)"""</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">'println_int'</span><span class="p">)))</span></div>
|
||||
|
||||
|
||||
@ -146,6 +146,9 @@
|
||||
|
||||
|
||||
<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">-></span> <span class="n">Instru3A</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
|
||||
<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">"xori"</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">"xor"</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>
|
||||
|
||||
|
||||
|
||||
@ -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">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="sd">"""Utility function: pretty-prints a set of locations."""</span>
|
||||
<span class="k">return</span> <span class="s2">"{"</span> <span class="o">+</span> <span class="s2">","</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">"}"</span></div>
|
||||
|
||||
|
||||
@ -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">→</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">→</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>
|
||||
|
||||
@ -230,6 +230,12 @@ Return a dict vertex -> 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">→</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">→</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>
|
||||
|
||||
@ -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">→</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">
|
||||
|
||||
@ -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">→</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>
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
BIN
docs/objects.inv
BIN
docs/objects.inv
Binary file not shown.
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user