Compare commits
No commits in common. "main" and "TP03" have entirely different histories.
@ -17,9 +17,8 @@ class PhiNode(Statement):
|
|||||||
"""
|
"""
|
||||||
A φ node is a renaming in the CFG, of the form temp_x = φ(temp_0, ..., temp_n).
|
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 var contains the variable temp_x.
|
||||||
The field srcs links each corresponding predecessor in the CFG
|
The field srcs relies for each precedent block in the CFG, identified with its label,
|
||||||
---identified by its label---, to the variable temp_i of the φ
|
the variable temp_i of the φ node.
|
||||||
node.
|
|
||||||
"""
|
"""
|
||||||
var: DataLocation
|
var: DataLocation
|
||||||
srcs: Dict[Label, Operand]
|
srcs: Dict[Label, Operand]
|
||||||
|
@ -1,30 +1,21 @@
|
|||||||
# MiniC Compiler
|
# MiniC Compiler
|
||||||
LAB5a (Control Flow Graph in SSA Form) & LAB5b (Smart Register Allocation), CAP 2023-24
|
LAB5a (Control Flow Graph in SSA Form) & LAB5b (Smart Register Allocation), CAP 2022-23
|
||||||
|
|
||||||
# Authors
|
# Authors
|
||||||
|
|
||||||
Augustin LUCAS
|
YOUR NAME HERE
|
||||||
|
|
||||||
# Contents
|
# Contents
|
||||||
|
|
||||||
Extension implemented : Optimizing swap
|
TODO:
|
||||||
- Cycles of size 1 : skip
|
- Explain any design choices you may have made.
|
||||||
- Cycles of size 2 : use 3 XOR operations to swap the registers values without any temporary register use
|
- Do not forget to remove all debug traces from your code!
|
||||||
|
- Did you implement an extension?
|
||||||
|
|
||||||
# Test design
|
# Test design
|
||||||
|
|
||||||
No tests were added since some of the `students`' tests from lab4 still failed to execute properly.
|
TODO: give the main objectives of your tests.
|
||||||
|
|
||||||
# Known bugs
|
# Known bugs
|
||||||
|
|
||||||
Failing tests:
|
TODO: bugs you could not fix (if any).
|
||||||
- `./TP04/tests/students/ext-for-fortran/test_imbricated_for.c`
|
|
||||||
- `./TP04/tests/students/ext-for-fortran/test_for.c`
|
|
||||||
- `./TP04/tests/students/base/test_nested_while.c`
|
|
||||||
- `./TP04/tests/students/base/test_fibonacci.c`
|
|
||||||
- `./TP04/tests/provided/dataflow/df03.c`
|
|
||||||
|
|
||||||
The bug seems to be related to the handling of Offsets because a lot more tests will fail if temporaries are only assigned to memory (no registers).
|
|
||||||
This can be done by commenting `TP05/SmartAllocator.py:124`.
|
|
||||||
|
|
||||||
This seems to affect `while` and `for` loops as well as regular variables (because variables may not be stored/loaded correctly).
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# MiniC Compiler
|
# MiniC Compiler
|
||||||
LAB5 (smart code generation), MIF08 / CAP 2023-24
|
LAB5 (smart code generation), MIF08 / CAP 2022-23
|
||||||
|
|
||||||
# Authors
|
# Authors
|
||||||
|
|
||||||
|
@ -1,21 +1,26 @@
|
|||||||
# MiniC Compiler
|
# MiniC Compiler
|
||||||
LAB4 (simple code generation), MIF08 / CAP 2023-24
|
LAB4 (simple code generation), MIF08 / CAP 2022-23
|
||||||
|
|
||||||
# Authors
|
# Authors
|
||||||
|
|
||||||
Augustin LUCAS
|
YOUR NAME HERE
|
||||||
|
|
||||||
# Contents
|
# Contents
|
||||||
|
|
||||||
|
TODO for STUDENTS : Say a bit about the code infrastructure ...
|
||||||
|
|
||||||
# Test design
|
# Test design
|
||||||
|
|
||||||
|
TODO: explain your tests
|
||||||
|
|
||||||
# Design choices
|
# Design choices
|
||||||
|
|
||||||
Booleans are implemented as integers behind the scenes, but type-checking before compilation disables any casting mechanism.
|
TODO: explain your choices. How did you implement boolean not? Did you implement an extension?
|
||||||
As for the previous lab, the Fortran-like for-loop extension has been implemented.
|
|
||||||
|
|
||||||
# Known bugs
|
# Known bugs
|
||||||
|
|
||||||
|
TODO: Bugs and limitations.
|
||||||
|
|
||||||
# Checklists
|
# Checklists
|
||||||
|
|
||||||
A check ([X]) means that the feature is implemented
|
A check ([X]) means that the feature is implemented
|
||||||
@ -23,30 +28,30 @@ and *tested* with appropriate test cases.
|
|||||||
|
|
||||||
## Code generation
|
## Code generation
|
||||||
|
|
||||||
- [x] Number Atom
|
- [ ] Number Atom
|
||||||
- [x] Boolean Atom
|
- [ ] Boolean Atom
|
||||||
- [x] Id Atom
|
- [ ] Id Atom
|
||||||
- [x] Additive expression
|
- [ ] Additive expression
|
||||||
- [x] Multiplicative expression
|
- [ ] Multiplicative expression
|
||||||
- [x] UnaryMinus expression
|
- [ ] UnaryMinus expression
|
||||||
- [x] Or expression
|
- [ ] Or expression
|
||||||
- [x] And expression
|
- [ ] And expression
|
||||||
- [x] Equality expression
|
- [ ] Equality expression
|
||||||
- [x] Relational expression (! many cases -> many tests)
|
- [ ] Relational expression (! many cases -> many tests)
|
||||||
- [x] Not expression
|
- [ ] Not expression
|
||||||
|
|
||||||
## Statements
|
## Statements
|
||||||
|
|
||||||
- [x] Prog, assignements
|
- [ ] Prog, assignements
|
||||||
- [x] While
|
- [ ] While
|
||||||
- [x] Cond Block
|
- [ ] Cond Block
|
||||||
- [x] If
|
- [ ] If
|
||||||
- [x] Nested ifs
|
- [ ] Nested ifs
|
||||||
- [x] Nested whiles
|
- [ ] Nested whiles
|
||||||
|
|
||||||
## Allocation
|
## Allocation
|
||||||
|
|
||||||
- [x] Naive allocation
|
- [ ] Naive allocation
|
||||||
- [x] All in memory allocation
|
- [ ] All in memory allocation
|
||||||
- [ ] Massive tests of memory allocation
|
- [ ] Massive tests of memory allocation
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# MiniC Compiler
|
# MiniC Compiler
|
||||||
LAB6 (code generation for functions), MIF08 / CAP 2023-24
|
LAB6 (code generation for functions), MIF08 / CAP 2022-23
|
||||||
|
|
||||||
# Authors
|
# Authors
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# MiniC interpreter and typer
|
# MiniC interpreter and typer
|
||||||
LAB3, MIF08 / CAP / CS444 2023-24
|
LAB3, MIF08 / CAP / CS444 2022-23
|
||||||
|
|
||||||
|
|
||||||
# Authors
|
# Authors
|
||||||
|
@ -14,25 +14,11 @@ class AllInMemAllocator(Allocator):
|
|||||||
before: List[Instruction] = []
|
before: List[Instruction] = []
|
||||||
after: List[Instruction] = []
|
after: List[Instruction] = []
|
||||||
new_args: List[Operand] = []
|
new_args: List[Operand] = []
|
||||||
|
# TODO: compute before,after,args.
|
||||||
for arg in old_instr.defined():
|
# TODO: iterate over old_args, check which argument
|
||||||
if isinstance(arg, Temporary):
|
# TODO: is a temporary (e.g. isinstance(..., Temporary)),
|
||||||
after.append(RiscV.sd(
|
# TODO: and if so, generate ld/sd accordingly. Replace the
|
||||||
S[3], arg.get_alloced_loc()
|
# TODO: temporary with S[1], S[2] or S[3] physical registers.
|
||||||
))
|
|
||||||
new_args.append(S[3])
|
|
||||||
else:
|
|
||||||
new_args.append(arg)
|
|
||||||
|
|
||||||
for i, arg in enumerate(old_instr.used(), 1):
|
|
||||||
if isinstance(arg, Temporary):
|
|
||||||
before.append(RiscV.ld(
|
|
||||||
S[i], arg.get_alloced_loc()
|
|
||||||
))
|
|
||||||
new_args.append(S[i])
|
|
||||||
else:
|
|
||||||
new_args.append(arg)
|
|
||||||
|
|
||||||
new_instr = old_instr.with_args(new_args)
|
new_instr = old_instr.with_args(new_args)
|
||||||
return before + [new_instr] + after
|
return before + [new_instr] + after
|
||||||
|
|
||||||
|
@ -20,13 +20,7 @@ def find_leaders(instructions: List[CodeStatement]) -> List[int]:
|
|||||||
last is len(instructions)
|
last is len(instructions)
|
||||||
"""
|
"""
|
||||||
leaders: List[int] = [0]
|
leaders: List[int] = [0]
|
||||||
|
# TODO fill leaders
|
||||||
for i, instr in enumerate(instructions):
|
|
||||||
if isinstance(instr, Label):
|
|
||||||
leaders.append(i)
|
|
||||||
elif isinstance(instr, AbsoluteJump) or isinstance(instr, ConditionalJump):
|
|
||||||
leaders.append(i+1)
|
|
||||||
|
|
||||||
# The final "ret" is also a form of jump
|
# The final "ret" is also a form of jump
|
||||||
leaders.append(len(instructions))
|
leaders.append(len(instructions))
|
||||||
return leaders
|
return leaders
|
||||||
@ -70,15 +64,9 @@ def prepare_chunk(pre_chunk: List[CodeStatement], fdata: FunctionData) -> tuple[
|
|||||||
jump = None
|
jump = None
|
||||||
inner_statements: List[CodeStatement] = pre_chunk
|
inner_statements: List[CodeStatement] = pre_chunk
|
||||||
# Extract the first instruction from inner_statements if it is a label, or create a fresh one
|
# Extract the first instruction from inner_statements if it is a label, or create a fresh one
|
||||||
if isinstance(inner_statements[0], Label):
|
raise NotImplementedError() # TODO
|
||||||
label = inner_statements[0]
|
|
||||||
inner_statements = inner_statements[1:]
|
|
||||||
else:
|
|
||||||
label = fdata.fresh_label(fdata._name)
|
|
||||||
# Extract the last instruction from inner_statements if it is a jump, or do nothing
|
# Extract the last instruction from inner_statements if it is a jump, or do nothing
|
||||||
if len(inner_statements) > 0 and (isinstance(inner_statements[-1], ConditionalJump) or isinstance(inner_statements[-1], AbsoluteJump)):
|
raise NotImplementedError() # TODO
|
||||||
jump = inner_statements[-1]
|
|
||||||
inner_statements = inner_statements[:-1]
|
|
||||||
# Check that there is no other label or jump left in inner_statements
|
# Check that there is no other label or jump left in inner_statements
|
||||||
l: List[BlockInstr] = []
|
l: List[BlockInstr] = []
|
||||||
for i in inner_statements:
|
for i in inner_statements:
|
||||||
|
@ -20,6 +20,7 @@ def linearize(cfg: CFG) -> List[Statement]:
|
|||||||
"""
|
"""
|
||||||
Linearize the given control flow graph as a list of instructions.
|
Linearize the given control flow graph as a list of instructions.
|
||||||
"""
|
"""
|
||||||
|
# TODO
|
||||||
l: List[Statement] = [] # Linearized CFG
|
l: List[Statement] = [] # Linearized CFG
|
||||||
blocks: List[Block] = ordered_blocks_list(cfg) # All blocks of the CFG
|
blocks: List[Block] = ordered_blocks_list(cfg) # All blocks of the CFG
|
||||||
for i, block in enumerate(blocks):
|
for i, block in enumerate(blocks):
|
||||||
@ -33,7 +34,6 @@ def linearize(cfg: CFG) -> List[Statement]:
|
|||||||
l.append(ConditionalJump(j.cond, j.op1, j.op2, j.label_then))
|
l.append(ConditionalJump(j.cond, j.op1, j.op2, j.label_then))
|
||||||
l.append(AbsoluteJump(j.label_else))
|
l.append(AbsoluteJump(j.label_else))
|
||||||
case AbsoluteJump() as j:
|
case AbsoluteJump() as j:
|
||||||
if i+1 == len(blocks) or j != blocks[i+1].get_label():
|
|
||||||
l.append(AbsoluteJump(j.label))
|
l.append(AbsoluteJump(j.label))
|
||||||
case Return():
|
case Return():
|
||||||
l.append(AbsoluteJump(cfg.get_end()))
|
l.append(AbsoluteJump(cfg.get_end()))
|
||||||
|
@ -74,13 +74,8 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
raise MiniCUnsupportedError("float literal")
|
raise MiniCUnsupportedError("float literal")
|
||||||
|
|
||||||
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
|
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
|
||||||
dest = self._current_function.fdata.fresh_tmp()
|
# true is 1 false is 0
|
||||||
self._current_function.add_instruction(
|
raise NotImplementedError() # TODO
|
||||||
RiscV.li(
|
|
||||||
dest, Operands.Immediate(1 if ctx.getText() == "true" else 0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return dest # true is 1 false is 0
|
|
||||||
|
|
||||||
def visitIdAtom(self, ctx) -> Operands.Temporary:
|
def visitIdAtom(self, ctx) -> Operands.Temporary:
|
||||||
try:
|
try:
|
||||||
@ -104,37 +99,13 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
assert ctx.myop is not None
|
assert ctx.myop is not None
|
||||||
tmpl: Operands.Temporary = self.visit(ctx.expr(0))
|
tmpl: Operands.Temporary = self.visit(ctx.expr(0))
|
||||||
tmpr: Operands.Temporary = self.visit(ctx.expr(1))
|
tmpr: Operands.Temporary = self.visit(ctx.expr(1))
|
||||||
tmp = self._current_function.fdata.fresh_tmp()
|
raise NotImplementedError() # TODO
|
||||||
|
|
||||||
if ctx.myop.type == MiniCParser.PLUS:
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.add(tmp, tmpl, tmpr)
|
|
||||||
)
|
|
||||||
elif ctx.myop.type == MiniCParser.MINUS:
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.sub(tmp, tmpl, tmpr)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
raise MiniCInternalError(
|
|
||||||
f"Unknown additive operator '{ctx.myop}'")
|
|
||||||
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
def visitOrExpr(self, ctx) -> Operands.Temporary:
|
def visitOrExpr(self, ctx) -> Operands.Temporary:
|
||||||
tmp = self._current_function.fdata.fresh_tmp()
|
raise NotImplementedError() # TODO
|
||||||
t1, t2 = self.visit(ctx.expr(0)), self.visit(ctx.expr(1))
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.lor(tmp, t1, t2)
|
|
||||||
)
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
def visitAndExpr(self, ctx) -> Operands.Temporary:
|
def visitAndExpr(self, ctx) -> Operands.Temporary:
|
||||||
tmp = self._current_function.fdata.fresh_tmp()
|
raise NotImplementedError() # TODO
|
||||||
t1, t2 = self.visit(ctx.expr(0)), self.visit(ctx.expr(1))
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.land(tmp, t1, t2)
|
|
||||||
)
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
def visitEqualityExpr(self, ctx) -> Operands.Temporary:
|
def visitEqualityExpr(self, ctx) -> Operands.Temporary:
|
||||||
return self.visitRelationalExpr(ctx)
|
return self.visitRelationalExpr(ctx)
|
||||||
@ -146,83 +117,18 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
print("relational expression:")
|
print("relational expression:")
|
||||||
print(Trees.toStringTree(ctx, [], self._parser))
|
print(Trees.toStringTree(ctx, [], self._parser))
|
||||||
print("Condition:", c)
|
print("Condition:", c)
|
||||||
|
raise NotImplementedError() # TODO
|
||||||
dest = self._current_function.fdata.fresh_tmp()
|
|
||||||
t1 = self.visit(ctx.expr(0))
|
|
||||||
t2 = self.visit(ctx.expr(1))
|
|
||||||
|
|
||||||
endrel = self._current_function.fdata.fresh_label("end_rel")
|
|
||||||
|
|
||||||
# dest <- 1
|
|
||||||
# t1 cond t2 ? jmp end
|
|
||||||
# dest <- 0
|
|
||||||
# end:
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.li(dest, Operands.Immediate(1)))
|
|
||||||
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.conditional_jump(endrel, t1, Condition(ctx.myop.type), t2))
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.li(dest, Operands.Immediate(0)))
|
|
||||||
|
|
||||||
self._current_function.add_label(endrel)
|
|
||||||
return dest
|
|
||||||
|
|
||||||
def visitMultiplicativeExpr(self, ctx) -> Operands.Temporary:
|
def visitMultiplicativeExpr(self, ctx) -> Operands.Temporary:
|
||||||
assert ctx.myop is not None
|
assert ctx.myop is not None
|
||||||
div_by_zero_lbl = self._current_function.fdata.get_label_div_by_zero()
|
div_by_zero_lbl = self._current_function.fdata.get_label_div_by_zero()
|
||||||
t1 = self.visit(ctx.expr(0))
|
raise NotImplementedError() # TODO
|
||||||
t2 = self.visit(ctx.expr(1))
|
|
||||||
dest = self._current_function.fdata.fresh_tmp()
|
|
||||||
|
|
||||||
if ctx.myop.type == MiniCParser.DIV or ctx.myop.type == MiniCParser.MOD:
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.conditional_jump(div_by_zero_lbl, t2, Condition("beq"), Operands.ZERO))
|
|
||||||
|
|
||||||
if ctx.myop.type == MiniCParser.MULT:
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.mul(dest, t1, t2))
|
|
||||||
elif ctx.myop.type == MiniCParser.DIV:
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.div(dest, t1, t2))
|
|
||||||
elif ctx.myop.type == MiniCParser.MOD:
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.rem(dest, t1, t2))
|
|
||||||
else:
|
|
||||||
raise MiniCInternalError(
|
|
||||||
f"Unknown additive operator '{ctx.myop}'")
|
|
||||||
|
|
||||||
return dest
|
|
||||||
|
|
||||||
def visitNotExpr(self, ctx) -> Operands.Temporary:
|
def visitNotExpr(self, ctx) -> Operands.Temporary:
|
||||||
dest = self._current_function.fdata.fresh_tmp()
|
raise NotImplementedError() # TODO
|
||||||
label_neq_zero = self._current_function.fdata.fresh_label("neq_zero")
|
|
||||||
t1 = self.visit(ctx.expr())
|
|
||||||
|
|
||||||
# dest <- 0
|
|
||||||
# t1 != dest ? jmp neq_zero
|
|
||||||
# dest <- 1
|
|
||||||
# neq_zero:
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.li(dest, Operands.Immediate(0))
|
|
||||||
)
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.conditional_jump(label_neq_zero, t1, Condition("bne"), Operands.ZERO)
|
|
||||||
)
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.li(dest, Operands.Immediate(1))
|
|
||||||
)
|
|
||||||
|
|
||||||
self._current_function.add_label(label_neq_zero)
|
|
||||||
return dest
|
|
||||||
|
|
||||||
def visitUnaryMinusExpr(self, ctx) -> Operands.Temporary:
|
def visitUnaryMinusExpr(self, ctx) -> Operands.Temporary:
|
||||||
dest = self._current_function.fdata.fresh_tmp()
|
raise NotImplementedError("unaryminusexpr") # TODO
|
||||||
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.sub(dest, Operands.ZERO, self.visit(ctx.expr()))
|
|
||||||
)
|
|
||||||
return dest
|
|
||||||
|
|
||||||
def visitProgRule(self, ctx) -> None:
|
def visitProgRule(self, ctx) -> None:
|
||||||
self.visitChildren(ctx)
|
self.visitChildren(ctx)
|
||||||
@ -254,25 +160,8 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
def visitIfStat(self, ctx) -> None:
|
def visitIfStat(self, ctx) -> None:
|
||||||
if self._debug:
|
if self._debug:
|
||||||
print("if statement")
|
print("if statement")
|
||||||
else_label = self._current_function.fdata.fresh_label("else_if")
|
|
||||||
end_if_label = self._current_function.fdata.fresh_label("end_if")
|
end_if_label = self._current_function.fdata.fresh_label("end_if")
|
||||||
|
raise NotImplementedError() # TODO
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.conditional_jump(
|
|
||||||
else_label, self.visit(ctx.expr()),
|
|
||||||
Condition('beq'), Operands.ZERO
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.visit(ctx.stat_block()[0])
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.jump(end_if_label)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._current_function.add_label(else_label)
|
|
||||||
if len(ctx.stat_block()) > 1:
|
|
||||||
self.visit(ctx.stat_block()[1])
|
|
||||||
|
|
||||||
self._current_function.add_label(end_if_label)
|
self._current_function.add_label(end_if_label)
|
||||||
|
|
||||||
def visitWhileStat(self, ctx) -> None:
|
def visitWhileStat(self, ctx) -> None:
|
||||||
@ -281,31 +170,7 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
print(Trees.toStringTree(ctx.expr(), [], self._parser))
|
print(Trees.toStringTree(ctx.expr(), [], self._parser))
|
||||||
print("and block is:")
|
print("and block is:")
|
||||||
print(Trees.toStringTree(ctx.stat_block(), [], self._parser))
|
print(Trees.toStringTree(ctx.stat_block(), [], self._parser))
|
||||||
|
raise NotImplementedError() # TODO
|
||||||
# ltest <- fresh_label()
|
|
||||||
loop_test = self._current_function.fdata.fresh_label("while_test")
|
|
||||||
# lendwhile <- fresh_label()
|
|
||||||
end_while = self._current_function.fdata.fresh_label("end_while")
|
|
||||||
# code.addLabel(ltest)
|
|
||||||
self._current_function.add_label(loop_test)
|
|
||||||
# t1 <- GenCodeExpr(b)
|
|
||||||
# code.add("beq lendwhile, t1, 0")
|
|
||||||
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.conditional_jump(
|
|
||||||
end_while, self.visit(ctx.expr()),
|
|
||||||
Condition('beq'), Operands.ZERO
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# GenCodeSmt(S) # execute S
|
|
||||||
self.visit(ctx.stat_block())
|
|
||||||
# code.add("j ltest") # and jump to the test
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.jump(loop_test)
|
|
||||||
)
|
|
||||||
# code.addLabel(lendwhile) # else it is done.
|
|
||||||
self._current_function.add_label(end_while)
|
|
||||||
|
|
||||||
# visit statements
|
# visit statements
|
||||||
|
|
||||||
def visitPrintlnintStat(self, ctx) -> None:
|
def visitPrintlnintStat(self, ctx) -> None:
|
||||||
@ -329,79 +194,3 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
for stat in ctx.stat():
|
for stat in ctx.stat():
|
||||||
self._current_function.add_comment(Trees.toStringTree(stat, [], self._parser))
|
self._current_function.add_comment(Trees.toStringTree(stat, [], self._parser))
|
||||||
self.visit(stat)
|
self.visit(stat)
|
||||||
|
|
||||||
def visitForStat(self, ctx) -> None:
|
|
||||||
def immediate_to_tmp(op):
|
|
||||||
if not isinstance(op, Operands.Immediate):
|
|
||||||
return op
|
|
||||||
new_op = self._current_function.fdata.fresh_tmp()
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.li(new_op, op))
|
|
||||||
return new_op
|
|
||||||
|
|
||||||
|
|
||||||
from_t = immediate_to_tmp(self.visit(ctx.expr(0)))
|
|
||||||
to_t = immediate_to_tmp(self.visit(ctx.expr(1)))
|
|
||||||
|
|
||||||
stride = Operands.Immediate(1)
|
|
||||||
if len(ctx.expr()) > 2:
|
|
||||||
stride = self.visit(ctx.expr(2))
|
|
||||||
|
|
||||||
stride = immediate_to_tmp(stride)
|
|
||||||
|
|
||||||
name = ctx.ID().getText()
|
|
||||||
if name not in self._symbol_table:
|
|
||||||
raise MiniCInternalError(
|
|
||||||
"Variable {} has not been declared before for loop".format(name))
|
|
||||||
|
|
||||||
variable = self._symbol_table[name] # variable acting as counter
|
|
||||||
for_test = self._current_function.fdata.fresh_label("forF_test")
|
|
||||||
end_for = self._current_function.fdata.fresh_label("end_forF")
|
|
||||||
body_for = self._current_function.fdata.fresh_label("body_forF")
|
|
||||||
neg_stride = self._current_function.fdata.fresh_label("neg_stride_forF")
|
|
||||||
counter = self._current_function.fdata.fresh_tmp() # real counter not affected by var. changes
|
|
||||||
|
|
||||||
# counter <- from
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.mv(counter, from_t))
|
|
||||||
#* for_test:
|
|
||||||
# var <- counter
|
|
||||||
# bge 0 stride neg_stride
|
|
||||||
# (positive stride here)
|
|
||||||
# ble counter to end_for
|
|
||||||
# j body
|
|
||||||
self._current_function.add_label(for_test)
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.mv(variable, counter))
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.conditional_jump(
|
|
||||||
neg_stride, Operands.ZERO,
|
|
||||||
Condition(MiniCParser.GTEQ), stride
|
|
||||||
))
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.conditional_jump(
|
|
||||||
end_for, counter,
|
|
||||||
Condition(MiniCParser.GTEQ), to_t
|
|
||||||
))
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.jump(body_for))
|
|
||||||
#* neg_stride:
|
|
||||||
# bl to counter end_for
|
|
||||||
self._current_function.add_label(neg_stride)
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.conditional_jump(
|
|
||||||
end_for, to_t,
|
|
||||||
Condition(MiniCParser.GTEQ), counter
|
|
||||||
))
|
|
||||||
#* body:
|
|
||||||
# <body>
|
|
||||||
# counter <- counter + stride
|
|
||||||
# j for_test
|
|
||||||
self._current_function.add_label(body_for)
|
|
||||||
self.visit(ctx.stat_block())
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.add(counter, counter, stride))
|
|
||||||
self._current_function.add_instruction(
|
|
||||||
RiscV.jump(for_test))
|
|
||||||
#* end_for:
|
|
||||||
self._current_function.add_label(end_for)
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
println_bool(true + false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 4 col 15: invalid type for additive operands: boolean and boolean
|
|
@ -1,16 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
bool x, y;
|
|
||||||
|
|
||||||
if (x <= y) {
|
|
||||||
println_string("ok");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 6 col 6: invalid type for non numeric type: boolean
|
|
@ -1,14 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
x = 5;
|
|
||||||
y = 0;
|
|
||||||
println_int(x/0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXECCODE 1
|
|
||||||
// EXPECTED
|
|
||||||
// Division by 0
|
|
@ -1,15 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
if (x != 0) {
|
|
||||||
y = 12;
|
|
||||||
} else {
|
|
||||||
y = -3;
|
|
||||||
}
|
|
||||||
println_int(y);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// -3
|
|
@ -1,27 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int num, result, i;
|
|
||||||
int prev1, prev2, tmp;
|
|
||||||
result = -1;
|
|
||||||
num = 15;
|
|
||||||
|
|
||||||
if (num < 2) {
|
|
||||||
result = num;
|
|
||||||
} else {
|
|
||||||
prev1 = 1;
|
|
||||||
prev2 = 0;
|
|
||||||
for i=2 to num {
|
|
||||||
tmp = prev1;
|
|
||||||
prev1 = prev1 + prev2;
|
|
||||||
prev2 = tmp;
|
|
||||||
}
|
|
||||||
result = prev1+prev2;
|
|
||||||
}
|
|
||||||
println_int(result);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXPECTED
|
|
||||||
// 610
|
|
@ -1,16 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
if (x) {
|
|
||||||
y = 5;
|
|
||||||
}
|
|
||||||
println_int(y);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 6 col 2: invalid type for non boolean as condition: integer
|
|
@ -1,15 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
while (x < 5000) {
|
|
||||||
y = x+1;
|
|
||||||
x = y+1;
|
|
||||||
}
|
|
||||||
println_int(x);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 5000
|
|
@ -1,19 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
x = 5;
|
|
||||||
y = 3;
|
|
||||||
println_int(x%y);
|
|
||||||
println_int((-x)%y);
|
|
||||||
y = 0;
|
|
||||||
println_int(x%y);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXECCODE 1
|
|
||||||
// EXPECTED
|
|
||||||
// 2
|
|
||||||
// -2
|
|
||||||
// Division by 0
|
|
@ -1,12 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
x = 12;
|
|
||||||
y = 5;
|
|
||||||
println_int(x*y);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 60
|
|
@ -1,33 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
if (true) {
|
|
||||||
if (false) {
|
|
||||||
println_int(-1);
|
|
||||||
} else {
|
|
||||||
println_int(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
println_int(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (false) {
|
|
||||||
if (false) {
|
|
||||||
println_int(-1);
|
|
||||||
} else {
|
|
||||||
println_int(-1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (true) {
|
|
||||||
println_int(2);
|
|
||||||
} else {
|
|
||||||
println_int(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 1
|
|
||||||
// 2
|
|
@ -1,25 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y, z;
|
|
||||||
while (x < 12) {
|
|
||||||
while (x < 25) {
|
|
||||||
x = x+2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println_int(x);
|
|
||||||
x = 0;
|
|
||||||
while (x < 5) {
|
|
||||||
x = x+1;
|
|
||||||
y = y+x;
|
|
||||||
while (z < 3) {
|
|
||||||
z = z+y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println_int(z);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 26
|
|
||||||
// 3
|
|
@ -1,14 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
bool x, y;
|
|
||||||
x = true;
|
|
||||||
y = false;
|
|
||||||
println_bool(!x);
|
|
||||||
println_bool(!y);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 0
|
|
||||||
// 1
|
|
@ -1,11 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
println_int(!(12+2));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 4 col 14: invalid type for NOT: only boolean allowed: integer
|
|
@ -1,12 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
bool x, y;
|
|
||||||
x = true;
|
|
||||||
y = false;
|
|
||||||
println_bool(x || y);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 1
|
|
@ -1,14 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
println_bool(true);
|
|
||||||
println_bool(y+2);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 7 col 2: invalid type for println_bool statement: integer
|
|
@ -1,14 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
println_float(15.0);
|
|
||||||
println_float(y+2);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 7 col 2: invalid type for println_float statement: integer
|
|
@ -1,35 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
println_bool(1 < 2);
|
|
||||||
println_bool(1 < 1);
|
|
||||||
println_bool(2 < 1);
|
|
||||||
|
|
||||||
println_bool(1 <= 2);
|
|
||||||
println_bool(1 <= 1);
|
|
||||||
println_bool(2 <= 1);
|
|
||||||
|
|
||||||
println_bool(1 > 2);
|
|
||||||
println_bool(1 > 1);
|
|
||||||
println_bool(2 > 1);
|
|
||||||
|
|
||||||
println_bool(1 >= 2);
|
|
||||||
println_bool(1 >= 1);
|
|
||||||
println_bool(2 >= 1);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 1
|
|
||||||
// 0
|
|
||||||
// 0
|
|
||||||
// 1
|
|
||||||
// 1
|
|
||||||
// 0
|
|
||||||
// 0
|
|
||||||
// 0
|
|
||||||
// 1
|
|
||||||
// 0
|
|
||||||
// 1
|
|
||||||
// 1
|
|
@ -1,13 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x;
|
|
||||||
while (x < 12) {
|
|
||||||
x = x+2;
|
|
||||||
}
|
|
||||||
println_int(x);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 12
|
|
@ -1,17 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
while (x) {
|
|
||||||
y = 5;
|
|
||||||
x = x+1;
|
|
||||||
}
|
|
||||||
println_int(y);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 6 col 2: invalid type for non boolean as condition: integer
|
|
@ -1,32 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
int zero, trois;
|
|
||||||
trois = 3;
|
|
||||||
|
|
||||||
// simple loop
|
|
||||||
for x=zero to trois {
|
|
||||||
y = y+3;
|
|
||||||
}
|
|
||||||
println_int(y);
|
|
||||||
println_int(x);
|
|
||||||
|
|
||||||
// inversed loop
|
|
||||||
for x=5 to 1 by -2 {
|
|
||||||
println_int(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// empty loop
|
|
||||||
for x=5 to 0 {
|
|
||||||
println_int(-1);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXPECTED
|
|
||||||
// 9
|
|
||||||
// 3
|
|
||||||
// 5
|
|
||||||
// 3
|
|
@ -1,18 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int i, count;
|
|
||||||
|
|
||||||
for i=0 to 6 {
|
|
||||||
for i=0 to 6 {
|
|
||||||
count = count + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println_int(count);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXPECTED
|
|
||||||
// 36
|
|
@ -1,17 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
float fl;
|
|
||||||
fl = 12.0;
|
|
||||||
|
|
||||||
for x=fl to 3 {
|
|
||||||
y = y+3;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 8 col 2: invalid type for non-integer from value: float
|
|
@ -1,17 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
float fl;
|
|
||||||
fl = 12.0;
|
|
||||||
|
|
||||||
for fl=0 to 3 {
|
|
||||||
y = y+3;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 8 col 2: invalid type for non-integer for loop counter: float
|
|
@ -1,15 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
for x=0 to 3 by 1.0 {
|
|
||||||
y = y+3;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 6 col 2: invalid type for non-integer stride value: float
|
|
@ -1,17 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
float fl;
|
|
||||||
fl = 12.0;
|
|
||||||
|
|
||||||
for x=0 to fl {
|
|
||||||
y = y+3;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 8 col 2: invalid type for non-integer to value: float
|
|
@ -1,15 +0,0 @@
|
|||||||
#include "printlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
for undef=0 to 3 {
|
|
||||||
y = y+3;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP TEST EXPECTED
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 6 col 2: Undefined variable undef
|
|
@ -5,8 +5,8 @@ Functions to convert a CFG into SSA Form.
|
|||||||
|
|
||||||
from typing import List, Dict, Set
|
from typing import List, Dict, Set
|
||||||
from Lib.CFG import Block, CFG
|
from Lib.CFG import Block, CFG
|
||||||
from Lib.Operands import Renamer, Operand
|
from Lib.Operands import Renamer
|
||||||
from Lib.Statement import Instruction, Label
|
from Lib.Statement import Instruction
|
||||||
from Lib.PhiNode import PhiNode
|
from Lib.PhiNode import PhiNode
|
||||||
from Lib.Dominators import computeDom, computeDT, computeDF
|
from Lib.Dominators import computeDom, computeDT, computeDF
|
||||||
|
|
||||||
@ -25,14 +25,8 @@ def insertPhis(cfg: CFG, DF: Dict[Block, Set[Block]]) -> None:
|
|||||||
d = queue.pop(0)
|
d = queue.pop(0)
|
||||||
for b in DF[d]:
|
for b in DF[d]:
|
||||||
if b not in has_phi:
|
if b not in has_phi:
|
||||||
srcs: Dict[Label, Operand] = {
|
# TODO add a phi node in block `b` (Lab 5a, Exercise 4)
|
||||||
x.get_label(): var for x in b.get_in()
|
raise NotImplementedError("insertPhis")
|
||||||
}
|
|
||||||
phi = PhiNode(var, srcs)
|
|
||||||
b.add_phi(phi)
|
|
||||||
|
|
||||||
queue.append(b)
|
|
||||||
has_phi.add(b)
|
|
||||||
|
|
||||||
|
|
||||||
def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Block) -> None:
|
def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Block) -> None:
|
||||||
@ -49,8 +43,7 @@ def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Blo
|
|||||||
for i in succ.get_phis():
|
for i in succ.get_phis():
|
||||||
assert (isinstance(i, PhiNode))
|
assert (isinstance(i, PhiNode))
|
||||||
i.rename_from(renamer, b.get_label())
|
i.rename_from(renamer, b.get_label())
|
||||||
for succ in DT[b]:
|
# TODO recursive call(s) of rename_block (Lab 5a, Exercise 5)
|
||||||
rename_block(cfg, DT, renamer, succ)
|
|
||||||
|
|
||||||
|
|
||||||
def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None:
|
def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None:
|
||||||
@ -61,8 +54,7 @@ def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None:
|
|||||||
This is an helper function called during SSA entry.
|
This is an helper function called during SSA entry.
|
||||||
"""
|
"""
|
||||||
renamer = Renamer(cfg.fdata._pool)
|
renamer = Renamer(cfg.fdata._pool)
|
||||||
for b in cfg.get_entries():
|
# TODO initial call(s) to rename_block (Lab 5a, Exercise 5)
|
||||||
rename_block(cfg, DT, renamer, b)
|
|
||||||
|
|
||||||
|
|
||||||
def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
|
def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
|
||||||
@ -74,8 +66,5 @@ def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
|
|||||||
`dom_graphs` indicates if we have to print the domination graphs.
|
`dom_graphs` indicates if we have to print the domination graphs.
|
||||||
`basename` is used for the names of the produced graphs.
|
`basename` is used for the names of the produced graphs.
|
||||||
"""
|
"""
|
||||||
dom = computeDom(cfg)
|
# TODO implement this function (Lab 5a, Exercise 2)
|
||||||
DT = computeDT(cfg, dom, dom_graphs, basename)
|
raise NotImplementedError("enter_ssa")
|
||||||
DF = computeDF(cfg, dom, DT, dom_graphs, basename)
|
|
||||||
insertPhis(cfg, DF)
|
|
||||||
rename_variables(cfg, DT)
|
|
||||||
|
@ -6,14 +6,14 @@ Functions to convert a CFG out of SSA Form.
|
|||||||
from typing import cast, List
|
from typing import cast, List
|
||||||
from Lib import RiscV
|
from Lib import RiscV
|
||||||
from Lib.CFG import Block, BlockInstr, CFG
|
from Lib.CFG import Block, BlockInstr, CFG
|
||||||
from Lib.Operands import Temporary, DataLocation
|
from Lib.Operands import Temporary
|
||||||
from Lib.Statement import AbsoluteJump, Label
|
from Lib.Statement import AbsoluteJump
|
||||||
from Lib.Terminator import BranchingTerminator, Return
|
from Lib.Terminator import BranchingTerminator, Return
|
||||||
from Lib.PhiNode import PhiNode
|
from Lib.PhiNode import PhiNode
|
||||||
from TP05.SequentializeMoves import sequentialize_moves, generate_smart_move
|
from TP05.SequentializeMoves import sequentialize_moves
|
||||||
|
|
||||||
|
|
||||||
def generate_moves_from_phis(phis: List[PhiNode], parent: Block, is_smart: bool=False) -> List[BlockInstr]:
|
def generate_moves_from_phis(phis: List[PhiNode], parent: Block) -> List[BlockInstr]:
|
||||||
"""
|
"""
|
||||||
`generate_moves_from_phis(phis, parent)` builds a list of move instructions
|
`generate_moves_from_phis(phis, parent)` builds a list of move instructions
|
||||||
to be inserted in a new block between `parent` and the block with phi nodes
|
to be inserted in a new block between `parent` and the block with phi nodes
|
||||||
@ -21,32 +21,10 @@ def generate_moves_from_phis(phis: List[PhiNode], parent: Block, is_smart: bool=
|
|||||||
|
|
||||||
This is an helper function called during SSA exit.
|
This is an helper function called during SSA exit.
|
||||||
"""
|
"""
|
||||||
# (Lab 5a, Exercise 6)
|
|
||||||
lbl = parent.get_label()
|
|
||||||
if is_smart:
|
|
||||||
parallel_moves: set[tuple[DataLocation, DataLocation]] = set()
|
|
||||||
moves: List[BlockInstr] = []
|
moves: List[BlockInstr] = []
|
||||||
for phi in phis:
|
# TODO compute 'moves', a list of 'mv' instructions to insert under parent
|
||||||
if lbl not in phi.get_srcs():
|
# (Lab 5a, Exercise 6)
|
||||||
continue
|
return moves
|
||||||
src = phi.get_srcs()[lbl]
|
|
||||||
if isinstance(src, Temporary) or isinstance(phi.var, Temporary):
|
|
||||||
loc1, loc2 = phi.var, src
|
|
||||||
if isinstance(loc1, Temporary):
|
|
||||||
loc1 = loc1.get_alloced_loc()
|
|
||||||
if isinstance(loc2, Temporary):
|
|
||||||
loc2 = loc2.get_alloced_loc()
|
|
||||||
moves += generate_smart_move(loc1, cast(DataLocation, loc2))
|
|
||||||
else:
|
|
||||||
src = phi.get_srcs()[lbl]
|
|
||||||
parallel_moves.add((phi.var, cast(DataLocation, src)))
|
|
||||||
return sequentialize_moves(parallel_moves)+moves
|
|
||||||
return [
|
|
||||||
RiscV.mv(
|
|
||||||
phi.var,
|
|
||||||
phi.get_srcs()[lbl]
|
|
||||||
) for phi in phis if lbl in phi.get_srcs()
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def exit_ssa(cfg: CFG, is_smart: bool) -> None:
|
def exit_ssa(cfg: CFG, is_smart: bool) -> None:
|
||||||
@ -60,22 +38,7 @@ def exit_ssa(cfg: CFG, is_smart: bool) -> None:
|
|||||||
b.remove_all_phis() # Remove all phi nodes in the block
|
b.remove_all_phis() # Remove all phi nodes in the block
|
||||||
parents: List[Block] = b.get_in().copy() # Copy as we modify it by adding blocks
|
parents: List[Block] = b.get_in().copy() # Copy as we modify it by adding blocks
|
||||||
for parent in parents:
|
for parent in parents:
|
||||||
# Add the block containing 'moves' to 'cfg'
|
moves = generate_moves_from_phis(phis, parent)
|
||||||
moves_label = cfg.fdata.fresh_label("merge_phi")
|
# TODO Add the block containing 'moves' to 'cfg'
|
||||||
block_moves = Block(moves_label, generate_moves_from_phis(phis, parent, is_smart=is_smart), AbsoluteJump(b.get_label()))
|
# and update edges and jumps accordingly (Lab 5a, Exercise 6)
|
||||||
cfg.add_block(block_moves)
|
raise NotImplementedError("exit_ssa")
|
||||||
|
|
||||||
# Update parent terminator
|
|
||||||
j = parent.get_terminator()
|
|
||||||
match j:
|
|
||||||
case AbsoluteJump():
|
|
||||||
new_terminator = AbsoluteJump(moves_label)
|
|
||||||
case BranchingTerminator():
|
|
||||||
lbl_else : Label = moves_label if (j.label_else == b.get_label()) else j.label_else
|
|
||||||
lbl_then : Label = moves_label if (j.label_then == b.get_label()) else j.label_then
|
|
||||||
new_terminator = BranchingTerminator(j.cond, j.op1, j.op2, lbl_else, lbl_then)
|
|
||||||
case Return():
|
|
||||||
new_terminator = AbsoluteJump(moves_label)
|
|
||||||
block_moves.set_terminator(Return())
|
|
||||||
|
|
||||||
parent.set_terminator(new_terminator)
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from typing import Dict, Set, Tuple
|
from typing import Dict, Set, Tuple
|
||||||
from Lib.Operands import Temporary
|
from Lib.Operands import Temporary
|
||||||
from Lib.Statement import Statement, regset_to_string, Instru3A
|
from Lib.Statement import Statement, regset_to_string
|
||||||
from Lib.CFG import Block, CFG
|
from Lib.CFG import Block, CFG
|
||||||
from Lib.PhiNode import PhiNode
|
from Lib.PhiNode import PhiNode
|
||||||
|
|
||||||
@ -35,41 +35,16 @@ class LivenessSSA:
|
|||||||
|
|
||||||
def livein_at_instruction(self, block: Block, pos: int, var: Temporary) -> None:
|
def livein_at_instruction(self, block: Block, pos: int, var: Temporary) -> None:
|
||||||
"""Backward propagation of liveness information at the beginning of an instruction."""
|
"""Backward propagation of liveness information at the beginning of an instruction."""
|
||||||
instr = block.get_all_statements()[pos]
|
raise NotImplementedError("LivenessSSA") # TODO (Lab 5b, Exercise 1)
|
||||||
|
|
||||||
if isinstance(instr, PhiNode) and var in instr.srcs.values():
|
|
||||||
bpred = self._cfg.get_block(
|
|
||||||
next(lbl for lbl, value in instr.srcs.items() if value == var)
|
|
||||||
)
|
|
||||||
self.liveout_at_block(bpred, var)
|
|
||||||
|
|
||||||
elif pos == 0:
|
|
||||||
for bpred in block.get_in():
|
|
||||||
self.liveout_at_block(bpred, var)
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.liveout_at_instruction(block, pos-1, var)
|
|
||||||
|
|
||||||
|
|
||||||
def liveout_at_instruction(self, block: Block, pos: int, var: Temporary) -> None:
|
def liveout_at_instruction(self, block: Block, pos: int, var: Temporary) -> None:
|
||||||
"""Backward propagation of liveness information at the end of an instruction."""
|
"""Backward propagation of liveness information at the end of an instruction."""
|
||||||
instr = block.get_all_statements()[pos]
|
instr = block.get_all_statements()[pos]
|
||||||
|
raise NotImplementedError("LivenessSSA") # TODO (Lab 5b, Exercise 1)
|
||||||
self._liveout[block, instr].add(var)
|
|
||||||
if var in instr.defined():
|
|
||||||
#self._seen[block].add(var)
|
|
||||||
return
|
|
||||||
|
|
||||||
self.livein_at_instruction(block, pos, var)
|
|
||||||
#self._seen[block].add(var)
|
|
||||||
|
|
||||||
|
|
||||||
def liveout_at_block(self, block: Block, var: Temporary) -> None:
|
def liveout_at_block(self, block: Block, var: Temporary) -> None:
|
||||||
"""Backward propagation of liveness information at the end of a block."""
|
"""Backward propagation of liveness information at the end of a block."""
|
||||||
if var not in self._seen[block]:
|
raise NotImplementedError("LivenessSSA") # TODO (Lab 5b, Exercise 1)
|
||||||
self._seen[block].add(var)
|
|
||||||
self.liveout_at_instruction(block, len(block.get_all_statements())-1, var)
|
|
||||||
|
|
||||||
|
|
||||||
def gather_uses(self) -> Dict[Temporary, Set[Tuple[Block, int]]]:
|
def gather_uses(self) -> Dict[Temporary, Set[Tuple[Block, int]]]:
|
||||||
"""
|
"""
|
||||||
@ -92,9 +67,7 @@ class LivenessSSA:
|
|||||||
|
|
||||||
def conflict_on_phis(self) -> None:
|
def conflict_on_phis(self) -> None:
|
||||||
"""Ensures that variables defined by φ instructions are in conflict with one-another."""
|
"""Ensures that variables defined by φ instructions are in conflict with one-another."""
|
||||||
for block in self._cfg.get_blocks():
|
raise NotImplementedError("LivenessSSA") # TODO (Lab 5b, Exercise 1)
|
||||||
for phinode in block.get_phis():
|
|
||||||
self._liveout[block, phinode] = set([v for v in phinode.used() if isinstance(v, Temporary)])
|
|
||||||
|
|
||||||
def print_map_in_out(self) -> None: # pragma: no cover
|
def print_map_in_out(self) -> None: # pragma: no cover
|
||||||
"""Print live out sets at each instruction, group by block, useful for debugging!"""
|
"""Print live out sets at each instruction, group by block, useful for debugging!"""
|
||||||
|
@ -18,33 +18,11 @@ def generate_smart_move(dest: DataLocation, src: DataLocation) -> List[BlockInst
|
|||||||
This is an helper function for `sequentialize_moves`.
|
This is an helper function for `sequentialize_moves`.
|
||||||
"""
|
"""
|
||||||
instr: List[BlockInstr] = []
|
instr: List[BlockInstr] = []
|
||||||
tmp: Register = S[1]
|
# TODO Compute the moves (Lab 5b, Exercise 4)
|
||||||
|
raise NotImplementedError("generate_smart_move")
|
||||||
match dest, src:
|
|
||||||
case Register(), Register():
|
|
||||||
instr.append(RiscV.mv(dest, src))
|
|
||||||
case Register(), Offset():
|
|
||||||
instr.append(RiscV.ld(dest, src))
|
|
||||||
case Offset(), Register():
|
|
||||||
instr.append(RiscV.sd(src, dest))
|
|
||||||
case Offset(), Offset():
|
|
||||||
instr.append(RiscV.ld(tmp, src))
|
|
||||||
instr.append(RiscV.sd(tmp, dest))
|
|
||||||
case _, _:
|
|
||||||
raise ValueError(f"Unsupported operands {type(dest)} <- {type(src)}")
|
|
||||||
|
|
||||||
return instr
|
return instr
|
||||||
|
|
||||||
|
|
||||||
def swap_registers(r1: Register, r2: Register) -> List[BlockInstr]:
|
|
||||||
"""Swap two registers"""
|
|
||||||
return [
|
|
||||||
RiscV.xor(r1, r1, r2),
|
|
||||||
RiscV.xor(r2, r1, r2),
|
|
||||||
RiscV.xor(r1, r1, r2)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def sequentialize_moves(parallel_moves: Set[Tuple[DataLocation, DataLocation]]
|
def sequentialize_moves(parallel_moves: Set[Tuple[DataLocation, DataLocation]]
|
||||||
) -> List[BlockInstr]:
|
) -> List[BlockInstr]:
|
||||||
"""
|
"""
|
||||||
@ -61,39 +39,22 @@ def sequentialize_moves(parallel_moves: Set[Tuple[DataLocation, DataLocation]]
|
|||||||
move_graph.add_edge((src, dest))
|
move_graph.add_edge((src, dest))
|
||||||
# List for the sequentialized moves to do
|
# List for the sequentialized moves to do
|
||||||
# Convention: in moves we put (dest, src) for each move
|
# Convention: in moves we put (dest, src) for each move
|
||||||
moves: List[Tuple[DataLocation, DataLocation] | BlockInstr] = []
|
moves: List[Tuple[DataLocation, DataLocation]] = []
|
||||||
# First iteratively remove all the vertices without successors
|
# First iteratively remove all the vetices without successors
|
||||||
vars_without_successor = {src
|
vars_without_successor = {src
|
||||||
for src, dests in move_graph.neighbourhoods()
|
for src, dests in move_graph.neighbourhoods()
|
||||||
if len(dests) == 0}
|
if len(dests) == 0}
|
||||||
while vars_without_successor:
|
while vars_without_successor:
|
||||||
var = vars_without_successor.pop()
|
# TODO Remove the leaves iteratively (Lab 5b, Exercise 4)
|
||||||
for src in move_graph.pred(var):
|
raise NotImplementedError("sequentialize_moves: leaves")
|
||||||
moves.append((var, src))
|
|
||||||
dests = [dests for sr, dests in move_graph.neighbourhoods() if sr == src][0]
|
|
||||||
if len(dests) == 1:
|
|
||||||
vars_without_successor.add(src)
|
|
||||||
|
|
||||||
move_graph.delete_vertex(var)
|
|
||||||
# Then handle the cycles
|
# Then handle the cycles
|
||||||
cycles: List = move_graph.connected_components()
|
cycles: List = move_graph.connected_components()
|
||||||
for cycle in cycles:
|
for cycle in cycles:
|
||||||
if len(cycle) == 1:
|
# TODO Handle each cycle (Lab 5b, Exercise 4)
|
||||||
continue
|
raise NotImplementedError("sequentialize_moves: cycles")
|
||||||
if len(cycle) == 2 and isinstance(cycle[0], Register) and isinstance(cycle[1], Register):
|
|
||||||
moves += swap_registers(*cycle)
|
|
||||||
continue
|
|
||||||
previous = tmp
|
|
||||||
for var in reversed(cycle):
|
|
||||||
moves.append((previous, var))
|
|
||||||
previous = var
|
|
||||||
moves.append((previous, tmp))
|
|
||||||
# Transform the moves to do in actual RiscV instructions
|
# Transform the moves to do in actual RiscV instructions
|
||||||
moves_instr: List[BlockInstr] = []
|
moves_instr: List[BlockInstr] = []
|
||||||
for val in moves:
|
for dest, src in moves:
|
||||||
if isinstance(val, BlockInstr):
|
instrs = generate_smart_move(dest, src)
|
||||||
moves_instr.append(val)
|
|
||||||
continue
|
|
||||||
instrs = generate_smart_move(*val)
|
|
||||||
moves_instr.extend(instrs)
|
moves_instr.extend(instrs)
|
||||||
return moves_instr
|
return moves_instr
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
from typing import List, Dict
|
from typing import List, Dict
|
||||||
from Lib.Errors import MiniCInternalError
|
from Lib.Errors import MiniCInternalError
|
||||||
from Lib.Operands import Temporary, Operand, S, Offset, DataLocation, GP_REGS
|
from Lib.Operands import Temporary, Operand, S, Offset, DataLocation, GP_REGS
|
||||||
from Lib.Statement import Instruction, Instru3A
|
from Lib.Statement import Instruction
|
||||||
from Lib.Allocator import Allocator
|
from Lib.Allocator import Allocator
|
||||||
from Lib.FunctionData import FunctionData
|
from Lib.FunctionData import FunctionData
|
||||||
from Lib import RiscV
|
from Lib import RiscV
|
||||||
from Lib.Graphes import Graph # For Graph coloring utility functions
|
from Lib.Graphes import Graph # For Graph coloring utility functions
|
||||||
from TP05.SequentializeMoves import generate_smart_move
|
|
||||||
|
|
||||||
|
|
||||||
class SmartAllocator(Allocator):
|
class SmartAllocator(Allocator):
|
||||||
@ -29,27 +28,9 @@ class SmartAllocator(Allocator):
|
|||||||
before: List[Instruction] = []
|
before: List[Instruction] = []
|
||||||
after: List[Instruction] = []
|
after: List[Instruction] = []
|
||||||
new_args: List[Operand] = []
|
new_args: List[Operand] = []
|
||||||
|
# TODO (lab5): Compute before, after, subst. This is similar to what
|
||||||
for arg in old_instr.defined():
|
# TODO (lab5): replace from the Naive and AllInMem Allocators do (Lab 4).
|
||||||
match arg:
|
raise NotImplementedError("Smart Replace (lab5)") # TODO
|
||||||
case Offset():
|
|
||||||
after.append(RiscV.sd(S[3], arg))
|
|
||||||
new_args.append(S[3])
|
|
||||||
case Temporary():
|
|
||||||
new_args.append(arg.get_alloced_loc())
|
|
||||||
case _: # Contains Register()
|
|
||||||
new_args.append(arg)
|
|
||||||
|
|
||||||
for i, arg in enumerate(old_instr.used(), 1):
|
|
||||||
match arg:
|
|
||||||
case Offset():
|
|
||||||
before.append(RiscV.ld(S[i], arg))
|
|
||||||
new_args.append(S[i])
|
|
||||||
case Temporary():
|
|
||||||
new_args.append(arg.get_alloced_loc())
|
|
||||||
case _: # Contains Register()
|
|
||||||
new_args.append(arg)
|
|
||||||
|
|
||||||
# And now return the new list!
|
# And now return the new list!
|
||||||
instr = old_instr.with_args(new_args)
|
instr = old_instr.with_args(new_args)
|
||||||
return before + [instr] + after
|
return before + [instr] + after
|
||||||
@ -89,12 +70,7 @@ class SmartAllocator(Allocator):
|
|||||||
# Iterate over self._liveness._liveout (dictionary containing all
|
# Iterate over self._liveness._liveout (dictionary containing all
|
||||||
# live out temporaries for each instruction), and for each conflict use
|
# live out temporaries for each instruction), and for each conflict use
|
||||||
# self._igraph.add_edge((t1, t2)) to add the corresponding edge.
|
# self._igraph.add_edge((t1, t2)) to add the corresponding edge.
|
||||||
for (block, statement), vars in self._liveness._liveout.items():
|
raise NotImplementedError("build_interference_graph (lab5)") # TODO
|
||||||
for t1 in list(vars)+statement.defined():
|
|
||||||
for t2 in vars:
|
|
||||||
if t1 == t2:
|
|
||||||
continue
|
|
||||||
self._igraph.add_edge((t1, t2))
|
|
||||||
|
|
||||||
def smart_alloc(self) -> None:
|
def smart_alloc(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -103,7 +79,6 @@ class SmartAllocator(Allocator):
|
|||||||
|
|
||||||
Precondition: the interference graph _igraph must have been built.
|
Precondition: the interference graph _igraph must have been built.
|
||||||
"""
|
"""
|
||||||
regs = list(GP_REGS) # Get a writable copy
|
|
||||||
# Checking the interference graph has been built
|
# Checking the interference graph has been built
|
||||||
if not self._igraph:
|
if not self._igraph:
|
||||||
raise MiniCInternalError("Empty interference graph in the Smart Allocator")
|
raise MiniCInternalError("Empty interference graph in the Smart Allocator")
|
||||||
@ -117,15 +92,7 @@ class SmartAllocator(Allocator):
|
|||||||
alloc_dict: Dict[Temporary, DataLocation] = dict()
|
alloc_dict: Dict[Temporary, DataLocation] = dict()
|
||||||
# Use the coloring `coloringreg` to fill `alloc_dict`.
|
# Use the coloring `coloringreg` to fill `alloc_dict`.
|
||||||
# Our version is less than 5 lines of code.
|
# Our version is less than 5 lines of code.
|
||||||
color_dict: Dict[int, DataLocation] = dict()
|
raise NotImplementedError("Allocation based on graph coloring (lab5)") # TODO
|
||||||
for temp in self._fdata._pool.get_all_temps():
|
|
||||||
if coloringreg[temp] not in color_dict:
|
|
||||||
color_dict[coloringreg[temp]] = (
|
|
||||||
regs.pop() if len(regs) > 0 else
|
|
||||||
self._fdata.fresh_offset()
|
|
||||||
)
|
|
||||||
alloc_dict[temp] = color_dict[coloringreg[temp]]
|
|
||||||
|
|
||||||
if self._debug:
|
if self._debug:
|
||||||
print("Allocation:")
|
print("Allocation:")
|
||||||
print(alloc_dict)
|
print(alloc_dict)
|
||||||
|
@ -85,7 +85,6 @@ ALL_IN_MEM_FILES.sort()
|
|||||||
ALL_FILES = list(set(ALL_FILES))
|
ALL_FILES = list(set(ALL_FILES))
|
||||||
ALL_FILES.sort()
|
ALL_FILES.sort()
|
||||||
|
|
||||||
|
|
||||||
class TestCodeGen(TestExpectPragmas, TestCompiler):
|
class TestCodeGen(TestExpectPragmas, TestCompiler):
|
||||||
DISABLE_CODEGEN = DISABLE_CODEGEN
|
DISABLE_CODEGEN = DISABLE_CODEGEN
|
||||||
SKIP_NOT_IMPLEMENTED = SKIP_NOT_IMPLEMENTED
|
SKIP_NOT_IMPLEMENTED = SKIP_NOT_IMPLEMENTED
|
||||||
|
83
PLANNING.md
83
PLANNING.md
@ -31,7 +31,7 @@ _Academic first semester 2024-2025_
|
|||||||
|
|
||||||
# Week 3:
|
# Week 3:
|
||||||
|
|
||||||
- :hammer: Lab 2: Thursday 23/09/2024, 13h30-15h30. Room E001 103 & -138 (Grenat) (Samuel Humeau & Emma Nardino)
|
- :hammer: Lab 2: Thursday 23/09/2023, 13h30-15h30. Room E001 103 & -138 (Grenat) (Samuel Humeau & Emma Nardino)
|
||||||
|
|
||||||
* Lexing & Parsing with ANTLR4 [TP02](TP02/tp2.pdf).
|
* Lexing & Parsing with ANTLR4 [TP02](TP02/tp2.pdf).
|
||||||
* Code in [TP02/](TP02/).
|
* Code in [TP02/](TP02/).
|
||||||
@ -64,84 +64,3 @@ _Academic first semester 2024-2025_
|
|||||||
|
|
||||||
* SSA [slides in english](course/capmif_cours06a_ssa.pdf).
|
* SSA [slides in english](course/capmif_cours06a_ssa.pdf).
|
||||||
|
|
||||||
# Week 6:
|
|
||||||
|
|
||||||
- :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/).
|
|
||||||
* Documentation (updated) [here](docs/html/index.html).
|
|
||||||
|
|
||||||
- :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).
|
|
||||||
|
|
||||||
- :book: Course: Thursday 25/10/2024, 10h15-12h15. Amphi B (Gabriel Radanne)
|
|
||||||
|
|
||||||
* SSA Optims [slides in english](course/cap_cours06b_ssa_optim.pdf).
|
|
||||||
|
|
||||||
# Week 8:
|
|
||||||
|
|
||||||
- :hammer: Lab 5b (1/2): Monday 04/11/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino)
|
|
||||||
|
|
||||||
* Smart Register Allocation [TP05b](TP05/tp5b.pdf).
|
|
||||||
* Code in [MiniC/TP04/](MiniC/TP05/).
|
|
||||||
|
|
||||||
- :book: Course: Thursday 7/11/2024, 10h15-12h15. Amphi B (Gabriel Radanne)
|
|
||||||
|
|
||||||
* Beyond Imperative [slides in english](course/cap_cours_bonuscomp.pdf).
|
|
||||||
|
|
||||||
# Week 9:
|
|
||||||
|
|
||||||
- :hammer: Lab 5b (2/2): Monday 18/11/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino)
|
|
||||||
|
|
||||||
- :book: Course: Thursday 21/11/2024, 10h15-12h15. Amphi J (Yannick Zakowski)
|
|
||||||
|
|
||||||
* Functions: code generation [slides in english](course/cap_cours08_func_codegen.pdf).
|
|
||||||
|
|
||||||
# Week 10:
|
|
||||||
|
|
||||||
- :notebook: TD: Monday 25/11/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino)
|
|
||||||
|
|
||||||
- :book: Course: Thursday 28/11/2024, 10h15-12h15. Amphi B (Yannick Zakowski)
|
|
||||||
|
|
||||||
* Functions: semantics [slides in english](course/cap_cour309_func_semantics.pdf).
|
|
||||||
|
|
||||||
# Week 11:
|
|
||||||
|
|
||||||
- :hammer: Choice Lab (1/3): Monday 02/12/2024, 8h00-13h30. Room E001 (Samuel Humeau & Emma Nardino)
|
|
||||||
|
|
||||||
* Optimisations under SSA form [TP5c](TP05/tp5c.pdf), code in [MiniC/TPoptim/](MiniC/TPoptim/).
|
|
||||||
* Parsing and typechecking functions [TP06a](TP06/tp6a.pdf), code in [MiniC/](MiniC/).
|
|
||||||
* Code generation for functions [TP06b](TP06/tp6b.pdf), code in [MiniC/](MiniC/).
|
|
||||||
|
|
||||||
- :book: Course: Thursday 05/12/2024, 10h15-12h15. Amphi B (Yannick Zakowski)
|
|
||||||
|
|
||||||
* On parallelism [slides in english](course/cap_cours10_parallelism.pdf).
|
|
||||||
|
|
||||||
# Week 12:
|
|
||||||
|
|
||||||
- :hammer: Choice Lab (2/3): Thursday 09/12/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino)
|
|
||||||
|
|
||||||
* Optimisations under SSA form [TP5c](TP05/tp5c.pdf), code in [MiniC/TPoptim/](MiniC/TPoptim/).
|
|
||||||
* Parsing and typechecking functions [TP06a](TP06/tp6a.pdf), code in [MiniC/](MiniC/).
|
|
||||||
* Code generation for functions [TP06b](TP06/tp6b.pdf), code in [MiniC/](MiniC/).
|
|
||||||
* Going Parallel with futures [TPfutures](TPfutures/tpfutures.pdf), code in [TPfutures/MiniC-futures/](TPfutures/MiniC-futures/).
|
|
||||||
|
|
||||||
- :book: Course: Thursday 12/12/2024, 10h15-12h15. Amphi B (Yannick Zakowski)
|
|
||||||
|
|
||||||
* Verified Compilation [introduction slides](course/cap_cours11_verified.pdf).
|
|
||||||
* Course on black board
|
|
||||||
* Additional resources: [Xavier Leroy's class at Collège de France](https://www.college-de-france.fr/en/agenda/lecture/mechanized-semantics-when-the-machine-reasons-about-its-languages)
|
|
||||||
|
|
||||||
# Week 13:
|
|
||||||
|
|
||||||
- :hammer: Choice Lab (3/3): Monday 16/12/2024, 13h30-15h30. Room E001 (Samuel Humeau & Emma Nardino)
|
|
||||||
|
BIN
TD/td_cap.pdf
BIN
TD/td_cap.pdf
Binary file not shown.
Binary file not shown.
BIN
TP04/tp4b.pdf
BIN
TP04/tp4b.pdf
Binary file not shown.
BIN
TP05/tp5a.pdf
BIN
TP05/tp5a.pdf
Binary file not shown.
BIN
TP05/tp5b.pdf
BIN
TP05/tp5b.pdf
Binary file not shown.
BIN
TP05/tp5c.pdf
BIN
TP05/tp5c.pdf
Binary file not shown.
BIN
TP06/tp6a.pdf
BIN
TP06/tp6a.pdf
Binary file not shown.
BIN
TP06/tp6b.pdf
BIN
TP06/tp6b.pdf
Binary file not shown.
15
TPfutures/MiniC-futures/.gitignore
vendored
15
TPfutures/MiniC-futures/.gitignore
vendored
@ -1,15 +0,0 @@
|
|||||||
/MiniCLexer.py
|
|
||||||
/MiniCParser.py
|
|
||||||
/MiniCVisitor.py
|
|
||||||
/MiniCListener.py
|
|
||||||
*.dot
|
|
||||||
*.dot.pdf
|
|
||||||
*.riscv
|
|
||||||
*-naive.s
|
|
||||||
*-gcc.s
|
|
||||||
*-all_in_mem.s
|
|
||||||
*-smart.s
|
|
||||||
*.cfut
|
|
||||||
*.o
|
|
||||||
/MiniC.interp
|
|
||||||
/MiniCLexer.interp
|
|
@ -1,14 +0,0 @@
|
|||||||
class MiniCRuntimeError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MiniCInternalError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MiniCUnsupportedError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MiniCTypeError(Exception):
|
|
||||||
pass
|
|
@ -1,56 +0,0 @@
|
|||||||
PACKAGE = MiniC
|
|
||||||
# Example: stop at the first failed test:
|
|
||||||
# make PYTEST_OPTS=-x tests
|
|
||||||
PYTEST_OPTS =
|
|
||||||
# Run the whole test infrastructure for a subset of test files e.g.
|
|
||||||
# make TEST_FILES='TP03/**/bad*.c' tests
|
|
||||||
ifdef TEST_FILES
|
|
||||||
export TEST_FILES
|
|
||||||
endif
|
|
||||||
|
|
||||||
PYTEST_BASE_OPTS=-vv -rs --failed-first --cov="$(PWD)" --cov-report=term --cov-report=html
|
|
||||||
|
|
||||||
ifndef ANTLR4
|
|
||||||
abort:
|
|
||||||
$(error variable ANTLR4 is not set)
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: antlr
|
|
||||||
|
|
||||||
.PHONY: antlr
|
|
||||||
antlr MiniCLexer.py MiniCParser.py: $(PACKAGE).g4
|
|
||||||
$(ANTLR4) $< -Dlanguage=Python3 -visitor
|
|
||||||
|
|
||||||
main-deps: MiniCLexer.py MiniCParser.py MiniCTypingVisitor.py MiniCPPListener.py
|
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
gcc -g -c -Wall -Wextra $< -o $@
|
|
||||||
|
|
||||||
$(TESTFILE:%.c=%.o): $(TESTFILE:%.c=%.cfut) $(HEADERS)
|
|
||||||
gcc -g -c -Iinclude -Wall -Wextra -x c $(TESTFILE:%.c=%.cfut) -o $(TESTFILE:%.c=%.o)
|
|
||||||
|
|
||||||
$(TESTFILE:%.c=%.out): $(TESTFILE:%.c=%.o) lib/futurelib.o
|
|
||||||
gcc -g $(TESTFILE:%.c=%.o) lib/futurelib.o -o $(TESTFILE:%.c=%.out) -lpthread
|
|
||||||
|
|
||||||
$(TESTFILE:%.c=%.cfut): main-deps
|
|
||||||
python3 MiniCC.py $(TESTFILE)
|
|
||||||
|
|
||||||
run: $(TESTFILE:%.c=%.out)
|
|
||||||
$(TESTFILE:%.c=%.out)
|
|
||||||
|
|
||||||
test: test_futures.py main-deps
|
|
||||||
python3 -m pytest $(PYTEST_BASE_OPTS) $(PYTEST_OPTS) ./test_futures.py
|
|
||||||
|
|
||||||
tar: clean
|
|
||||||
dir=$$(basename "$$PWD") && cd .. && \
|
|
||||||
tar cvfz "$$dir.tgz" --exclude="*.riscv" --exclude=".git" --exclude=".pytest_cache" \
|
|
||||||
--exclude="htmlcov" "$$dir"
|
|
||||||
@echo "Created ../$$(basename "$$PWD").tgz"
|
|
||||||
|
|
||||||
clean-tests:
|
|
||||||
cd tests && \
|
|
||||||
find . \( -iname "*.cfut" -or -iname "*.out" \) -print0 | xargs -0 rm -rf \;
|
|
||||||
|
|
||||||
clean: clean-tests
|
|
||||||
find . \( -iname "*~" -or -iname ".cache*" -or -iname "*.diff" -or -iname "log*.txt" -or -iname "__pycache__" -or -iname "*.tokens" -or -iname "*.interp" -or -iname "*.o" \) -print0 | xargs -0 rm -rf \;
|
|
||||||
rm -rf *~ $(PACKAGE)Parser.py $(PACKAGE)Lexer.py $(PACKAGE)Visitor.py $(PACKAGE)Listener.py .coverage .benchmarks
|
|
@ -1,164 +0,0 @@
|
|||||||
grammar MiniC;
|
|
||||||
|
|
||||||
prog: include* function* EOF #progRule;
|
|
||||||
|
|
||||||
//include statements reduced to string
|
|
||||||
include: INCLUDE STRING #includestat ;
|
|
||||||
|
|
||||||
function
|
|
||||||
: typee ID OPAR param_l? CPAR OBRACE vardecl_l block RETURN expr SCOL CBRACE #funcDef
|
|
||||||
| typee ID OPAR param_l? CPAR SCOL #funcDecl
|
|
||||||
;
|
|
||||||
|
|
||||||
vardecl_l: vardecl* #varDeclList;
|
|
||||||
|
|
||||||
vardecl: typee id_l SCOL #varDecl;
|
|
||||||
|
|
||||||
param: typee ID #paramDecl;
|
|
||||||
|
|
||||||
param_l
|
|
||||||
: param #paramListBase
|
|
||||||
| param COM param_l #paramList
|
|
||||||
;
|
|
||||||
|
|
||||||
id_l
|
|
||||||
: ID #idListBase
|
|
||||||
| ID COM id_l #idList
|
|
||||||
;
|
|
||||||
|
|
||||||
block: stat* #statList;
|
|
||||||
|
|
||||||
stat
|
|
||||||
: assignment SCOL
|
|
||||||
| if_stat
|
|
||||||
| while_stat
|
|
||||||
| print_stat
|
|
||||||
;
|
|
||||||
|
|
||||||
assignment: ID ASSIGN expr #assignStat;
|
|
||||||
|
|
||||||
if_stat: IF OPAR expr CPAR then_block=stat_block (ELSE else_block=stat_block)? #ifStat;
|
|
||||||
|
|
||||||
stat_block
|
|
||||||
: OBRACE block CBRACE
|
|
||||||
| stat
|
|
||||||
;
|
|
||||||
|
|
||||||
while_stat: WHILE OPAR expr CPAR body=stat_block #whileStat;
|
|
||||||
|
|
||||||
|
|
||||||
print_stat
|
|
||||||
: PRINTINT OPAR expr CPAR SCOL #printlnintStat
|
|
||||||
| PRINTFLOAT OPAR expr CPAR SCOL #printlnfloatStat
|
|
||||||
| PRINTBOOL OPAR expr CPAR SCOL #printlnboolStat
|
|
||||||
| PRINTSTRING OPAR expr CPAR SCOL #printstringStat
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_l
|
|
||||||
: expr #exprListBase
|
|
||||||
| expr COM expr_l #exprList
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
expr
|
|
||||||
: MINUS expr #unaryMinusExpr
|
|
||||||
| NOT expr #notExpr
|
|
||||||
| expr myop=(MULT|DIV|MOD) expr #multiplicativeExpr
|
|
||||||
| expr myop=(PLUS|MINUS) expr #additiveExpr
|
|
||||||
| expr myop=(GT|LT|GTEQ|LTEQ) expr #relationalExpr
|
|
||||||
| expr myop=(EQ|NEQ) expr #equalityExpr
|
|
||||||
| expr AND expr #andExpr
|
|
||||||
| expr OR expr #orExpr
|
|
||||||
| ID OPAR expr_l? CPAR #funcCall
|
|
||||||
| GET OPAR expr CPAR #getCall
|
|
||||||
| ASYNC OPAR ID COM expr_l? CPAR #asyncFuncCall
|
|
||||||
| atom #atomExpr
|
|
||||||
;
|
|
||||||
|
|
||||||
atom
|
|
||||||
: OPAR expr CPAR #parExpr
|
|
||||||
| INT #intAtom
|
|
||||||
| FLOAT #floatAtom
|
|
||||||
| (TRUE | FALSE) #booleanAtom
|
|
||||||
| ID #idAtom
|
|
||||||
| STRING #stringAtom
|
|
||||||
;
|
|
||||||
|
|
||||||
typee
|
|
||||||
: mytype=(INTTYPE|FLOATTYPE|BOOLTYPE|STRINGTYPE|FUTINTTYPE) #basicType
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
ASYNC : 'Async';
|
|
||||||
GET : 'Get';
|
|
||||||
OR : '||';
|
|
||||||
AND : '&&';
|
|
||||||
EQ : '==';
|
|
||||||
NEQ : '!=';
|
|
||||||
GT : '>';
|
|
||||||
LT : '<';
|
|
||||||
GTEQ : '>=';
|
|
||||||
LTEQ : '<=';
|
|
||||||
PLUS : '+';
|
|
||||||
MINUS : '-';
|
|
||||||
MULT : '*';
|
|
||||||
DIV : '/';
|
|
||||||
MOD : '%';
|
|
||||||
NOT : '!';
|
|
||||||
|
|
||||||
COL: ':';
|
|
||||||
SCOL : ';';
|
|
||||||
COM : ',';
|
|
||||||
ASSIGN : '=';
|
|
||||||
OPAR : '(';
|
|
||||||
CPAR : ')';
|
|
||||||
OBRACE : '{';
|
|
||||||
CBRACE : '}';
|
|
||||||
|
|
||||||
TRUE : 'true';
|
|
||||||
FALSE : 'false';
|
|
||||||
IF : 'if';
|
|
||||||
ELSE : 'else';
|
|
||||||
WHILE : 'while';
|
|
||||||
RETURN : 'return';
|
|
||||||
PRINTINT : 'println_int';
|
|
||||||
PRINTBOOL : 'println_bool';
|
|
||||||
PRINTSTRING : 'println_string';
|
|
||||||
PRINTFLOAT : 'println_float';
|
|
||||||
|
|
||||||
FUTINTTYPE: 'futint';
|
|
||||||
INTTYPE: 'int';
|
|
||||||
FLOATTYPE: 'float';
|
|
||||||
STRINGTYPE: 'string';
|
|
||||||
BOOLTYPE : 'bool';
|
|
||||||
INCLUDE : '#include';
|
|
||||||
|
|
||||||
ID
|
|
||||||
: [a-zA-Z_] [a-zA-Z_0-9]*
|
|
||||||
;
|
|
||||||
|
|
||||||
INT
|
|
||||||
: [0-9]+
|
|
||||||
;
|
|
||||||
|
|
||||||
FLOAT
|
|
||||||
: [0-9]+ '.' [0-9]*
|
|
||||||
| '.' [0-9]+
|
|
||||||
;
|
|
||||||
|
|
||||||
STRING
|
|
||||||
: '"' (~["\r\n] | '""')* '"'
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
COMMENT
|
|
||||||
// # is a comment in Mini-C, and used for #include in real C so that we ignore #include statements
|
|
||||||
// BUT now we want to keep includes => # removed
|
|
||||||
: '//' ~[\r\n]* -> skip
|
|
||||||
;
|
|
||||||
|
|
||||||
SPACE
|
|
||||||
// here is a little for code rewriting.
|
|
||||||
: [ \t\r\n] -> channel(HIDDEN)
|
|
||||||
;
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
|||||||
#! /usr/bin/env python3
|
|
||||||
"""
|
|
||||||
MiniC-futures Lab. Language Extension for MiniC with future primitives
|
|
||||||
Usage:
|
|
||||||
python3 Main.py <filename>
|
|
||||||
python3 Main.py --help
|
|
||||||
"""
|
|
||||||
import traceback
|
|
||||||
from MiniCLexer import MiniCLexer
|
|
||||||
from MiniCParser import MiniCParser
|
|
||||||
from MiniCTypingVisitor import MiniCTypingVisitor, MiniCTypeError
|
|
||||||
from MiniCPPListener import MiniCPPListener
|
|
||||||
from Errors import MiniCUnsupportedError, MiniCInternalError
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker
|
|
||||||
from antlr4.error.ErrorListener import ErrorListener
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
class CountErrorListener(ErrorListener):
|
|
||||||
"""Count number of errors.
|
|
||||||
|
|
||||||
Parser provides getNumberOfSyntaxErrors(), but the Lexer
|
|
||||||
apparently doesn't provide an easy way to know if an error occured
|
|
||||||
after the fact. Do the counting ourserves with a listener.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(CountErrorListener, self).__init__()
|
|
||||||
self.count = 0
|
|
||||||
|
|
||||||
def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
|
|
||||||
self.count += 1
|
|
||||||
|
|
||||||
|
|
||||||
def main(inputname,
|
|
||||||
typecheck=True, typecheck_only=False, stdout=False, output_name=None, debug=False):
|
|
||||||
(basename, rest) = os.path.splitext(inputname)
|
|
||||||
if not typecheck_only:
|
|
||||||
if stdout:
|
|
||||||
output_name = None
|
|
||||||
elif output_name is None:
|
|
||||||
output_name = basename + ".cfut"
|
|
||||||
|
|
||||||
input_s = FileStream(inputname, encoding='utf-8')
|
|
||||||
lexer = MiniCLexer(input_s)
|
|
||||||
counter = CountErrorListener()
|
|
||||||
lexer._listeners.append(counter)
|
|
||||||
stream = CommonTokenStream(lexer)
|
|
||||||
parser = MiniCParser(stream)
|
|
||||||
parser._listeners.append(counter)
|
|
||||||
tree = parser.prog()
|
|
||||||
if counter.count > 0:
|
|
||||||
exit(3) # Syntax or lexicography errors occurred, don't try to go further.
|
|
||||||
|
|
||||||
if typecheck:
|
|
||||||
typing_visitor = MiniCTypingVisitor()
|
|
||||||
try:
|
|
||||||
typing_visitor.visit(tree)
|
|
||||||
except MiniCTypeError as e:
|
|
||||||
print(e.args[0])
|
|
||||||
exit(2)
|
|
||||||
|
|
||||||
if typecheck_only:
|
|
||||||
if debug:
|
|
||||||
print("Not running code generation because of --disable-codegen.")
|
|
||||||
return
|
|
||||||
|
|
||||||
pw = ParseTreeWalker()
|
|
||||||
extractor = MiniCPPListener(stream)
|
|
||||||
pw.walk(extractor, tree)
|
|
||||||
with open(output_name, 'w') if output_name else sys.stdout as output:
|
|
||||||
extractor.printrw(output)
|
|
||||||
|
|
||||||
|
|
||||||
# command line management
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = argparse.ArgumentParser(description='Generate code for .c file')
|
|
||||||
|
|
||||||
parser.add_argument('filename', type=str,
|
|
||||||
help='Source file.')
|
|
||||||
parser.add_argument('--stdout', action='store_true',
|
|
||||||
help='Generate code to stdout')
|
|
||||||
parser.add_argument('--debug', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help='Emit verbose debug output')
|
|
||||||
parser.add_argument('--disable-typecheck', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help="Don't run the typechecker before generating code")
|
|
||||||
parser.add_argument('--disable-codegen', action='store_true',
|
|
||||||
default=False,
|
|
||||||
help="Run only the typechecker, don't try generating code.")
|
|
||||||
parser.add_argument('--output', type=str,
|
|
||||||
help='Generate code to outfile')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
try:
|
|
||||||
main(args.filename,
|
|
||||||
not args.disable_typecheck, args.disable_codegen,
|
|
||||||
args.stdout, args.output, args.debug,
|
|
||||||
)
|
|
||||||
except MiniCUnsupportedError as e:
|
|
||||||
print(e)
|
|
||||||
exit(5)
|
|
||||||
except (MiniCInternalError):
|
|
||||||
traceback.print_exc()
|
|
||||||
exit(4)
|
|
@ -1,27 +0,0 @@
|
|||||||
from MiniCListener import MiniCListener
|
|
||||||
|
|
||||||
from antlr4.TokenStreamRewriter import TokenStreamRewriter
|
|
||||||
|
|
||||||
|
|
||||||
class MiniCPPListener(MiniCListener):
|
|
||||||
def __init__(self, t):
|
|
||||||
self.rewriter = TokenStreamRewriter(tokens=t)
|
|
||||||
|
|
||||||
def printrw(self, output):
|
|
||||||
output.write(self.rewriter.getText('default', 0, 1000))
|
|
||||||
|
|
||||||
def enterProgRule(self, ctx):
|
|
||||||
"""Adds an include futurelib.h at the beginning of program."""
|
|
||||||
indexprog = ctx.start.tokenIndex
|
|
||||||
self.rewriter.insertBeforeIndex(indexprog, '#include \"futurelib.h\"\n')
|
|
||||||
|
|
||||||
def exitFuncDef(self, ctx):
|
|
||||||
"""Adds a call to freeAllFutures at the end of the body of the main function."""
|
|
||||||
(indexret, endret) = ctx.RETURN().getSourceInterval()
|
|
||||||
if ctx.ID().getText() == "main":
|
|
||||||
self.rewriter.insertBeforeIndex(indexret, 'freeAllFutures();\n')
|
|
||||||
|
|
||||||
def enterAsyncFuncCall(self, ctx):
|
|
||||||
"""Adds a & for getting a function pointer to the asynchronous called function."""
|
|
||||||
indexfunid = ctx.start.tokenIndex # token of async
|
|
||||||
self.rewriter.insertBeforeIndex(indexfunid + 2, '&')
|
|
@ -1,17 +0,0 @@
|
|||||||
# Visitor to *typecheck* MiniC files
|
|
||||||
from typing import List
|
|
||||||
from MiniCVisitor import MiniCVisitor
|
|
||||||
from MiniCParser import MiniCParser
|
|
||||||
from Lib.Errors import MiniCInternalError, MiniCTypeError
|
|
||||||
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
# NEW: ADD FutInteger
|
|
||||||
class BaseType(Enum):
|
|
||||||
Float, Integer, Boolean, String, FutInteger = range(5)
|
|
||||||
|
|
||||||
|
|
||||||
class MiniCTypingVisitor(MiniCVisitor):
|
|
||||||
# TODO Add your own typer here
|
|
||||||
pass
|
|
@ -1,25 +0,0 @@
|
|||||||
# MiniC Compiler
|
|
||||||
LAB8 (Futures) CAP 2022-23
|
|
||||||
|
|
||||||
# Authors
|
|
||||||
|
|
||||||
YOUR NAME HERE
|
|
||||||
|
|
||||||
# Contents
|
|
||||||
|
|
||||||
TODO:
|
|
||||||
- Explain any design choices you may have made.
|
|
||||||
- Did you implement a bonus?
|
|
||||||
|
|
||||||
# Howto
|
|
||||||
|
|
||||||
`make run TESTFILE=tests/provided/test_fut0.c`: launch the compiler, then GCC and run a single file.
|
|
||||||
|
|
||||||
# Test design
|
|
||||||
|
|
||||||
TODO: explain your tests.
|
|
||||||
|
|
||||||
# Known bugs
|
|
||||||
|
|
||||||
TODO: bugs you could not fix (if any) and limitations.
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
#include "stdio.h"
|
|
||||||
|
|
||||||
typedef char * string;
|
|
||||||
typedef int bool;
|
|
||||||
static const int true = 1;
|
|
||||||
static const int false = 0;
|
|
||||||
|
|
||||||
void print_int(int i) {printf("%i",i);}
|
|
||||||
void println_int(int i) {printf("%i\n",i);}
|
|
||||||
|
|
||||||
void print_string(string);
|
|
||||||
void println_string(string);
|
|
@ -1,34 +0,0 @@
|
|||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
typedef struct // a struct for storing a future to int
|
|
||||||
{
|
|
||||||
int Id;
|
|
||||||
int Value;
|
|
||||||
int resolved;
|
|
||||||
pthread_t tid;
|
|
||||||
} FutureInt;
|
|
||||||
|
|
||||||
typedef FutureInt* futint; // a typedef to deal with the future type of MiniCFut
|
|
||||||
|
|
||||||
FutureInt *fresh_future_malloc(); // allocates (malloc) a fresh future and initializes its field
|
|
||||||
|
|
||||||
void print_futureInt(FutureInt *fut); // for debug purposes: print a fut int status
|
|
||||||
|
|
||||||
void free_future(FutureInt *fut); // frees the pointer allocated by fresh_future
|
|
||||||
|
|
||||||
void resolve_future(FutureInt *fut, int val); // function called when an async call is finished
|
|
||||||
|
|
||||||
int Get(FutureInt *fut);
|
|
||||||
// called by the main program:
|
|
||||||
// checks that the future is resolved and
|
|
||||||
// returns the value stored in the future
|
|
||||||
|
|
||||||
FutureInt *Async(int (*fun)(int), int p);
|
|
||||||
// asynchronous function call:
|
|
||||||
// takes a function pointer as parameter and the fun call parameter as second parameter
|
|
||||||
// returns an unresolved future
|
|
||||||
// creates a thread to perform the asynchronous function call
|
|
||||||
|
|
||||||
void freeAllFutures();
|
|
||||||
// called at the end of the main block: waits for the resolution of all futures
|
|
||||||
// and frees all future pointers created by fresh_future
|
|
@ -1,77 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "../include/futurelib.h"
|
|
||||||
|
|
||||||
FutureInt *All[70];
|
|
||||||
// A table of future pointers to store all the futures created
|
|
||||||
// In a realistic scenario this would be a dynamic structure
|
|
||||||
int NbAll = 0;
|
|
||||||
// Number of futures created
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
// A structure for the argument of thread creation: function pointer and parameter
|
|
||||||
{
|
|
||||||
FutureInt *fut;
|
|
||||||
int (*fun)(int);
|
|
||||||
int param;
|
|
||||||
} arg_struct;
|
|
||||||
|
|
||||||
FutureInt *fresh_future_malloc()
|
|
||||||
{
|
|
||||||
// TODO Exercise 4.2
|
|
||||||
// Use malloc(sizeof(FutureInt)) and reference created futures
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_futureInt(FutureInt *f)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
// For debug purposes only
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_future(FutureInt *fut)
|
|
||||||
{
|
|
||||||
free(fut);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resolve_future(FutureInt *fut, int val)
|
|
||||||
{
|
|
||||||
// TODO Exercise 5.1
|
|
||||||
// Fill fut accordingly
|
|
||||||
}
|
|
||||||
|
|
||||||
int Get(FutureInt *fut)
|
|
||||||
{
|
|
||||||
// TODO Exercise 5.2
|
|
||||||
// Wait until future is resolved (do a sleep(1) between two checks)
|
|
||||||
// Do not forget to do a pthread_join(fut->tid, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *runTask(void *param)
|
|
||||||
{
|
|
||||||
// TODO Exercise 4.1
|
|
||||||
// function that is launched by the created thread: should call the function and
|
|
||||||
// deal with the future, using the function resolve_future
|
|
||||||
// param can be cast to (arg_struct *)
|
|
||||||
// this function should free the pointer param
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FutureInt *Async(int (*fun)(int), int p)
|
|
||||||
{
|
|
||||||
// TODO Exercise 4.3
|
|
||||||
// Main system call should be: int err = pthread_create(&fut->tid, NULL, &runTask, (args));
|
|
||||||
// Allocate a future and space for arguments: args = malloc(sizeof(arg_struct));
|
|
||||||
// Do not forget to populate args
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeAllFutures()
|
|
||||||
{
|
|
||||||
// TODO Exercises 4.4 & 5.3
|
|
||||||
// 1 - Wait for all futures (Get) to avoid dangling threads (Exercise 5.3)
|
|
||||||
// 2 - Call free_future for all futures (Exercise 4.4)
|
|
||||||
}
|
|
@ -1,193 +0,0 @@
|
|||||||
import collections
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
testinfo = collections.namedtuple(
|
|
||||||
'testinfo',
|
|
||||||
['exitcode', 'execcode', 'output', 'linkargs', 'skip_test_expected'])
|
|
||||||
default_testinfo = testinfo(
|
|
||||||
exitcode=0, execcode=0, output='', linkargs=[], skip_test_expected=False)
|
|
||||||
|
|
||||||
|
|
||||||
def cat(filename):
|
|
||||||
with open(filename, "rb") as f:
|
|
||||||
for line in f:
|
|
||||||
sys.stdout.buffer.write(line)
|
|
||||||
|
|
||||||
|
|
||||||
def env_bool_variable(name, globals):
|
|
||||||
if name not in globals:
|
|
||||||
globals[name] = False
|
|
||||||
if name in os.environ:
|
|
||||||
globals[name] = True
|
|
||||||
|
|
||||||
|
|
||||||
def env_str_variable(name, globals):
|
|
||||||
if name in os.environ:
|
|
||||||
globals[name] = os.environ[name]
|
|
||||||
|
|
||||||
|
|
||||||
class TestExpectPragmas(object):
|
|
||||||
"""Base class for tests that read the expected result as annotations
|
|
||||||
in test files.
|
|
||||||
|
|
||||||
get_expect(file) will parse the file, looking EXPECT and EXITCODE
|
|
||||||
pragmas.
|
|
||||||
|
|
||||||
run_command(command) is a wrapper around subprocess.check_output()
|
|
||||||
that extracts the output and exit code.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def get_expect(self, filename):
|
|
||||||
"""Parse "filename" looking for EXPECT and EXITCODE annotations.
|
|
||||||
|
|
||||||
Look for a line "EXPECTED" (possibly with whitespaces and
|
|
||||||
comments). Text after this "EXPECTED" line is the expected
|
|
||||||
output.
|
|
||||||
|
|
||||||
The file may also contain a line like "EXITCODE <n>" where <n>
|
|
||||||
is an integer, and is the expected exitcode of the command.
|
|
||||||
|
|
||||||
The result is cached to avoid re-parsing the file multiple
|
|
||||||
times.
|
|
||||||
"""
|
|
||||||
if filename not in self.__expect:
|
|
||||||
self.__expect[filename] = self._extract_expect(filename)
|
|
||||||
return self.__expect[filename]
|
|
||||||
|
|
||||||
def remove(self, file):
|
|
||||||
"""Like os.remove(), but ignore errors, e.g. don't complain if the
|
|
||||||
file doesn't exist.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
os.remove(file)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def run_command(self, cmd, scope="compile"):
|
|
||||||
"""Run the command cmd (given as [command, arg1, arg2, ...]), and
|
|
||||||
return testinfo(exitcode=..., output=...) containing the
|
|
||||||
exit code of the command it its standard output + standard error.
|
|
||||||
|
|
||||||
If scope="compile" (resp. "runtime"), then the exitcode (resp.
|
|
||||||
execcode) is set with the exit status of the command, and the
|
|
||||||
execcode (resp. exitcode) is set to 0.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
output = subprocess.check_output(cmd, timeout=60,
|
|
||||||
stderr=subprocess.STDOUT)
|
|
||||||
status = 0
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
output = e.output
|
|
||||||
status = e.returncode
|
|
||||||
if scope == "runtime":
|
|
||||||
return default_testinfo._replace(execcode=status,
|
|
||||||
output=output.decode())
|
|
||||||
else:
|
|
||||||
return default_testinfo._replace(exitcode=status,
|
|
||||||
output=output.decode())
|
|
||||||
|
|
||||||
def skip_if_partial_match(self, actual, expect, ignore_error_message):
|
|
||||||
if not ignore_error_message:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# TODO: Deal with undefined behavior here?
|
|
||||||
|
|
||||||
if expect.exitcode != actual.exitcode:
|
|
||||||
# Not the same exit code => something's wrong anyway
|
|
||||||
return False
|
|
||||||
|
|
||||||
if actual.exitcode == 3:
|
|
||||||
# There's a syntax error in both expected and actual,
|
|
||||||
# but the actual error may slightly differ if we don't
|
|
||||||
# have the exact same .g4.
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Let the test pass with 'return True' if appropriate.
|
|
||||||
# Otherwise, continue to the full assertion for a
|
|
||||||
# complete diagnostic.
|
|
||||||
if actual.exitcode != 0 and expect.exitcode == actual.exitcode:
|
|
||||||
if expect.output == '':
|
|
||||||
# No output expected, but we know there must be an
|
|
||||||
# error. If there was a particular error message
|
|
||||||
# expected, we'd have written it in the output,
|
|
||||||
# hence just ignore the actual message.
|
|
||||||
return True
|
|
||||||
# Ignore difference in error message except in the
|
|
||||||
# line number (ignore the column too, it may
|
|
||||||
# slightly vary, eg. in "foo" / 4, the error may
|
|
||||||
# be considered on "foo" or on /):
|
|
||||||
if re.match(r'^In function [^ :]*: Line [0-9]* col [0-9]*:',
|
|
||||||
actual.output):
|
|
||||||
out_loc = re.sub(r' col [0-9]*:.*$', '', actual.output)
|
|
||||||
exp_loc = re.sub(r' col [0-9]*:.*$', '', expect.output)
|
|
||||||
if out_loc == exp_loc:
|
|
||||||
return True
|
|
||||||
if any(x.output and
|
|
||||||
(x.output.endswith('has no value yet!' + os.linesep)
|
|
||||||
or x.output.endswith(' by 0' + os.linesep))
|
|
||||||
for x in (actual, expect)):
|
|
||||||
# Ignore the error message when our compiler
|
|
||||||
# raises this error (either in actual or expect,
|
|
||||||
# depending on what we're testing).
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
__expect = {}
|
|
||||||
|
|
||||||
def _extract_expect(self, file):
|
|
||||||
exitcode = 0
|
|
||||||
execcode = 0
|
|
||||||
linkargs = []
|
|
||||||
inside_expected = False
|
|
||||||
skip_test_expected = False
|
|
||||||
expected_lines = []
|
|
||||||
expected_present = False
|
|
||||||
with open(file, encoding="utf-8") as f:
|
|
||||||
for line in f.readlines():
|
|
||||||
# Ignore non-comments
|
|
||||||
if not re.match(r'\s*//', line):
|
|
||||||
continue
|
|
||||||
# Cleanup comment start and whitespaces
|
|
||||||
line = re.sub(r'\s*//\s*', '', line)
|
|
||||||
line = re.sub(r'\s*$', '', line)
|
|
||||||
|
|
||||||
if line == 'END EXPECTED':
|
|
||||||
inside_expected = False
|
|
||||||
elif line.startswith('EXITCODE'):
|
|
||||||
words = line.split(' ')
|
|
||||||
assert len(words) == 2
|
|
||||||
exitcode = int(words[1])
|
|
||||||
elif line.startswith('EXECCODE'):
|
|
||||||
words = line.split(' ')
|
|
||||||
assert len(words) == 2
|
|
||||||
execcode = int(words[1])
|
|
||||||
elif line.startswith('LINKARGS'):
|
|
||||||
words = line.split(' ')
|
|
||||||
assert len(words) >= 2
|
|
||||||
linkargs += [w.replace("$dir", os.path.dirname(file))
|
|
||||||
for w in words[1:]]
|
|
||||||
elif line == 'EXPECTED':
|
|
||||||
inside_expected = True
|
|
||||||
expected_present = True
|
|
||||||
elif line == 'SKIP TEST EXPECTED':
|
|
||||||
skip_test_expected = True
|
|
||||||
elif inside_expected:
|
|
||||||
expected_lines.append(line)
|
|
||||||
|
|
||||||
if not expected_present:
|
|
||||||
pytest.fail("Missing EXPECTED directive in test file")
|
|
||||||
|
|
||||||
if expected_lines == []:
|
|
||||||
output = ''
|
|
||||||
else:
|
|
||||||
output = os.linesep.join(expected_lines) + os.linesep
|
|
||||||
|
|
||||||
return testinfo(exitcode=exitcode, execcode=execcode,
|
|
||||||
output=output, linkargs=linkargs,
|
|
||||||
skip_test_expected=skip_test_expected)
|
|
@ -1,105 +0,0 @@
|
|||||||
#! /usr/bin/env python3
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import pytest
|
|
||||||
import glob
|
|
||||||
import subprocess
|
|
||||||
import re
|
|
||||||
from test_expect_pragma import (
|
|
||||||
TestExpectPragmas, cat, testinfo,
|
|
||||||
env_bool_variable, env_str_variable
|
|
||||||
)
|
|
||||||
|
|
||||||
"""
|
|
||||||
Usage:
|
|
||||||
python3 test_futur.py
|
|
||||||
(or make test)
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
CAP, 2020
|
|
||||||
Unit test infrastructure for testing futures:
|
|
||||||
1) compare the actual output to the expected one (in comments)
|
|
||||||
2) compare the actual output to the one obtained by simulation
|
|
||||||
"""
|
|
||||||
|
|
||||||
DISABLE_TYPECHECK = False
|
|
||||||
TYPECHECK_ONLY = False
|
|
||||||
|
|
||||||
HERE = os.path.dirname(os.path.realpath(__file__))
|
|
||||||
if HERE == os.path.realpath('.'):
|
|
||||||
HERE = '.'
|
|
||||||
TEST_DIR = HERE
|
|
||||||
IMPLEM_DIR = HERE
|
|
||||||
MINIC_FUT = os.path.join(IMPLEM_DIR, 'MiniCC.py')
|
|
||||||
|
|
||||||
ALL_FILES = glob.glob(os.path.join(TEST_DIR, 'tests/**/[a-zA-Z]*.c'),
|
|
||||||
recursive=True)
|
|
||||||
|
|
||||||
GCC = 'gcc'
|
|
||||||
|
|
||||||
if 'TEST_FILES' in os.environ:
|
|
||||||
ALL_FILES = glob.glob(os.environ['TEST_FILES'], recursive=True)
|
|
||||||
|
|
||||||
|
|
||||||
class TestFuture(TestExpectPragmas):
|
|
||||||
|
|
||||||
# Not in test_expect_pragma to get assertion rewritting
|
|
||||||
def assert_equal(self, actual, expected):
|
|
||||||
if TYPECHECK_ONLY and expected.exitcode == 0:
|
|
||||||
# Compiler does not fail => no output expected
|
|
||||||
assert actual.output == "", \
|
|
||||||
("Compiler unexpectedly generated some"
|
|
||||||
"output with --disable-codegen")
|
|
||||||
assert actual.exitcode == 0, \
|
|
||||||
"Compiler unexpectedly failed with --disable-codegen"
|
|
||||||
return
|
|
||||||
if DISABLE_TYPECHECK and expected.exitcode != 0:
|
|
||||||
# Test should fail at typecheck, and we don't do
|
|
||||||
# typechecking => nothing to check.
|
|
||||||
pytest.skip("Test that doesn't typecheck with --disable-typecheck")
|
|
||||||
if expected.output is not None and actual.output is not None:
|
|
||||||
assert actual.output == expected.output, \
|
|
||||||
"Output of the program is incorrect."
|
|
||||||
assert actual.exitcode == expected.exitcode, \
|
|
||||||
"Exit code of the compiler is incorrect"
|
|
||||||
assert actual.execcode == expected.execcode, \
|
|
||||||
"Exit code of the execution is incorrect"
|
|
||||||
|
|
||||||
def c2c(self, file):
|
|
||||||
return self.run_command(['python3', MINIC_FUT, file])
|
|
||||||
|
|
||||||
def compile_with_gcc(self, file, output_name):
|
|
||||||
print("Compiling with GCC...")
|
|
||||||
result = self.run_command(
|
|
||||||
[GCC, '-Iinclude', '-Ilib', '-x', 'c', file, "lib/futurelib.c",
|
|
||||||
'--output=' + output_name, '-lpthread'])
|
|
||||||
print(result.output)
|
|
||||||
print("Compiling with GCC... DONE")
|
|
||||||
return result
|
|
||||||
|
|
||||||
def compile_and_run(self, file):
|
|
||||||
basename, _ = os.path.splitext(file)
|
|
||||||
rw_name = basename + '.cfut'
|
|
||||||
exec_name = basename + '.out'
|
|
||||||
print("File: " + rw_name)
|
|
||||||
resgcc = self.compile_with_gcc(rw_name, exec_name)
|
|
||||||
if resgcc.exitcode != 0:
|
|
||||||
return resgcc._replace(exitcode=1, output=None)
|
|
||||||
res2 = self.run_command(exec_name, scope="runtime")
|
|
||||||
return res2
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('filename', ALL_FILES)
|
|
||||||
def test_future(self, filename):
|
|
||||||
expect = self.get_expect(filename)
|
|
||||||
c2csuccess = self.c2c(filename)
|
|
||||||
if c2csuccess.exitcode == 0:
|
|
||||||
actual = self.compile_and_run(filename)
|
|
||||||
else:
|
|
||||||
actual = c2csuccess
|
|
||||||
self.assert_equal(actual, expect)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
pytest.main(sys.argv)
|
|
@ -1,38 +0,0 @@
|
|||||||
#include "compat.h"
|
|
||||||
|
|
||||||
// Call future
|
|
||||||
int slow(int x)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
i=0;
|
|
||||||
while (i<1000) { i=i+1 ; x=2*i+x;}
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int summ(int x)
|
|
||||||
{
|
|
||||||
int ret,i;
|
|
||||||
if (x == 1)
|
|
||||||
ret=1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = x + summ(x - 1);
|
|
||||||
i=0;
|
|
||||||
while (i<100) { i=i+1 ; x=slow(2);}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int val;
|
|
||||||
|
|
||||||
val=Async(summ,1);
|
|
||||||
println_int(val);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXITCODE 2
|
|
||||||
// EXPECTED
|
|
||||||
// In function main: Line 29 col 4: type mismatch for val: integer and futinteger
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
#include "compat.h"
|
|
||||||
|
|
||||||
// Call future
|
|
||||||
|
|
||||||
int functi(int x){
|
|
||||||
int y;
|
|
||||||
y=x;
|
|
||||||
y = 42;
|
|
||||||
println_int(0);
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
futint fval;
|
|
||||||
fval = Async(functi,123);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 0
|
|
@ -1,22 +0,0 @@
|
|||||||
#include "compat.h"
|
|
||||||
|
|
||||||
// Call future
|
|
||||||
|
|
||||||
int functi(int x){
|
|
||||||
int y;
|
|
||||||
y=x;
|
|
||||||
y = 42;
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
futint fval;
|
|
||||||
int val;
|
|
||||||
fval = Async(functi,123);
|
|
||||||
val = Get(fval);
|
|
||||||
println_int(val);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 42
|
|
@ -1,41 +0,0 @@
|
|||||||
#include "compat.h"
|
|
||||||
|
|
||||||
// Call future
|
|
||||||
|
|
||||||
int summ(int x)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
if (x == 1)
|
|
||||||
ret=1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret=x + summ(x - 1);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int useFuture(futint f)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
x=Get(f);
|
|
||||||
return x+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int val,x;
|
|
||||||
futint f,g;
|
|
||||||
|
|
||||||
f=Async(summ,15);
|
|
||||||
g=Async(summ,16);
|
|
||||||
|
|
||||||
val=Get(f)+Get(g)+useFuture(g);
|
|
||||||
println_int(val);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 393
|
|
@ -1,56 +0,0 @@
|
|||||||
#include "compat.h"
|
|
||||||
|
|
||||||
// Call future
|
|
||||||
|
|
||||||
int slow(int x)
|
|
||||||
{
|
|
||||||
int i,t;
|
|
||||||
i=0;
|
|
||||||
t=0;
|
|
||||||
while (i<x*1000) { i=i+1 ; t=t+2*i+x;}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
int summ(int x)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
if (x == 1)
|
|
||||||
ret=1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = x + summ(x - 1);
|
|
||||||
i=0;
|
|
||||||
while (i<100) { i=i+1 ; x=slow(20);}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int summandprint(int x)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
ret=summ(x);
|
|
||||||
println_int(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int val;
|
|
||||||
futint f,g;
|
|
||||||
|
|
||||||
f=Async(summandprint,500);
|
|
||||||
g=Async(summandprint,2);
|
|
||||||
|
|
||||||
val=Get(f)+Get(g);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// EXPECTED
|
|
||||||
// 3
|
|
||||||
// 125250
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
dm_cap.pdf
BIN
dm_cap.pdf
Binary file not shown.
@ -45,13 +45,8 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,406 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html class="writer-html5" lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Lib.CFG — MiniC documentation</title>
|
|
||||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
||||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
|
||||||
<script src="../../_static/doctools.js"></script>
|
|
||||||
<script src="../../_static/sphinx_highlight.js"></script>
|
|
||||||
<script src="../../_static/js/theme.js"></script>
|
|
||||||
<link rel="index" title="Index" href="../../genindex.html" />
|
|
||||||
<link rel="search" title="Search" href="../../search.html" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="wy-body-for-nav">
|
|
||||||
<div class="wy-grid-for-nav">
|
|
||||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
||||||
<div class="wy-side-scroll">
|
|
||||||
<div class="wy-side-nav-search" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="../../index.html" class="icon icon-home">
|
|
||||||
MiniC
|
|
||||||
</a>
|
|
||||||
<div role="search">
|
|
||||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
|
||||||
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
|
||||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
|
||||||
<ul>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
|
||||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
||||||
<a href="../../index.html">MiniC</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="wy-nav-content">
|
|
||||||
<div class="rst-content">
|
|
||||||
<div role="navigation" aria-label="Page navigation">
|
|
||||||
<ul class="wy-breadcrumbs">
|
|
||||||
<li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="../index.html">Module code</a></li>
|
|
||||||
<li class="breadcrumb-item active">Lib.CFG</li>
|
|
||||||
<li class="wy-breadcrumbs-aside">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
<div itemprop="articleBody">
|
|
||||||
|
|
||||||
<h1>Source code for Lib.CFG</h1><div class="highlight"><pre>
|
|
||||||
<span></span><span class="sd">"""</span>
|
|
||||||
<span class="sd">Classes for a RiscV CFG: :py:class:`CFG` for the CFG itself,</span>
|
|
||||||
<span class="sd">and :py:class:`Block` for its basic blocks.</span>
|
|
||||||
<span class="sd">"""</span>
|
|
||||||
|
|
||||||
<span class="kn">from</span> <span class="nn">graphviz</span> <span class="kn">import</span> <span class="n">Digraph</span> <span class="c1"># for dot output</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">cast</span><span class="p">,</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Set</span><span class="p">,</span> <span class="n">Iterator</span>
|
|
||||||
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Errors</span> <span class="kn">import</span> <span class="n">MiniCInternalError</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Operands</span> <span class="kn">import</span> <span class="p">(</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">,</span> <span class="n">Function</span><span class="p">,</span> <span class="n">A0</span><span class="p">)</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Statement</span> <span class="kn">import</span> <span class="p">(</span>
|
|
||||||
<span class="n">Statement</span><span class="p">,</span> <span class="n">Instru3A</span><span class="p">,</span> <span class="n">Label</span><span class="p">,</span>
|
|
||||||
<span class="n">AbsoluteJump</span><span class="p">,</span> <span class="n">ConditionalJump</span><span class="p">,</span> <span class="n">Comment</span>
|
|
||||||
<span class="p">)</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Terminator</span> <span class="kn">import</span> <span class="p">(</span>
|
|
||||||
<span class="n">Terminator</span><span class="p">,</span> <span class="n">BranchingTerminator</span><span class="p">,</span> <span class="n">Return</span><span class="p">)</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.FunctionData</span> <span class="kn">import</span> <span class="p">(</span><span class="n">FunctionData</span><span class="p">,</span> <span class="n">_iter_statements</span><span class="p">,</span> <span class="n">_print_code</span><span class="p">)</span>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="n">BlockInstr</span> <span class="o">=</span> <span class="n">Instru3A</span> <span class="o">|</span> <span class="n">Comment</span>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block">[docs]</a><span class="k">class</span> <span class="nc">Block</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> A basic block of a :py:class:`CFG` is made of three main parts:</span>
|
|
||||||
|
|
||||||
<span class="sd"> - a start :py:class:`label <Lib.Statement.Label>` that uniquely identifies the block in the CFG</span>
|
|
||||||
<span class="sd"> - the main body of the block, a list of instructions</span>
|
|
||||||
<span class="sd"> (excluding labels, jumps and branching instructions)</span>
|
|
||||||
<span class="sd"> - a :py:class:`terminator <Lib.Terminator.Terminator>`</span>
|
|
||||||
<span class="sd"> that represents the final jump or branching instruction of the block,</span>
|
|
||||||
<span class="sd"> and points to the successors of the block.</span>
|
|
||||||
<span class="sd"> See the documentation for :py:class:`Lib.Terminator.Terminator` for further explanations.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
|
|
||||||
<span class="n">_terminator</span><span class="p">:</span> <span class="n">Terminator</span>
|
|
||||||
<span class="n">_label</span><span class="p">:</span> <span class="n">Label</span>
|
|
||||||
<span class="n">_phis</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="n">_instructions</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">BlockInstr</span><span class="p">]</span>
|
|
||||||
<span class="n">_in</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="s1">'Block'</span><span class="p">]</span>
|
|
||||||
<span class="n">_gen</span><span class="p">:</span> <span class="n">Set</span>
|
|
||||||
<span class="n">_kill</span><span class="p">:</span> <span class="n">Set</span>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="n">Label</span><span class="p">,</span> <span class="n">insts</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">BlockInstr</span><span class="p">],</span> <span class="n">terminator</span><span class="p">:</span> <span class="n">Terminator</span><span class="p">):</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_label</span> <span class="o">=</span> <span class="n">label</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_instructions</span> <span class="o">=</span> <span class="n">insts</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_in</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_phis</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_terminator</span> <span class="o">=</span> <span class="n">terminator</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_gen</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_kill</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
||||||
<span class="n">instr</span> <span class="o">=</span> <span class="p">[</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_instructions</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">Comment</span><span class="p">)]</span>
|
|
||||||
<span class="n">instr_str</span> <span class="o">=</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">instr</span><span class="p">))</span>
|
|
||||||
<span class="n">s</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">:</span><span class="se">\n\n</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_label</span><span class="p">,</span> <span class="n">instr_str</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">s</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.to_dot"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.to_dot">[docs]</a> <span class="k">def</span> <span class="nf">to_dot</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Outputs all statements of the block as a string."""</span>
|
|
||||||
<span class="c1"># dot is weird: lines ending with \l instead of \n are left-aligned.</span>
|
|
||||||
<span class="n">NEWLINE</span> <span class="o">=</span> <span class="s1">'</span><span class="se">\\</span><span class="s1">l '</span>
|
|
||||||
<span class="n">instr</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="n">instr</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_phis</span>
|
|
||||||
<span class="n">instr</span> <span class="o">+=</span> <span class="p">[</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_instructions</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">Comment</span><span class="p">)]</span>
|
|
||||||
<span class="n">instr</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>
|
|
||||||
<span class="n">instr_str</span> <span class="o">=</span> <span class="n">NEWLINE</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">instr</span><span class="p">))</span>
|
|
||||||
<span class="n">s</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">:</span><span class="si">{}{}</span><span class="se">\\</span><span class="s1">l'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_label</span><span class="p">,</span> <span class="n">NEWLINE</span><span class="p">,</span> <span class="n">instr_str</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">s</span></div>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
||||||
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_label</span><span class="p">)</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.get_body"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.get_body">[docs]</a> <span class="k">def</span> <span class="nf">get_body</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">BlockInstr</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the statements in the body of the block (no phi-node nor the terminator)."""</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_instructions</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.get_all_statements"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.get_all_statements">[docs]</a> <span class="k">def</span> <span class="nf">get_all_statements</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="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Return all statements of the block</span>
|
|
||||||
<span class="sd"> (including phi-nodes and the terminator, but not the label of the block).</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_phis</span> <span class="o">+</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_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="w"> </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="w"> </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>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.get_in"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.get_in">[docs]</a> <span class="k">def</span> <span class="nf">get_in</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="s1">'Block'</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the list of blocks with an edge to the considered block."""</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_in</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.get_terminator"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.get_terminator">[docs]</a> <span class="k">def</span> <span class="nf">get_terminator</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Terminator</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the terminator of the block."""</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_terminator</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.set_terminator"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.set_terminator">[docs]</a> <span class="k">def</span> <span class="nf">set_terminator</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">term</span><span class="p">:</span> <span class="n">Terminator</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Set the terminator of the block."""</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_terminator</span> <span class="o">=</span> <span class="n">term</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.get_phis"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.get_phis">[docs]</a> <span class="k">def</span> <span class="nf">get_phis</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="w"> </span><span class="sd">"""Return the list of all φ instructions of the block."""</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_phis</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.add_phi"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.add_phi">[docs]</a> <span class="k">def</span> <span class="nf">add_phi</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">phi</span><span class="p">:</span> <span class="n">Statement</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Add a φ instruction to the block."""</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_phis</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">phi</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.set_phis"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.set_phis">[docs]</a> <span class="k">def</span> <span class="nf">set_phis</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">phis</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="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Replace the φ instructions in the block by the given list `phis`."""</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_phis</span> <span class="o">=</span> <span class="n">phis</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.remove_all_phis"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.remove_all_phis">[docs]</a> <span class="k">def</span> <span class="nf">remove_all_phis</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Remove all φ instructions in the block."""</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_phis</span> <span class="o">=</span> <span class="p">[]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.iter_statements"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.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="w"> </span><span class="sd">"""Iterate over instructions.</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"> Assume there is no phi-node.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">assert</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_phis</span> <span class="o">==</span> <span class="p">[])</span>
|
|
||||||
<span class="n">new_statements</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">_instructions</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
|
|
||||||
<span class="n">end_statements</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_terminator</span><span class="p">())</span>
|
|
||||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">end_statements</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">1</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">end_statements</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">Terminator</span><span class="p">):</span>
|
|
||||||
<span class="n">new_terminator</span> <span class="o">=</span> <span class="n">end_statements</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_instructions</span> <span class="o">=</span> <span class="n">new_statements</span> <span class="o">+</span> <span class="n">end_statements</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">set_terminator</span><span class="p">(</span><span class="n">new_terminator</span><span class="p">)</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="k">raise</span> <span class="n">MiniCInternalError</span><span class="p">(</span>
|
|
||||||
<span class="s2">"Block.iter_statements: Invalid replacement for terminator </span><span class="si">{}</span><span class="s2">:</span><span class="se">\n</span><span class="s2"> </span><span class="si">{}</span><span class="s2">"</span>
|
|
||||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_terminator</span><span class="p">(),</span> <span class="n">end_statements</span><span class="p">))</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Block.add_instruction"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.Block.add_instruction">[docs]</a> <span class="k">def</span> <span class="nf">add_instruction</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instr</span><span class="p">:</span> <span class="n">BlockInstr</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Add an instruction to the body of the block."""</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_instructions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">instr</span><span class="p">)</span></div></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG">[docs]</a><span class="k">class</span> <span class="nc">CFG</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> A complete control-flow graph representing a function.</span>
|
|
||||||
<span class="sd"> This class is mainly made of a list of basic :py:class:`Block`,</span>
|
|
||||||
<span class="sd"> a label indicating the :py:meth:`entry point of the function <get_start>`,</span>
|
|
||||||
<span class="sd"> and an :py:meth:`exit label <get_end>`.</span>
|
|
||||||
|
|
||||||
<span class="sd"> As with linear code, metadata about the function can be found</span>
|
|
||||||
<span class="sd"> in the :py:attr:`fdata` member variable.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
|
|
||||||
<span class="n">_start</span><span class="p">:</span> <span class="n">Label</span>
|
|
||||||
<span class="n">_end</span><span class="p">:</span> <span class="n">Label</span>
|
|
||||||
<span class="n">_blocks</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Label</span><span class="p">,</span> <span class="n">Block</span><span class="p">]</span>
|
|
||||||
|
|
||||||
<span class="c1">#: Metadata about the function represented by this CFG</span>
|
|
||||||
<span class="n">fdata</span><span class="p">:</span> <span class="n">FunctionData</span>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fdata</span><span class="p">:</span> <span class="n">FunctionData</span><span class="p">):</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span> <span class="o">=</span> <span class="p">{}</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">fdata</span> <span class="o">=</span> <span class="n">fdata</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_init_blks</span><span class="p">()</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_end</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fdata</span><span class="o">.</span><span class="n">fresh_label</span><span class="p">(</span><span class="s2">"end"</span><span class="p">)</span>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="nf">_init_blks</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Add a block for division by 0."""</span>
|
|
||||||
<span class="c1"># Label for the address of the error message</span>
|
|
||||||
<span class="c1"># This address is added by print_code</span>
|
|
||||||
<span class="n">label_div_by_zero_msg</span> <span class="o">=</span> <span class="n">Label</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fdata</span><span class="o">.</span><span class="n">_label_div_by_zero</span><span class="o">.</span><span class="n">name</span> <span class="o">+</span> <span class="s2">"_msg"</span><span class="p">)</span>
|
|
||||||
<span class="n">blk</span> <span class="o">=</span> <span class="n">Block</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fdata</span><span class="o">.</span><span class="n">_label_div_by_zero</span><span class="p">,</span> <span class="p">[</span>
|
|
||||||
<span class="n">Instru3A</span><span class="p">(</span><span class="s2">"la"</span><span class="p">,</span> <span class="n">A0</span><span class="p">,</span> <span class="n">label_div_by_zero_msg</span><span class="p">),</span>
|
|
||||||
<span class="n">Instru3A</span><span class="p">(</span><span class="s2">"call"</span><span class="p">,</span> <span class="n">Function</span><span class="p">(</span><span class="s2">"println_string"</span><span class="p">)),</span>
|
|
||||||
<span class="n">Instru3A</span><span class="p">(</span><span class="s2">"li"</span><span class="p">,</span> <span class="n">A0</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">(</span><span class="mi">1</span><span class="p">)),</span>
|
|
||||||
<span class="n">Instru3A</span><span class="p">(</span><span class="s2">"call"</span><span class="p">,</span> <span class="n">Function</span><span class="p">(</span><span class="s2">"exit"</span><span class="p">)),</span>
|
|
||||||
<span class="p">],</span> <span class="n">terminator</span><span class="o">=</span><span class="n">Return</span><span class="p">())</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">add_block</span><span class="p">(</span><span class="n">blk</span><span class="p">)</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.get_start"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.get_start">[docs]</a> <span class="k">def</span> <span class="nf">get_start</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="w"> </span><span class="sd">"""Return the entry label of the CFG."""</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_start</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.set_start"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.set_start">[docs]</a> <span class="k">def</span> <span class="nf">set_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">start</span><span class="p">:</span> <span class="n">Label</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Set the entry label of the CFG."""</span>
|
|
||||||
<span class="k">assert</span> <span class="p">(</span><span class="n">start</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span><span class="p">)</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_start</span> <span class="o">=</span> <span class="n">start</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.get_end"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.get_end">[docs]</a> <span class="k">def</span> <span class="nf">get_end</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="w"> </span><span class="sd">"""Return the exit label of the CFG."""</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_end</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.add_block"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.add_block">[docs]</a> <span class="k">def</span> <span class="nf">add_block</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">blk</span><span class="p">:</span> <span class="n">Block</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Add a new block to the CFG."""</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span><span class="p">[</span><span class="n">blk</span><span class="o">.</span><span class="n">_label</span><span class="p">]</span> <span class="o">=</span> <span class="n">blk</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.get_block"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.get_block">[docs]</a> <span class="k">def</span> <span class="nf">get_block</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="n">Label</span><span class="p">)</span> <span class="o">-></span> <span class="n">Block</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the block with label `name`."""</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span><span class="p">[</span><span class="n">name</span><span class="p">]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.get_blocks"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.get_blocks">[docs]</a> <span class="k">def</span> <span class="nf">get_blocks</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">Block</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return all the blocks."""</span>
|
|
||||||
<span class="k">return</span> <span class="p">[</span><span class="n">b</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span><span class="o">.</span><span class="n">values</span><span class="p">()]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.get_entries"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.get_entries">[docs]</a> <span class="k">def</span> <span class="nf">get_entries</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">Block</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return all the blocks with no predecessors."""</span>
|
|
||||||
<span class="k">return</span> <span class="p">[</span><span class="n">b</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span><span class="o">.</span><span class="n">values</span><span class="p">()</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">b</span><span class="o">.</span><span class="n">get_in</span><span class="p">()]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.add_edge"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.add_edge">[docs]</a> <span class="k">def</span> <span class="nf">add_edge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">src</span><span class="p">:</span> <span class="n">Block</span><span class="p">,</span> <span class="n">dest</span><span class="p">:</span> <span class="n">Block</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Add the edge src -> dest in the control flow graph."""</span>
|
|
||||||
<span class="n">dest</span><span class="o">.</span><span class="n">get_in</span><span class="p">()</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">src</span><span class="p">)</span></div>
|
|
||||||
<span class="c1"># assert (dest.get_label() in src.get_terminator().targets())</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.remove_edge"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.remove_edge">[docs]</a> <span class="k">def</span> <span class="nf">remove_edge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">src</span><span class="p">:</span> <span class="n">Block</span><span class="p">,</span> <span class="n">dest</span><span class="p">:</span> <span class="n">Block</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Remove the edge src -> dest in the control flow graph."""</span>
|
|
||||||
<span class="n">dest</span><span class="o">.</span><span class="n">get_in</span><span class="p">()</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">src</span><span class="p">)</span></div>
|
|
||||||
<span class="c1"># assert (dest.get_label() not in src.get_terminator().targets())</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.out_blocks"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.out_blocks">[docs]</a> <span class="k">def</span> <span class="nf">out_blocks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">block</span><span class="p">:</span> <span class="n">Block</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Block</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Return the list of blocks in the CFG targeted by</span>
|
|
||||||
<span class="sd"> the Terminator of Block block.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">return</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">get_block</span><span class="p">(</span><span class="n">dest</span><span class="p">)</span> <span class="k">for</span> <span class="n">dest</span> <span class="ow">in</span> <span class="n">block</span><span class="o">.</span><span class="n">get_terminator</span><span class="p">()</span><span class="o">.</span><span class="n">targets</span><span class="p">()]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.gather_defs"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.gather_defs">[docs]</a> <span class="k">def</span> <span class="nf">gather_defs</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Dict</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="n">Block</span><span class="p">]]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Return a dictionary associating variables to all the blocks</span>
|
|
||||||
<span class="sd"> containing one of their definitions.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">defs</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
|
||||||
<span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_blocks</span><span class="p">():</span>
|
|
||||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">b</span><span class="o">.</span><span class="n">get_all_statements</span><span class="p">():</span>
|
|
||||||
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">i</span><span class="o">.</span><span class="n">defined</span><span class="p">():</span>
|
|
||||||
<span class="k">if</span> <span class="n">v</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">defs</span><span class="p">:</span>
|
|
||||||
<span class="n">defs</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="n">b</span><span class="p">}</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="n">defs</span><span class="p">[</span><span class="n">v</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">defs</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.iter_statements"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.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="w"> </span><span class="sd">"""Apply f to all instructions in all the blocks."""</span>
|
|
||||||
<span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_blocks</span><span class="p">():</span>
|
|
||||||
<span class="n">b</span><span class="o">.</span><span class="n">iter_statements</span><span class="p">(</span><span class="n">f</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.linearize_naive"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.linearize_naive">[docs]</a> <span class="k">def</span> <span class="nf">linearize_naive</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Iterator</span><span class="p">[</span><span class="n">Statement</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Linearize the given control flow graph as a list of instructions.</span>
|
|
||||||
<span class="sd"> Naive procedure that adds jumps everywhere.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">for</span> <span class="n">label</span><span class="p">,</span> <span class="n">block</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
||||||
<span class="k">yield</span> <span class="n">label</span>
|
|
||||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">block</span><span class="o">.</span><span class="n">_instructions</span><span class="p">:</span>
|
|
||||||
<span class="k">yield</span> <span class="n">i</span>
|
|
||||||
<span class="k">match</span> <span class="n">block</span><span class="o">.</span><span class="n">get_terminator</span><span class="p">():</span>
|
|
||||||
<span class="k">case</span> <span class="n">BranchingTerminator</span><span class="p">()</span> <span class="k">as</span> <span class="n">j</span><span class="p">:</span>
|
|
||||||
<span class="c1"># In case of conditional jump, add the missing edge</span>
|
|
||||||
<span class="k">yield</span> <span class="n">ConditionalJump</span><span class="p">(</span><span class="n">j</span><span class="o">.</span><span class="n">cond</span><span class="p">,</span> <span class="n">j</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="n">j</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="n">j</span><span class="o">.</span><span class="n">label_then</span><span class="p">)</span>
|
|
||||||
<span class="k">yield</span> <span class="n">AbsoluteJump</span><span class="p">(</span><span class="n">j</span><span class="o">.</span><span class="n">label_else</span><span class="p">)</span>
|
|
||||||
<span class="k">case</span> <span class="n">AbsoluteJump</span><span class="p">()</span> <span class="k">as</span> <span class="n">j</span><span class="p">:</span>
|
|
||||||
<span class="k">yield</span> <span class="n">AbsoluteJump</span><span class="p">(</span><span class="n">j</span><span class="o">.</span><span class="n">label</span><span class="p">)</span>
|
|
||||||
<span class="k">case</span> <span class="n">Return</span><span class="p">():</span>
|
|
||||||
<span class="k">yield</span> <span class="n">AbsoluteJump</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_end</span><span class="p">())</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.print_code"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.print_code">[docs]</a> <span class="k">def</span> <span class="nf">print_code</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">output</span><span class="p">,</span> <span class="n">linearize</span><span class="o">=</span><span class="p">(</span><span class="k">lambda</span> <span class="n">cfg</span><span class="p">:</span> <span class="nb">list</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">linearize_naive</span><span class="p">())),</span>
|
|
||||||
<span class="n">comment</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Print the linearization of the CFG."""</span>
|
|
||||||
<span class="n">statements</span> <span class="o">=</span> <span class="n">linearize</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
||||||
<span class="n">_print_code</span><span class="p">(</span><span class="n">statements</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fdata</span><span class="p">,</span> <span class="n">output</span><span class="p">,</span> <span class="n">init_label</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_start</span><span class="p">,</span>
|
|
||||||
<span class="n">fin_label</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_end</span><span class="p">,</span> <span class="n">fin_div0</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">comment</span><span class="o">=</span><span class="n">comment</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="CFG.print_dot"><a class="viewcode-back" href="../../api/Lib.CFG.html#Lib.CFG.CFG.print_dot">[docs]</a> <span class="k">def</span> <span class="nf">print_dot</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">DF</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">view</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Print the CFG as a graph."""</span>
|
|
||||||
<span class="n">graph</span> <span class="o">=</span> <span class="n">Digraph</span><span class="p">()</span>
|
|
||||||
<span class="c1"># nodes</span>
|
|
||||||
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">blk</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
||||||
<span class="k">if</span> <span class="n">DF</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="n">df_str</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{}</span><span class="s2">"</span> <span class="k">if</span> <span class="n">blk</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">DF</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">len</span><span class="p">(</span><span class="n">DF</span><span class="p">[</span><span class="n">blk</span><span class="p">])</span> <span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">DF</span><span class="p">[</span><span class="n">blk</span><span class="p">])</span>
|
|
||||||
<span class="n">df_lab</span> <span class="o">=</span> <span class="n">blk</span><span class="o">.</span><span class="n">to_dot</span><span class="p">()</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n\n</span><span class="s2">Dominance frontier:</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span> <span class="n">df_str</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="n">df_lab</span> <span class="o">=</span> <span class="n">blk</span><span class="o">.</span><span class="n">to_dot</span><span class="p">()</span>
|
|
||||||
<span class="n">graph</span><span class="o">.</span><span class="n">node</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">blk</span><span class="o">.</span><span class="n">_label</span><span class="p">),</span> <span class="n">label</span><span class="o">=</span><span class="n">df_lab</span><span class="p">,</span> <span class="n">shape</span><span class="o">=</span><span class="s1">'rectangle'</span><span class="p">)</span>
|
|
||||||
<span class="c1"># edges</span>
|
|
||||||
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">blk</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_blocks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
||||||
<span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">blk</span><span class="o">.</span><span class="n">get_terminator</span><span class="p">()</span><span class="o">.</span><span class="n">targets</span><span class="p">():</span>
|
|
||||||
<span class="n">graph</span><span class="o">.</span><span class="n">edge</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">blk</span><span class="o">.</span><span class="n">_label</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">child</span><span class="p">))</span>
|
|
||||||
<span class="n">graph</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">view</span><span class="o">=</span><span class="n">view</span><span class="p">)</span></div></div>
|
|
||||||
</pre></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<div role="contentinfo">
|
|
||||||
<p>© Copyright 2023, compil-lyon.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
|
||||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
|
||||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
|
||||||
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
jQuery(function () {
|
|
||||||
SphinxRtdTheme.Navigation.enable(true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,239 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html class="writer-html5" lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Lib.Dominators — MiniC documentation</title>
|
|
||||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
||||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
|
||||||
<script src="../../_static/doctools.js"></script>
|
|
||||||
<script src="../../_static/sphinx_highlight.js"></script>
|
|
||||||
<script src="../../_static/js/theme.js"></script>
|
|
||||||
<link rel="index" title="Index" href="../../genindex.html" />
|
|
||||||
<link rel="search" title="Search" href="../../search.html" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="wy-body-for-nav">
|
|
||||||
<div class="wy-grid-for-nav">
|
|
||||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
||||||
<div class="wy-side-scroll">
|
|
||||||
<div class="wy-side-nav-search" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="../../index.html" class="icon icon-home">
|
|
||||||
MiniC
|
|
||||||
</a>
|
|
||||||
<div role="search">
|
|
||||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
|
||||||
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
|
||||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
|
||||||
<ul>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
|
||||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
||||||
<a href="../../index.html">MiniC</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="wy-nav-content">
|
|
||||||
<div class="rst-content">
|
|
||||||
<div role="navigation" aria-label="Page navigation">
|
|
||||||
<ul class="wy-breadcrumbs">
|
|
||||||
<li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="../index.html">Module code</a></li>
|
|
||||||
<li class="breadcrumb-item active">Lib.Dominators</li>
|
|
||||||
<li class="wy-breadcrumbs-aside">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
<div itemprop="articleBody">
|
|
||||||
|
|
||||||
<h1>Source code for Lib.Dominators</h1><div class="highlight"><pre>
|
|
||||||
<span></span><span class="sd">"""</span>
|
|
||||||
<span class="sd">Utility functions to work with dominators in a :py:class:`CFG <Lib.CFG.CFG>`.</span>
|
|
||||||
|
|
||||||
<span class="sd">Do not hesitate to look at the source of the functions</span>
|
|
||||||
<span class="sd">to get a better understanding of the algorithms.</span>
|
|
||||||
<span class="sd">"""</span>
|
|
||||||
|
|
||||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Set</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">graphviz</span> <span class="kn">import</span> <span class="n">Digraph</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.CFG</span> <span class="kn">import</span> <span class="n">Block</span><span class="p">,</span> <span class="n">CFG</span>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="computeDom"><a class="viewcode-back" href="../../api/Lib.Dominators.html#Lib.Dominators.computeDom">[docs]</a><span class="k">def</span> <span class="nf">computeDom</span><span class="p">(</span><span class="n">cfg</span><span class="p">:</span> <span class="n">CFG</span><span class="p">)</span> <span class="o">-></span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> `computeDom(cfg)` computes the table associating blocks to their</span>
|
|
||||||
<span class="sd"> dominators in `cfg`.</span>
|
|
||||||
<span class="sd"> It works by solving the equation system.</span>
|
|
||||||
|
|
||||||
<span class="sd"> This is an helper function called during SSA entry.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">all_blocks</span><span class="p">:</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get_blocks</span><span class="p">())</span>
|
|
||||||
<span class="n">dominators</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
|
||||||
<span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">all_blocks</span><span class="p">:</span>
|
|
||||||
<span class="k">if</span> <span class="n">b</span><span class="o">.</span><span class="n">get_in</span><span class="p">():</span> <span class="c1"># If b has some predecessor</span>
|
|
||||||
<span class="n">dominators</span><span class="p">[</span><span class="n">b</span><span class="p">]</span> <span class="o">=</span> <span class="n">all_blocks</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span> <span class="c1"># If b has no predecessors</span>
|
|
||||||
<span class="n">dominators</span><span class="p">[</span><span class="n">b</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="n">b</span><span class="p">}</span>
|
|
||||||
<span class="n">new_dominators</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
|
||||||
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
|
||||||
<span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">all_blocks</span><span class="p">:</span>
|
|
||||||
<span class="k">if</span> <span class="n">b</span><span class="o">.</span><span class="n">get_in</span><span class="p">():</span>
|
|
||||||
<span class="n">dom_preds</span> <span class="o">=</span> <span class="p">[</span><span class="n">dominators</span><span class="p">[</span><span class="n">b2</span><span class="p">]</span> <span class="k">for</span> <span class="n">b2</span> <span class="ow">in</span> <span class="n">b</span><span class="o">.</span><span class="n">get_in</span><span class="p">()]</span>
|
|
||||||
<span class="n">new_dominators</span><span class="p">[</span><span class="n">b</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="n">b</span><span class="p">}</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="nb">set</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="o">*</span><span class="n">dom_preds</span><span class="p">))</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="n">new_dominators</span><span class="p">[</span><span class="n">b</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="n">b</span><span class="p">}</span>
|
|
||||||
<span class="k">if</span> <span class="n">dominators</span> <span class="o">==</span> <span class="n">new_dominators</span><span class="p">:</span>
|
|
||||||
<span class="k">break</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="n">dominators</span> <span class="o">=</span> <span class="n">new_dominators</span>
|
|
||||||
<span class="n">new_dominators</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
|
||||||
<span class="k">return</span> <span class="n">dominators</span></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="printDT"><a class="viewcode-back" href="../../api/Lib.Dominators.html#Lib.Dominators.printDT">[docs]</a><span class="k">def</span> <span class="nf">printDT</span><span class="p">(</span><span class="n">filename</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">graph</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]])</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Display a graphical rendering of the given domination tree."""</span>
|
|
||||||
<span class="n">dot</span> <span class="o">=</span> <span class="n">Digraph</span><span class="p">()</span>
|
|
||||||
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">graph</span><span class="p">:</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">node</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">k</span><span class="o">.</span><span class="n">get_label</span><span class="p">()))</span>
|
|
||||||
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">graph</span><span class="p">:</span>
|
|
||||||
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">]:</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">edge</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">k</span><span class="o">.</span><span class="n">get_label</span><span class="p">()),</span> <span class="nb">str</span><span class="p">(</span><span class="n">v</span><span class="o">.</span><span class="n">get_label</span><span class="p">()))</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">view</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="computeDT"><a class="viewcode-back" href="../../api/Lib.Dominators.html#Lib.Dominators.computeDT">[docs]</a><span class="k">def</span> <span class="nf">computeDT</span><span class="p">(</span><span class="n">cfg</span><span class="p">:</span> <span class="n">CFG</span><span class="p">,</span> <span class="n">dominators</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]],</span>
|
|
||||||
<span class="n">dom_graphs</span><span class="p">:</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">basename</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> `computeDT(cfg, dominators)` computes the domination tree of `cfg`</span>
|
|
||||||
<span class="sd"> using the previously computed `dominators`.</span>
|
|
||||||
<span class="sd"> It returns `DT`, a dictionary which associates a block with its children</span>
|
|
||||||
<span class="sd"> in the dominator tree.</span>
|
|
||||||
|
|
||||||
<span class="sd"> This is an helper function called during SSA entry.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="c1"># First, compute the immediate dominators</span>
|
|
||||||
<span class="n">idominators</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Block</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
|
||||||
<span class="k">for</span> <span class="n">b</span><span class="p">,</span> <span class="n">doms</span> <span class="ow">in</span> <span class="n">dominators</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
||||||
<span class="c1"># The immediate dominator of b is the unique vertex n ≠ b</span>
|
|
||||||
<span class="c1"># which dominates b and is dominated by all vertices in Dom(b) − b.</span>
|
|
||||||
<span class="n">strict_doms</span> <span class="o">=</span> <span class="n">doms</span> <span class="o">-</span> <span class="p">{</span><span class="n">b</span><span class="p">}</span>
|
|
||||||
<span class="n">idoms</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
||||||
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">strict_doms</span><span class="p">:</span>
|
|
||||||
<span class="k">if</span> <span class="n">strict_doms</span><span class="o">.</span><span class="n">issubset</span><span class="p">(</span><span class="n">dominators</span><span class="p">[</span><span class="n">n</span><span class="p">]):</span>
|
|
||||||
<span class="n">idoms</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
|
||||||
<span class="k">if</span> <span class="n">idoms</span><span class="p">:</span>
|
|
||||||
<span class="k">assert</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">idoms</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
|
|
||||||
<span class="n">idominators</span><span class="p">[</span><span class="n">b</span><span class="p">]</span> <span class="o">=</span> <span class="n">idoms</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
|
||||||
<span class="c1"># Then, simply inverse the relation to obtain the domination tree</span>
|
|
||||||
<span class="n">DT</span> <span class="o">=</span> <span class="p">{</span><span class="n">b</span><span class="p">:</span> <span class="nb">set</span><span class="p">()</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get_blocks</span><span class="p">()}</span>
|
|
||||||
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">idominator</span> <span class="ow">in</span> <span class="n">idominators</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
||||||
<span class="n">DT</span><span class="p">[</span><span class="n">idominator</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
|
||||||
<span class="c1"># Print the domination tree if asked</span>
|
|
||||||
<span class="k">if</span> <span class="n">dom_graphs</span><span class="p">:</span>
|
|
||||||
<span class="n">s</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">.ssa.DT.dot"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">basename</span><span class="p">,</span> <span class="n">cfg</span><span class="o">.</span><span class="n">fdata</span><span class="o">.</span><span class="n">get_name</span><span class="p">())</span>
|
|
||||||
<span class="nb">print</span><span class="p">(</span><span class="s2">"SSA - domination tree graph:"</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
|
|
||||||
<span class="n">printDT</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">DT</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">DT</span></div>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="nf">_computeDF_at_block</span><span class="p">(</span>
|
|
||||||
<span class="n">cfg</span><span class="p">:</span> <span class="n">CFG</span><span class="p">,</span>
|
|
||||||
<span class="n">dominators</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]],</span>
|
|
||||||
<span class="n">DT</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]],</span>
|
|
||||||
<span class="n">b</span><span class="p">:</span> <span class="n">Block</span><span class="p">,</span>
|
|
||||||
<span class="n">DF</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]])</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> `_computeDF_at_block(...)` computes the dominance frontier at the given block,</span>
|
|
||||||
<span class="sd"> by updating `DF`.</span>
|
|
||||||
|
|
||||||
<span class="sd"> This is an helper function called during SSA entry.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">S</span><span class="p">:</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="n">succ</span> <span class="k">for</span> <span class="n">succ</span> <span class="ow">in</span> <span class="n">cfg</span><span class="o">.</span><span class="n">out_blocks</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="k">if</span> <span class="n">succ</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">DT</span><span class="p">[</span><span class="n">b</span><span class="p">]}</span>
|
|
||||||
<span class="k">for</span> <span class="n">b_succ</span> <span class="ow">in</span> <span class="n">DT</span><span class="p">[</span><span class="n">b</span><span class="p">]:</span>
|
|
||||||
<span class="n">_computeDF_at_block</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">dominators</span><span class="p">,</span> <span class="n">DT</span><span class="p">,</span> <span class="n">b_succ</span><span class="p">,</span> <span class="n">DF</span><span class="p">)</span>
|
|
||||||
<span class="k">for</span> <span class="n">b_frontier</span> <span class="ow">in</span> <span class="n">DF</span><span class="p">[</span><span class="n">b_succ</span><span class="p">]:</span>
|
|
||||||
<span class="k">if</span> <span class="n">b</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="n">dominators</span><span class="p">[</span><span class="n">b_frontier</span><span class="p">]</span> <span class="o">-</span> <span class="p">{</span><span class="n">b_frontier</span><span class="p">}):</span>
|
|
||||||
<span class="n">S</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">b_frontier</span><span class="p">)</span>
|
|
||||||
<span class="n">DF</span><span class="p">[</span><span class="n">b</span><span class="p">]</span> <span class="o">=</span> <span class="n">S</span>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="computeDF"><a class="viewcode-back" href="../../api/Lib.Dominators.html#Lib.Dominators.computeDF">[docs]</a><span class="k">def</span> <span class="nf">computeDF</span><span class="p">(</span><span class="n">cfg</span><span class="p">:</span> <span class="n">CFG</span><span class="p">,</span> <span class="n">dominators</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]],</span>
|
|
||||||
<span class="n">DT</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]],</span> <span class="n">dom_graphs</span><span class="p">:</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">basename</span><span class="p">:</span> <span class="nb">str</span>
|
|
||||||
<span class="p">)</span> <span class="o">-></span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> `computeDF(...)` computes the dominance frontier of a CFG.</span>
|
|
||||||
<span class="sd"> It returns `DF` which associates a block to its frontier.</span>
|
|
||||||
|
|
||||||
<span class="sd"> This is an helper function called during SSA entry.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">DF</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Block</span><span class="p">,</span> <span class="n">Set</span><span class="p">[</span><span class="n">Block</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
|
||||||
<span class="k">for</span> <span class="n">b_entry</span> <span class="ow">in</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get_entries</span><span class="p">():</span>
|
|
||||||
<span class="n">_computeDF_at_block</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">dominators</span><span class="p">,</span> <span class="n">DT</span><span class="p">,</span> <span class="n">b_entry</span><span class="p">,</span> <span class="n">DF</span><span class="p">)</span>
|
|
||||||
<span class="c1"># Print the domination frontier on the CFG if asked</span>
|
|
||||||
<span class="k">if</span> <span class="n">dom_graphs</span><span class="p">:</span>
|
|
||||||
<span class="n">s</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">.ssa.DF.dot"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">basename</span><span class="p">,</span> <span class="n">cfg</span><span class="o">.</span><span class="n">fdata</span><span class="o">.</span><span class="n">get_name</span><span class="p">())</span>
|
|
||||||
<span class="nb">print</span><span class="p">(</span><span class="s2">"SSA - dominance frontier graph:"</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
|
|
||||||
<span class="n">cfg</span><span class="o">.</span><span class="n">print_dot</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">DF</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">DF</span></div>
|
|
||||||
</pre></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<div role="contentinfo">
|
|
||||||
<p>© Copyright 2023, compil-lyon.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
|
||||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
|
||||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
|
||||||
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
jQuery(function () {
|
|
||||||
SphinxRtdTheme.Navigation.enable(true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -45,13 +45,8 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,13 +45,8 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,423 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html class="writer-html5" lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Lib.Graphes — MiniC documentation</title>
|
|
||||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
||||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
|
||||||
<script src="../../_static/doctools.js"></script>
|
|
||||||
<script src="../../_static/sphinx_highlight.js"></script>
|
|
||||||
<script src="../../_static/js/theme.js"></script>
|
|
||||||
<link rel="index" title="Index" href="../../genindex.html" />
|
|
||||||
<link rel="search" title="Search" href="../../search.html" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="wy-body-for-nav">
|
|
||||||
<div class="wy-grid-for-nav">
|
|
||||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
||||||
<div class="wy-side-scroll">
|
|
||||||
<div class="wy-side-nav-search" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="../../index.html" class="icon icon-home">
|
|
||||||
MiniC
|
|
||||||
</a>
|
|
||||||
<div role="search">
|
|
||||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
|
||||||
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
|
||||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
|
||||||
<ul>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
|
||||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
||||||
<a href="../../index.html">MiniC</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="wy-nav-content">
|
|
||||||
<div class="rst-content">
|
|
||||||
<div role="navigation" aria-label="Page navigation">
|
|
||||||
<ul class="wy-breadcrumbs">
|
|
||||||
<li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="../index.html">Module code</a></li>
|
|
||||||
<li class="breadcrumb-item active">Lib.Graphes</li>
|
|
||||||
<li class="wy-breadcrumbs-aside">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
<div itemprop="articleBody">
|
|
||||||
|
|
||||||
<h1>Source code for Lib.Graphes</h1><div class="highlight"><pre>
|
|
||||||
<span></span><span class="sd">""" Python Classes for Oriented and Non Oriented Graphs</span>
|
|
||||||
<span class="sd">"""</span>
|
|
||||||
|
|
||||||
<span class="kn">from</span> <span class="nn">graphviz</span> <span class="kn">import</span> <span class="n">Digraph</span> <span class="c1"># for dot output</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">List</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Set</span><span class="p">,</span> <span class="n">Tuple</span><span class="p">,</span> <span class="n">Any</span>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GraphError"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GraphError">[docs]</a><span class="k">class</span> <span class="nc">GraphError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Exception raised for self loops.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
|
|
||||||
<span class="n">message</span><span class="p">:</span> <span class="nb">str</span>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GeneralGraph"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GeneralGraph">[docs]</a><span class="k">class</span> <span class="nc">GeneralGraph</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> General class regrouping similarities</span>
|
|
||||||
<span class="sd"> between directed and non oriented graphs.</span>
|
|
||||||
<span class="sd"> The only differences between the two are:</span>
|
|
||||||
|
|
||||||
<span class="sd"> - how to compute the set of edges</span>
|
|
||||||
<span class="sd"> - how to add an edge</span>
|
|
||||||
<span class="sd"> - how to print the graph</span>
|
|
||||||
<span class="sd"> - how to delete a vertex</span>
|
|
||||||
<span class="sd"> - how to delete an edge</span>
|
|
||||||
<span class="sd"> - we only color undirected graphs</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
|
|
||||||
<span class="n">graph_dict</span><span class="p">:</span> <span class="n">Dict</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="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph_dict</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Initializes a graph object.</span>
|
|
||||||
<span class="sd"> If no dictionary or None is given,</span>
|
|
||||||
<span class="sd"> an empty dictionary will be used.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">if</span> <span class="n">graph_dict</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="n">graph_dict</span> <span class="o">=</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">graph_dict</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GeneralGraph.vertices"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GeneralGraph.vertices">[docs]</a> <span class="k">def</span> <span class="nf">vertices</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">Any</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the vertices of a 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">keys</span><span class="p">())</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GeneralGraph.add_vertex"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GeneralGraph.add_vertex">[docs]</a> <span class="k">def</span> <span class="nf">add_vertex</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vertex</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> If the vertex "vertex" is not in</span>
|
|
||||||
<span class="sd"> self.graph_dict, a key "vertex" with an empty</span>
|
|
||||||
<span class="sd"> list as a value is added to the dictionary.</span>
|
|
||||||
<span class="sd"> Otherwise nothing has to be done.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">if</span> <span class="n">vertex</span> <span class="ow">not</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="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GeneralGraph.edges"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GeneralGraph.edges">[docs]</a> <span class="k">def</span> <span class="nf">edges</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">Set</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the edges of the graph."""</span>
|
|
||||||
<span class="k">return</span> <span class="p">[]</span></div>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
||||||
<span class="n">res</span> <span class="o">=</span> <span class="s2">"vertices: "</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">res</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">k</span><span class="p">)</span> <span class="o">+</span> <span class="s2">" "</span>
|
|
||||||
<span class="n">res</span> <span class="o">+=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">edges: "</span>
|
|
||||||
<span class="k">for</span> <span class="n">edge</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">edges</span><span class="p">():</span>
|
|
||||||
<span class="n">res</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">edge</span><span class="p">)</span> <span class="o">+</span> <span class="s2">" "</span>
|
|
||||||
<span class="k">return</span> <span class="n">res</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GeneralGraph.dfs_traversal"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GeneralGraph.dfs_traversal">[docs]</a> <span class="k">def</span> <span class="nf">dfs_traversal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">root</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Compute a depth first search of the graph,</span>
|
|
||||||
<span class="sd"> from the vertex root.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">seen</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="n">todo</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">root</span><span class="p">]</span>
|
|
||||||
<span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">todo</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> <span class="c1"># while todo ...</span>
|
|
||||||
<span class="n">current</span> <span class="o">=</span> <span class="n">todo</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
|
||||||
<span class="n">seen</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
|
|
||||||
<span class="k">for</span> <span class="n">neighbour</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">current</span><span class="p">]:</span>
|
|
||||||
<span class="k">if</span> <span class="n">neighbour</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">seen</span><span class="p">:</span>
|
|
||||||
<span class="n">todo</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">neighbour</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">seen</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GeneralGraph.is_reachable_from"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GeneralGraph.is_reachable_from">[docs]</a> <span class="k">def</span> <span class="nf">is_reachable_from</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">v1</span><span class="p">:</span> <span class="n">Any</span><span class="p">,</span> <span class="n">v2</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""True if there is a path from v1 to v2."""</span>
|
|
||||||
<span class="k">return</span> <span class="n">v2</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">dfs_traversal</span><span class="p">(</span><span class="n">v1</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GeneralGraph.connected_components"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GeneralGraph.connected_components">[docs]</a> <span class="k">def</span> <span class="nf">connected_components</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">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Compute the list of all connected components of the graph,</span>
|
|
||||||
<span class="sd"> each component being a list of vetices.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">components</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="n">done</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">vertices</span><span class="p">():</span>
|
|
||||||
<span class="k">if</span> <span class="n">v</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">done</span><span class="p">:</span>
|
|
||||||
<span class="n">v_comp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">dfs_traversal</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
|
|
||||||
<span class="n">components</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">v_comp</span><span class="p">)</span>
|
|
||||||
<span class="n">done</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">v_comp</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">components</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="GeneralGraph.bfs_traversal"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.GeneralGraph.bfs_traversal">[docs]</a> <span class="k">def</span> <span class="nf">bfs_traversal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">root</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Compute a breadth first search of the graph,</span>
|
|
||||||
<span class="sd"> from the vertex root.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">seen</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="n">todo</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">root</span><span class="p">]</span>
|
|
||||||
<span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">todo</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> <span class="c1"># while todo ...</span>
|
|
||||||
<span class="n">current</span> <span class="o">=</span> <span class="n">todo</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># list.pop(0): for dequeuing (on the left...) !</span>
|
|
||||||
<span class="n">seen</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
|
|
||||||
<span class="k">for</span> <span class="n">neighbour</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">current</span><span class="p">]:</span>
|
|
||||||
<span class="k">if</span> <span class="n">neighbour</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">seen</span><span class="p">:</span>
|
|
||||||
<span class="n">todo</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">neighbour</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">seen</span></div></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Graph"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.Graph">[docs]</a><span class="k">class</span> <span class="nc">Graph</span><span class="p">(</span><span class="n">GeneralGraph</span><span class="p">):</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Class for non oriented graphs."""</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Graph.edges"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.Graph.edges">[docs]</a> <span class="k">def</span> <span class="nf">edges</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">Set</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> A static method generating the set of edges</span>
|
|
||||||
<span class="sd"> (they appear twice in the dictionnary).</span>
|
|
||||||
<span class="sd"> Return a list of sets.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">edges</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="k">for</span> <span class="n">vertex</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="k">for</span> <span class="n">neighbour</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">vertex</span><span class="p">]:</span>
|
|
||||||
<span class="k">if</span> <span class="p">{</span><span class="n">neighbour</span><span class="p">,</span> <span class="n">vertex</span><span class="p">}</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">edges</span><span class="p">:</span>
|
|
||||||
<span class="n">edges</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="n">vertex</span><span class="p">,</span> <span class="n">neighbour</span><span class="p">})</span>
|
|
||||||
<span class="k">return</span> <span class="n">edges</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Graph.add_edge"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.Graph.add_edge">[docs]</a> <span class="k">def</span> <span class="nf">add_edge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">edge</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">Any</span><span class="p">])</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Add an edge in the graph.</span>
|
|
||||||
<span class="sd"> edge should be a pair and not (c,c)</span>
|
|
||||||
<span class="sd"> (we call g.add_edge((v1,v2)))</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="p">(</span><span class="n">vertex1</span><span class="p">,</span> <span class="n">vertex2</span><span class="p">)</span> <span class="o">=</span> <span class="n">edge</span>
|
|
||||||
<span class="k">if</span> <span class="n">vertex1</span> <span class="o">==</span> <span class="n">vertex2</span><span class="p">:</span>
|
|
||||||
<span class="k">raise</span> <span class="n">GraphError</span><span class="p">(</span><span class="s2">"Cannot add a self loop on vertex </span><span class="si">{}</span><span class="s2"> in an unoriented graph."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
||||||
<span class="nb">str</span><span class="p">(</span><span class="n">vertex1</span><span class="p">)))</span>
|
|
||||||
<span class="k">if</span> <span class="n">vertex1</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="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex1</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">vertex2</span><span class="p">)</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex1</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="n">vertex2</span><span class="p">}</span>
|
|
||||||
<span class="k">if</span> <span class="n">vertex2</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="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex2</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">vertex1</span><span class="p">)</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex2</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="n">vertex1</span><span class="p">}</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Graph.print_dot"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.Graph.print_dot">[docs]</a> <span class="k">def</span> <span class="nf">print_dot</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">colors</span><span class="o">=</span><span class="p">{})</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><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">'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>
|
|
||||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">colors</span><span class="p">:</span>
|
|
||||||
<span class="n">color</span> <span class="o">=</span> <span class="s2">"red"</span> <span class="c1"># Graph not colored: red for everyone</span>
|
|
||||||
<span class="k">elif</span> <span class="n">k</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">colors</span><span class="p">:</span>
|
|
||||||
<span class="n">color</span> <span class="o">=</span> <span class="s2">"grey"</span> <span class="c1"># Node not colored: grey</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="n">n</span> <span class="o">=</span> <span class="n">colors</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
|
|
||||||
<span class="k">if</span> <span class="n">n</span> <span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">color_names</span><span class="p">):</span>
|
|
||||||
<span class="n">color</span> <span class="o">=</span> <span class="n">color_names</span><span class="p">[</span><span class="n">colors</span><span class="p">[</span><span class="n">k</span><span class="p">]]</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="n">color</span> <span class="o">=</span> <span class="s2">"black"</span> <span class="c1"># Too many colors anyway, it won't be readable.</span>
|
|
||||||
<span class="n">shape</span> <span class="o">=</span> <span class="n">color_shapes</span><span class="p">[</span><span class="n">n</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">color_shapes</span><span class="p">)]</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">node</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">k</span><span class="p">),</span> <span class="n">color</span><span class="o">=</span><span class="n">color</span><span class="p">,</span> <span class="n">shape</span><span class="o">=</span><span class="n">shape</span><span class="p">)</span>
|
|
||||||
<span class="k">for</span> <span class="p">(</span><span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">edges</span><span class="p">():</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">edge</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">v1</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">v2</span><span class="p">),</span> <span class="nb">dir</span><span class="o">=</span><span class="s2">"none"</span><span class="p">)</span>
|
|
||||||
<span class="c1"># print(dot.source)</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">view</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="c1"># print in pdf</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Graph.delete_vertex"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.Graph.delete_vertex">[docs]</a> <span class="k">def</span> <span class="nf">delete_vertex</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vertex</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Delete a vertex and all the adjacent edges."""</span>
|
|
||||||
<span class="n">gdict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span>
|
|
||||||
<span class="k">for</span> <span class="n">neighbour</span> <span class="ow">in</span> <span class="n">gdict</span><span class="p">[</span><span class="n">vertex</span><span class="p">]:</span>
|
|
||||||
<span class="n">gdict</span><span class="p">[</span><span class="n">neighbour</span><span class="p">]</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">vertex</span><span class="p">)</span>
|
|
||||||
<span class="k">del</span> <span class="n">gdict</span><span class="p">[</span><span class="n">vertex</span><span class="p">]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Graph.delete_edge"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.Graph.delete_edge">[docs]</a> <span class="k">def</span> <span class="nf">delete_edge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">edge</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">Any</span><span class="p">]):</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Delete an edge."""</span>
|
|
||||||
<span class="p">(</span><span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">)</span> <span class="o">=</span> <span class="n">edge</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">v1</span><span class="p">]</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">v2</span><span class="p">)</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">v2</span><span class="p">]</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">v1</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Graph.color"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.Graph.color">[docs]</a> <span class="k">def</span> <span class="nf">color</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Dict</span><span class="p">[</span><span class="n">Any</span><span class="p">,</span> <span class="nb">int</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Color the graph with an unlimited number of colors.</span>
|
|
||||||
<span class="sd"> Return a dict vertex -> color, where color is an integer (0, 1, ...).</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">coloring</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">color_with_k_colors</span><span class="p">()</span>
|
|
||||||
<span class="k">return</span> <span class="n">coloring</span></div>
|
|
||||||
|
|
||||||
<span class="c1"># see algo of the course</span>
|
|
||||||
<div class="viewcode-block" id="Graph.color_with_k_colors"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.Graph.color_with_k_colors">[docs]</a> <span class="k">def</span> <span class="nf">color_with_k_colors</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">K</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">avoidingnodes</span><span class="o">=</span><span class="p">())</span> <span class="o">-></span> <span class="n">Tuple</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="n">Any</span><span class="p">,</span> <span class="nb">int</span><span class="p">],</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">List</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Color with <= K colors (if K is unspecified, use unlimited colors).</span>
|
|
||||||
|
|
||||||
<span class="sd"> Return 3 values:</span>
|
|
||||||
|
|
||||||
<span class="sd"> - a dict vertex -> color</span>
|
|
||||||
<span class="sd"> - a Boolean, True if the coloring succeeded</span>
|
|
||||||
<span class="sd"> - the set of nodes actually colored</span>
|
|
||||||
|
|
||||||
<span class="sd"> Do not color vertices belonging to avoidingnodes.</span>
|
|
||||||
|
|
||||||
<span class="sd"> Continue even if the algo fails.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">if</span> <span class="n">K</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="n">K</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">)</span>
|
|
||||||
<span class="n">todo_vertices</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="n">is_total</span> <span class="o">=</span> <span class="kc">True</span>
|
|
||||||
<span class="n">gcopy</span> <span class="o">=</span> <span class="n">Graph</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">copy</span><span class="p">())</span>
|
|
||||||
<span class="c1"># suppress nodes that are not to be considered.</span>
|
|
||||||
<span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">avoidingnodes</span><span class="p">:</span>
|
|
||||||
<span class="n">gcopy</span><span class="o">.</span><span class="n">delete_vertex</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
|
|
||||||
<span class="c1"># append nodes in the list according to their degree and node number:</span>
|
|
||||||
<span class="k">while</span> <span class="n">gcopy</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">:</span>
|
|
||||||
<span class="n">todo</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">gcopy</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">)</span>
|
|
||||||
<span class="n">todo</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">v</span><span class="p">:</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">gcopy</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">v</span><span class="p">]),</span> <span class="nb">str</span><span class="p">(</span><span class="n">v</span><span class="p">)))</span>
|
|
||||||
<span class="n">lower</span> <span class="o">=</span> <span class="n">todo</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
||||||
<span class="n">todo_vertices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">lower</span><span class="p">)</span>
|
|
||||||
<span class="n">gcopy</span><span class="o">.</span><span class="n">delete_vertex</span><span class="p">(</span><span class="n">lower</span><span class="p">)</span>
|
|
||||||
<span class="c1"># Now reverse the list: first elements are those with higher degree</span>
|
|
||||||
<span class="c1"># print(todo_vertices)</span>
|
|
||||||
<span class="n">todo_vertices</span><span class="o">.</span><span class="n">reverse</span><span class="p">()</span> <span class="c1"># in place reversal</span>
|
|
||||||
<span class="c1"># print(todo_vertices)</span>
|
|
||||||
<span class="n">coloring</span> <span class="o">=</span> <span class="p">{}</span>
|
|
||||||
<span class="n">colored_nodes</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="c1"># gdict will be the coloring map to return</span>
|
|
||||||
<span class="n">gdict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span>
|
|
||||||
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">todo_vertices</span><span class="p">:</span>
|
|
||||||
<span class="n">seen_neighbours</span> <span class="o">=</span> <span class="p">[</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">gdict</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">coloring</span><span class="p">]</span>
|
|
||||||
<span class="n">choose_among</span> <span class="o">=</span> <span class="p">[</span><span class="n">i</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="n">K</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span>
|
|
||||||
<span class="n">i</span> <span class="ow">in</span> <span class="p">[</span><span class="n">coloring</span><span class="p">[</span><span class="n">v1</span><span class="p">]</span> <span class="k">for</span> <span class="n">v1</span> <span class="ow">in</span> <span class="n">seen_neighbours</span><span class="p">])]</span>
|
|
||||||
<span class="k">if</span> <span class="n">choose_among</span><span class="p">:</span>
|
|
||||||
<span class="c1"># if the node can be colored, I choose the minimal color.</span>
|
|
||||||
<span class="n">color</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">choose_among</span><span class="p">)</span>
|
|
||||||
<span class="n">coloring</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">color</span>
|
|
||||||
<span class="n">colored_nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="c1"># if I cannot color some node, the coloring is not Total</span>
|
|
||||||
<span class="c1"># but I continue</span>
|
|
||||||
<span class="n">is_total</span> <span class="o">=</span> <span class="kc">False</span>
|
|
||||||
<span class="k">return</span> <span class="p">(</span><span class="n">coloring</span><span class="p">,</span> <span class="n">is_total</span><span class="p">,</span> <span class="n">colored_nodes</span><span class="p">)</span></div></div>
|
|
||||||
|
|
||||||
|
|
||||||
<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="w"> </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="w"> </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="w"> </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>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="DiGraph.edges"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.DiGraph.edges">[docs]</a> <span class="k">def</span> <span class="nf">edges</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">Set</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">""" A static method generating the set of edges"""</span>
|
|
||||||
<span class="n">edges</span> <span class="o">=</span> <span class="p">[]</span>
|
|
||||||
<span class="k">for</span> <span class="n">vertex</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="k">for</span> <span class="n">neighbour</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">vertex</span><span class="p">]:</span>
|
|
||||||
<span class="n">edges</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">vertex</span><span class="p">,</span> <span class="n">neighbour</span><span class="p">))</span>
|
|
||||||
<span class="k">return</span> <span class="n">edges</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="DiGraph.add_edge"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.DiGraph.add_edge">[docs]</a> <span class="k">def</span> <span class="nf">add_edge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">edge</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">Any</span><span class="p">])</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Add an edge in the graph.</span>
|
|
||||||
<span class="sd"> edge should be a pair and not (c,c)</span>
|
|
||||||
<span class="sd"> (we call g.add_edge((v1,v2)))</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="p">(</span><span class="n">vertex1</span><span class="p">,</span> <span class="n">vertex2</span><span class="p">)</span> <span class="o">=</span> <span class="n">edge</span>
|
|
||||||
<span class="k">if</span> <span class="n">vertex1</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="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex1</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">vertex2</span><span class="p">)</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex1</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="n">vertex2</span><span class="p">}</span>
|
|
||||||
<span class="k">if</span> <span class="n">vertex2</span> <span class="ow">not</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="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex2</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="DiGraph.print_dot"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.DiGraph.print_dot">[docs]</a> <span class="k">def</span> <span class="nf">print_dot</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Print the graph."""</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>
|
|
||||||
<span class="n">color</span> <span class="o">=</span> <span class="s2">"grey"</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">node</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">k</span><span class="p">),</span> <span class="n">color</span><span class="o">=</span><span class="n">color</span><span class="p">,</span> <span class="n">shape</span><span class="o">=</span><span class="n">shape</span><span class="p">)</span>
|
|
||||||
<span class="k">for</span> <span class="p">(</span><span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">edges</span><span class="p">():</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">edge</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">v1</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">v2</span><span class="p">),</span> <span class="nb">dir</span><span class="o">=</span><span class="s2">"none"</span><span class="p">)</span>
|
|
||||||
<span class="c1"># print(dot.source)</span>
|
|
||||||
<span class="n">dot</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">view</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="c1"># print in pdf</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="DiGraph.delete_vertex"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.DiGraph.delete_vertex">[docs]</a> <span class="k">def</span> <span class="nf">delete_vertex</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vertex</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Delete a vertex and all the adjacent edges."""</span>
|
|
||||||
<span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">neighbours</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">vertex</span> <span class="ow">in</span> <span class="n">neighbours</span><span class="p">:</span>
|
|
||||||
<span class="n">neighbours</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">vertex</span><span class="p">)</span>
|
|
||||||
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">vertex</span><span class="p">]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="DiGraph.delete_edge"><a class="viewcode-back" href="../../api/Lib.Graphes.html#Lib.Graphes.DiGraph.delete_edge">[docs]</a> <span class="k">def</span> <span class="nf">delete_edge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">edge</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">Any</span><span class="p">])</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Delete an edge."""</span>
|
|
||||||
<span class="p">(</span><span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">)</span> <span class="o">=</span> <span class="n">edge</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">graph_dict</span><span class="p">[</span><span class="n">v1</span><span class="p">]</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">v2</span><span class="p">)</span></div></div>
|
|
||||||
</pre></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<div role="contentinfo">
|
|
||||||
<p>© Copyright 2023, compil-lyon.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
|
||||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
|
||||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
|
||||||
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
jQuery(function () {
|
|
||||||
SphinxRtdTheme.Navigation.enable(true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -45,13 +45,8 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,13 +45,8 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,174 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html class="writer-html5" lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Lib.PhiNode — MiniC documentation</title>
|
|
||||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
||||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
|
||||||
<script src="../../_static/doctools.js"></script>
|
|
||||||
<script src="../../_static/sphinx_highlight.js"></script>
|
|
||||||
<script src="../../_static/js/theme.js"></script>
|
|
||||||
<link rel="index" title="Index" href="../../genindex.html" />
|
|
||||||
<link rel="search" title="Search" href="../../search.html" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="wy-body-for-nav">
|
|
||||||
<div class="wy-grid-for-nav">
|
|
||||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
||||||
<div class="wy-side-scroll">
|
|
||||||
<div class="wy-side-nav-search" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="../../index.html" class="icon icon-home">
|
|
||||||
MiniC
|
|
||||||
</a>
|
|
||||||
<div role="search">
|
|
||||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
|
||||||
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
|
||||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
|
||||||
<ul>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
|
||||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
||||||
<a href="../../index.html">MiniC</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="wy-nav-content">
|
|
||||||
<div class="rst-content">
|
|
||||||
<div role="navigation" aria-label="Page navigation">
|
|
||||||
<ul class="wy-breadcrumbs">
|
|
||||||
<li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="../index.html">Module code</a></li>
|
|
||||||
<li class="breadcrumb-item active">Lib.PhiNode</li>
|
|
||||||
<li class="wy-breadcrumbs-aside">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
<div itemprop="articleBody">
|
|
||||||
|
|
||||||
<h1>Source code for Lib.PhiNode</h1><div class="highlight"><pre>
|
|
||||||
<span></span><span class="sd">"""</span>
|
|
||||||
<span class="sd">Classes for φ nodes in a RiscV CFG :py:class:`CFG <Lib.CFG.CFG>` under SSA Form:</span>
|
|
||||||
<span class="sd">:py:class:`PhiNode` for a statement of the form temp_x = φ(temp_0, ..., temp_n).</span>
|
|
||||||
<span class="sd">These particular kinds of statements are expected to be in the field</span>
|
|
||||||
<span class="sd">b._phis for a :py:class:`Block <Lib.CFG.Block>` b.</span>
|
|
||||||
<span class="sd">"""</span>
|
|
||||||
|
|
||||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">List</span><span class="p">,</span> <span class="n">Dict</span>
|
|
||||||
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Operands</span> <span class="kn">import</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">,</span> <span class="n">DataLocation</span><span class="p">,</span> <span class="n">Renamer</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Statement</span> <span class="kn">import</span> <span class="n">Statement</span><span class="p">,</span> <span class="n">Label</span>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="PhiNode"><a class="viewcode-back" href="../../api/Lib.PhiNode.html#Lib.PhiNode.PhiNode">[docs]</a><span class="nd">@dataclass</span>
|
|
||||||
<span class="k">class</span> <span class="nc">PhiNode</span><span class="p">(</span><span class="n">Statement</span><span class="p">):</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> A φ node is a renaming in the CFG, of the form temp_x = φ(temp_0, ..., temp_n).</span>
|
|
||||||
<span class="sd"> The field var contains the variable temp_x.</span>
|
|
||||||
<span class="sd"> The field srcs links each corresponding predecessor in the CFG</span>
|
|
||||||
<span class="sd"> ---identified by its label---, to the variable temp_i of the φ</span>
|
|
||||||
<span class="sd"> node.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="n">var</span><span class="p">:</span> <span class="n">DataLocation</span>
|
|
||||||
<span class="n">srcs</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Label</span><span class="p">,</span> <span class="n">Operand</span><span class="p">]</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="PhiNode.defined"><a class="viewcode-back" href="../../api/Lib.PhiNode.html#Lib.PhiNode.PhiNode.defined">[docs]</a> <span class="k">def</span> <span class="nf">defined</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">Operand</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the variable defined by the φ node."""</span>
|
|
||||||
<span class="k">return</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">var</span><span class="p">]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="PhiNode.get_srcs"><a class="viewcode-back" href="../../api/Lib.PhiNode.html#Lib.PhiNode.PhiNode.get_srcs">[docs]</a> <span class="k">def</span> <span class="nf">get_srcs</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Dict</span><span class="p">[</span><span class="n">Label</span><span class="p">,</span> <span class="n">Operand</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Return the dictionnary associating for each previous block the corresponding variable.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">srcs</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="PhiNode.used"><a class="viewcode-back" href="../../api/Lib.PhiNode.html#Lib.PhiNode.PhiNode.used">[docs]</a> <span class="k">def</span> <span class="nf">used</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">Operand</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the variables used by the statement."""</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">srcs</span><span class="o">.</span><span class="n">values</span><span class="p">())</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="PhiNode.rename"><a class="viewcode-back" href="../../api/Lib.PhiNode.html#Lib.PhiNode.PhiNode.rename">[docs]</a> <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">renamer</span><span class="p">:</span> <span class="n">Renamer</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Rename the variable defined by the φ node with a fresh name."""</span>
|
|
||||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">):</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">var</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">fresh</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="PhiNode.rename_from"><a class="viewcode-back" href="../../api/Lib.PhiNode.html#Lib.PhiNode.PhiNode.rename_from">[docs]</a> <span class="k">def</span> <span class="nf">rename_from</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">renamer</span><span class="p">:</span> <span class="n">Renamer</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="n">Label</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Rename the variable associated to the block identified by `label`."""</span>
|
|
||||||
<span class="k">if</span> <span class="n">label</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">srcs</span><span class="p">:</span>
|
|
||||||
<span class="n">t</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">srcs</span><span class="p">[</span><span class="n">label</span><span class="p">]</span>
|
|
||||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">):</span>
|
|
||||||
<span class="k">if</span> <span class="n">renamer</span><span class="o">.</span><span class="n">defined</span><span class="p">(</span><span class="n">t</span><span class="p">):</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">srcs</span><span class="p">[</span><span class="n">label</span><span class="p">]</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">srcs</span><span class="p">[</span><span class="n">label</span><span class="p">]</span></div>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
||||||
<span class="k">return</span> <span class="s2">"</span><span class="si">{}</span><span class="s2"> = φ(</span><span class="si">{}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">srcs</span><span class="p">)</span>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
||||||
<span class="k">return</span> <span class="nb">hash</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">var</span><span class="p">,</span> <span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">srcs</span><span class="o">.</span><span class="n">items</span><span class="p">()))</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="PhiNode.printIns"><a class="viewcode-back" href="../../api/Lib.PhiNode.html#Lib.PhiNode.PhiNode.printIns">[docs]</a> <span class="k">def</span> <span class="nf">printIns</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stream</span><span class="p">):</span>
|
|
||||||
<span class="nb">print</span><span class="p">(</span><span class="s1">' # '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">file</span><span class="o">=</span><span class="n">stream</span><span class="p">)</span></div></div>
|
|
||||||
</pre></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<div role="contentinfo">
|
|
||||||
<p>© Copyright 2023, compil-lyon.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
|
||||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
|
||||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
|
||||||
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
jQuery(function () {
|
|
||||||
SphinxRtdTheme.Navigation.enable(true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -45,13 +45,8 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,13 +45,8 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,264 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html class="writer-html5" lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Lib.Terminator — MiniC documentation</title>
|
|
||||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
||||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
|
||||||
<script src="../../_static/doctools.js"></script>
|
|
||||||
<script src="../../_static/sphinx_highlight.js"></script>
|
|
||||||
<script src="../../_static/js/theme.js"></script>
|
|
||||||
<link rel="index" title="Index" href="../../genindex.html" />
|
|
||||||
<link rel="search" title="Search" href="../../search.html" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="wy-body-for-nav">
|
|
||||||
<div class="wy-grid-for-nav">
|
|
||||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
||||||
<div class="wy-side-scroll">
|
|
||||||
<div class="wy-side-nav-search" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="../../index.html" class="icon icon-home">
|
|
||||||
MiniC
|
|
||||||
</a>
|
|
||||||
<div role="search">
|
|
||||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
|
||||||
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
|
||||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
|
||||||
<ul>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
|
||||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
||||||
<a href="../../index.html">MiniC</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="wy-nav-content">
|
|
||||||
<div class="rst-content">
|
|
||||||
<div role="navigation" aria-label="Page navigation">
|
|
||||||
<ul class="wy-breadcrumbs">
|
|
||||||
<li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="../index.html">Module code</a></li>
|
|
||||||
<li class="breadcrumb-item active">Lib.Terminator</li>
|
|
||||||
<li class="wy-breadcrumbs-aside">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
<div itemprop="articleBody">
|
|
||||||
|
|
||||||
<h1>Source code for Lib.Terminator</h1><div class="highlight"><pre>
|
|
||||||
<span></span><span class="sd">"""</span>
|
|
||||||
<span class="sd">MIF08, CAP, CFG library - Terminators.</span>
|
|
||||||
|
|
||||||
<span class="sd">Each :py:class:`block <Lib.CFG.Block>` of a :py:class:`CFG <Lib.CFG.CFG>`</span>
|
|
||||||
<span class="sd">ends with a branching instruction called a terminator.</span>
|
|
||||||
<span class="sd">There are three kinds of terminators:</span>
|
|
||||||
|
|
||||||
<span class="sd">- :py:class:`Lib.Statement.AbsoluteJump` is a non-conditional jump</span>
|
|
||||||
<span class="sd"> to another block of the CFG</span>
|
|
||||||
<span class="sd">- :py:class:`BranchingTerminator` is a conditional branching</span>
|
|
||||||
<span class="sd"> instruction with two successor blocks.</span>
|
|
||||||
<span class="sd"> Unlike the class :py:class:`ConditionalJump <Lib.Statement.ConditionalJump>`</span>
|
|
||||||
<span class="sd"> that was used in :py:class:`LinearCode <Lib.LinearCode.LinearCode>`,</span>
|
|
||||||
<span class="sd"> both successor labels have to be specified.</span>
|
|
||||||
<span class="sd">- :py:class:`Return` marks the end of the function</span>
|
|
||||||
|
|
||||||
<span class="sd">During the construction of the CFG, :py:func:`jump2terminator` builds</span>
|
|
||||||
<span class="sd">a terminator for each extracted chunk of instructions.</span>
|
|
||||||
<span class="sd">"""</span>
|
|
||||||
|
|
||||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">List</span><span class="p">,</span> <span class="n">Dict</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Errors</span> <span class="kn">import</span> <span class="n">MiniCInternalError</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Operands</span> <span class="kn">import</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">Renamer</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">,</span> <span class="n">Condition</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">Lib.Statement</span> <span class="kn">import</span> <span class="n">AbsoluteJump</span><span class="p">,</span> <span class="n">ConditionalJump</span><span class="p">,</span> <span class="n">Instruction</span><span class="p">,</span> <span class="n">Label</span><span class="p">,</span> <span class="n">Statement</span>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Return"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.Return">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">unsafe_hash</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
||||||
<span class="k">class</span> <span class="nc">Return</span><span class="p">(</span><span class="n">Statement</span><span class="p">):</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""A terminator that marks the end of the function."""</span>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
||||||
<span class="k">return</span> <span class="p">(</span><span class="s2">"return"</span><span class="p">)</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Return.printIns"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.Return.printIns">[docs]</a> <span class="k">def</span> <span class="nf">printIns</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stream</span><span class="p">):</span>
|
|
||||||
<span class="nb">print</span><span class="p">(</span><span class="s2">"return"</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">stream</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Return.targets"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.Return.targets">[docs]</a> <span class="k">def</span> <span class="nf">targets</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">Label</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the labels targetted by the Return terminator."""</span>
|
|
||||||
<span class="k">return</span> <span class="p">[]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Return.args"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.Return.args">[docs]</a> <span class="k">def</span> <span class="nf">args</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">Operand</span><span class="p">]:</span>
|
|
||||||
<span class="k">return</span> <span class="p">[]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Return.rename"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.Return.rename">[docs]</a> <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">renamer</span><span class="p">:</span> <span class="n">Renamer</span><span class="p">):</span>
|
|
||||||
<span class="k">pass</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Return.substitute"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.Return.substitute">[docs]</a> <span class="k">def</span> <span class="nf">substitute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subst</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Operand</span><span class="p">]):</span>
|
|
||||||
<span class="k">if</span> <span class="n">subst</span> <span class="o">!=</span> <span class="p">{}:</span>
|
|
||||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span>
|
|
||||||
<span class="s2">"substitute: No possible substitution on instruction </span><span class="si">{}</span><span class="s2">"</span>
|
|
||||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Return.with_args"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.Return.with_args">[docs]</a> <span class="k">def</span> <span class="nf">with_args</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new_args</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Operand</span><span class="p">]):</span>
|
|
||||||
<span class="k">if</span> <span class="n">new_args</span> <span class="o">!=</span> <span class="p">[]:</span>
|
|
||||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span>
|
|
||||||
<span class="s2">"substitute: No possible substitution on instruction </span><span class="si">{}</span><span class="s2">"</span>
|
|
||||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
|
||||||
<span class="k">return</span> <span class="bp">self</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="Return.is_read_only"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.Return.is_read_only">[docs]</a> <span class="k">def</span> <span class="nf">is_read_only</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
|
||||||
<span class="k">return</span> <span class="kc">True</span></div></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="BranchingTerminator"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.BranchingTerminator">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">init</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
|
||||||
<span class="k">class</span> <span class="nc">BranchingTerminator</span><span class="p">(</span><span class="n">Instruction</span><span class="p">):</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""A terminating statement with a condition."""</span>
|
|
||||||
|
|
||||||
<span class="c1">#: The condition of the branch</span>
|
|
||||||
<span class="n">cond</span><span class="p">:</span> <span class="n">Condition</span>
|
|
||||||
<span class="c1">#: The destination label if the condition is true</span>
|
|
||||||
<span class="n">label_then</span><span class="p">:</span> <span class="n">Label</span>
|
|
||||||
<span class="c1">#: The destination label if the condition is false</span>
|
|
||||||
<span class="n">label_else</span><span class="p">:</span> <span class="n">Label</span>
|
|
||||||
<span class="c1">#: The first operand of the condition</span>
|
|
||||||
<span class="n">op1</span><span class="p">:</span> <span class="n">Operand</span>
|
|
||||||
<span class="c1">#: The second operand of the condition</span>
|
|
||||||
<span class="n">op2</span><span class="p">:</span> <span class="n">Operand</span>
|
|
||||||
<span class="n">_read_only</span> <span class="o">=</span> <span class="kc">True</span>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cond</span><span class="p">:</span> <span class="n">Condition</span><span class="p">,</span> <span class="n">op1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">op2</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span>
|
|
||||||
<span class="n">label_then</span><span class="p">:</span> <span class="n">Label</span><span class="p">,</span> <span class="n">label_else</span><span class="p">:</span> <span class="n">Label</span><span class="p">):</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">cond</span> <span class="o">=</span> <span class="n">cond</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">label_then</span> <span class="o">=</span> <span class="n">label_then</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">label_else</span> <span class="o">=</span> <span class="n">label_else</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">op1</span> <span class="o">=</span> <span class="n">op1</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">op2</span> <span class="o">=</span> <span class="n">op2</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">ins</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cond</span><span class="p">)</span>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="BranchingTerminator.args"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.BranchingTerminator.args">[docs]</a> <span class="k">def</span> <span class="nf">args</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">Operand</span><span class="p">]:</span>
|
|
||||||
<span class="k">return</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label_then</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label_else</span><span class="p">]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="BranchingTerminator.targets"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.BranchingTerminator.targets">[docs]</a> <span class="k">def</span> <span class="nf">targets</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">Label</span><span class="p">]:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""Return the labels targetted by the Branching terminator."""</span>
|
|
||||||
<span class="k">return</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">label_then</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label_else</span><span class="p">]</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="BranchingTerminator.rename"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.BranchingTerminator.rename">[docs]</a> <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">renamer</span><span class="p">:</span> <span class="n">Renamer</span><span class="p">):</span>
|
|
||||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">):</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">op1</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">)</span>
|
|
||||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">):</span>
|
|
||||||
<span class="bp">self</span><span class="o">.</span><span class="n">op2</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="BranchingTerminator.substitute"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.BranchingTerminator.substitute">[docs]</a> <span class="k">def</span> <span class="nf">substitute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subst</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Operand</span><span class="p">]):</span>
|
|
||||||
<span class="k">for</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">subst</span><span class="p">:</span>
|
|
||||||
<span class="k">if</span> <span class="n">op</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">():</span>
|
|
||||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span>
|
|
||||||
<span class="s2">"substitute: Operand </span><span class="si">{}</span><span class="s2"> is not present in instruction </span><span class="si">{}</span><span class="s2">"</span>
|
|
||||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span>
|
|
||||||
<span class="n">op1</span> <span class="o">=</span> <span class="n">subst</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">)</span> \
|
|
||||||
<span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">op1</span>
|
|
||||||
<span class="n">op2</span> <span class="o">=</span> <span class="n">subst</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">)</span> \
|
|
||||||
<span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">op2</span>
|
|
||||||
<span class="k">return</span> <span class="n">BranchingTerminator</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cond</span><span class="p">,</span> <span class="n">op1</span><span class="p">,</span> <span class="n">op2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label_then</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label_else</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="BranchingTerminator.with_args"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.BranchingTerminator.with_args">[docs]</a> <span class="k">def</span> <span class="nf">with_args</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new_args</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Operand</span><span class="p">]):</span>
|
|
||||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">new_args</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">4</span><span class="p">:</span>
|
|
||||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span>
|
|
||||||
<span class="s2">"substitute: Invalid number of arguments for instruction </span><span class="si">{}</span><span class="s2">, expected 4 got </span><span class="si">{}</span><span class="s2">"</span>
|
|
||||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new_args</span><span class="p">))</span>
|
|
||||||
<span class="n">op1</span> <span class="o">=</span> <span class="n">new_args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
||||||
<span class="n">op2</span> <span class="o">=</span> <span class="n">new_args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
||||||
<span class="k">return</span> <span class="n">BranchingTerminator</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cond</span><span class="p">,</span> <span class="n">op1</span><span class="p">,</span> <span class="n">op2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label_then</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label_else</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
||||||
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">super</span><span class="p">)</span></div>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="n">Terminator</span> <span class="o">=</span> <span class="n">Return</span> <span class="o">|</span> <span class="n">AbsoluteJump</span> <span class="o">|</span> <span class="n">BranchingTerminator</span>
|
|
||||||
<span class="sd">"""Type alias for terminators"""</span>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="viewcode-block" id="jump2terminator"><a class="viewcode-back" href="../../api/Lib.Terminator.html#Lib.Terminator.jump2terminator">[docs]</a><span class="k">def</span> <span class="nf">jump2terminator</span><span class="p">(</span><span class="n">j</span><span class="p">:</span> <span class="n">ConditionalJump</span> <span class="o">|</span> <span class="n">AbsoluteJump</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span>
|
|
||||||
<span class="n">next_label</span><span class="p">:</span> <span class="n">Label</span> <span class="o">|</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="n">Terminator</span><span class="p">:</span>
|
|
||||||
<span class="w"> </span><span class="sd">"""</span>
|
|
||||||
<span class="sd"> Construct the Terminator associated to the potential jump j</span>
|
|
||||||
<span class="sd"> to the potential label next_label.</span>
|
|
||||||
<span class="sd"> """</span>
|
|
||||||
<span class="k">match</span> <span class="n">j</span><span class="p">:</span>
|
|
||||||
<span class="k">case</span> <span class="n">ConditionalJump</span><span class="p">():</span>
|
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="n">next_label</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">):</span>
|
|
||||||
<span class="k">raise</span> <span class="n">MiniCInternalError</span><span class="p">(</span>
|
|
||||||
<span class="s2">"jump2terminator: Missing secondary label for instruction </span><span class="si">{}</span><span class="s2">"</span>
|
|
||||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">j</span><span class="p">))</span>
|
|
||||||
<span class="n">label_else</span> <span class="o">=</span> <span class="n">next_label</span>
|
|
||||||
<span class="k">return</span> <span class="n">BranchingTerminator</span><span class="p">(</span><span class="n">j</span><span class="o">.</span><span class="n">cond</span><span class="p">,</span> <span class="n">j</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="n">j</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="n">j</span><span class="o">.</span><span class="n">label</span><span class="p">,</span> <span class="n">label_else</span><span class="p">)</span>
|
|
||||||
<span class="k">case</span> <span class="n">AbsoluteJump</span><span class="p">():</span>
|
|
||||||
<span class="k">return</span> <span class="n">AbsoluteJump</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="n">j</span><span class="o">.</span><span class="n">label</span><span class="p">)</span>
|
|
||||||
<span class="k">case</span><span class="w"> </span><span class="k">_</span><span class="p">:</span>
|
|
||||||
<span class="k">if</span> <span class="n">next_label</span><span class="p">:</span>
|
|
||||||
<span class="k">return</span> <span class="n">AbsoluteJump</span><span class="p">(</span><span class="n">next_label</span><span class="p">)</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="k">return</span> <span class="n">Return</span><span class="p">()</span></div>
|
|
||||||
</pre></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<div role="contentinfo">
|
|
||||||
<p>© Copyright 2023, compil-lyon.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
|
||||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
|
||||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
|
||||||
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
jQuery(function () {
|
|
||||||
SphinxRtdTheme.Navigation.enable(true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -45,13 +45,8 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Allocator.html">Temporary allocation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -79,17 +74,12 @@
|
|||||||
|
|
||||||
<h1>All modules for which code is available</h1>
|
<h1>All modules for which code is available</h1>
|
||||||
<ul><li><a href="Lib/Allocator.html">Lib.Allocator</a></li>
|
<ul><li><a href="Lib/Allocator.html">Lib.Allocator</a></li>
|
||||||
<li><a href="Lib/CFG.html">Lib.CFG</a></li>
|
|
||||||
<li><a href="Lib/Dominators.html">Lib.Dominators</a></li>
|
|
||||||
<li><a href="Lib/Errors.html">Lib.Errors</a></li>
|
<li><a href="Lib/Errors.html">Lib.Errors</a></li>
|
||||||
<li><a href="Lib/FunctionData.html">Lib.FunctionData</a></li>
|
<li><a href="Lib/FunctionData.html">Lib.FunctionData</a></li>
|
||||||
<li><a href="Lib/Graphes.html">Lib.Graphes</a></li>
|
|
||||||
<li><a href="Lib/LinearCode.html">Lib.LinearCode</a></li>
|
<li><a href="Lib/LinearCode.html">Lib.LinearCode</a></li>
|
||||||
<li><a href="Lib/Operands.html">Lib.Operands</a></li>
|
<li><a href="Lib/Operands.html">Lib.Operands</a></li>
|
||||||
<li><a href="Lib/PhiNode.html">Lib.PhiNode</a></li>
|
|
||||||
<li><a href="Lib/RiscV.html">Lib.RiscV</a></li>
|
<li><a href="Lib/RiscV.html">Lib.RiscV</a></li>
|
||||||
<li><a href="Lib/Statement.html">Lib.Statement</a></li>
|
<li><a href="Lib/Statement.html">Lib.Statement</a></li>
|
||||||
<li><a href="Lib/Terminator.html">Lib.Terminator</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
Lib.CFG module
|
|
||||||
==============
|
|
||||||
|
|
||||||
.. automodule:: Lib.CFG
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
@ -1,7 +0,0 @@
|
|||||||
Lib.Dominators module
|
|
||||||
=====================
|
|
||||||
|
|
||||||
.. automodule:: Lib.Dominators
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
@ -1,7 +0,0 @@
|
|||||||
Lib.Graphes module
|
|
||||||
==================
|
|
||||||
|
|
||||||
.. automodule:: Lib.Graphes
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
@ -1,7 +0,0 @@
|
|||||||
Lib.PhiNode module
|
|
||||||
==================
|
|
||||||
|
|
||||||
.. automodule:: Lib.PhiNode
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
@ -1,7 +0,0 @@
|
|||||||
Lib.Terminator module
|
|
||||||
=====================
|
|
||||||
|
|
||||||
.. automodule:: Lib.Terminator
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
@ -8,17 +8,12 @@ Submodules
|
|||||||
:maxdepth: 4
|
:maxdepth: 4
|
||||||
|
|
||||||
Lib.Allocator
|
Lib.Allocator
|
||||||
Lib.CFG
|
|
||||||
Lib.Dominators
|
|
||||||
Lib.Errors
|
Lib.Errors
|
||||||
Lib.FunctionData
|
Lib.FunctionData
|
||||||
Lib.Graphes
|
|
||||||
Lib.LinearCode
|
Lib.LinearCode
|
||||||
Lib.Operands
|
Lib.Operands
|
||||||
Lib.PhiNode
|
|
||||||
Lib.RiscV
|
Lib.RiscV
|
||||||
Lib.Statement
|
Lib.Statement
|
||||||
Lib.Terminator
|
|
||||||
|
|
||||||
Module contents
|
Module contents
|
||||||
---------------
|
---------------
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
<script src="../_static/js/theme.js"></script>
|
<script src="../_static/js/theme.js"></script>
|
||||||
<link rel="index" title="Index" href="../genindex.html" />
|
<link rel="index" title="Index" href="../genindex.html" />
|
||||||
<link rel="search" title="Search" href="../search.html" />
|
<link rel="search" title="Search" href="../search.html" />
|
||||||
<link rel="next" title="Lib.CFG module" href="Lib.CFG.html" />
|
|
||||||
<link rel="prev" title="Lib.LinearCode module" href="Lib.LinearCode.html" />
|
<link rel="prev" title="Lib.LinearCode module" href="Lib.LinearCode.html" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -48,7 +47,6 @@
|
|||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Operands.html">Base library - Operands</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="Lib.Operands.html">Base library - Operands</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.FunctionData.html">Base library - Function data</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="Lib.FunctionData.html">Base library - Function data</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.LinearCode.html">Linear intermediate representation</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Temporary allocation</a><ul>
|
<li class="toctree-l1 current"><a class="current reference internal" href="#">Temporary allocation</a><ul>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#Lib.Allocator.Allocator"><code class="docutils literal notranslate"><span class="pre">Allocator</span></code></a><ul>
|
<li class="toctree-l2"><a class="reference internal" href="#Lib.Allocator.Allocator"><code class="docutils literal notranslate"><span class="pre">Allocator</span></code></a><ul>
|
||||||
@ -64,10 +62,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -165,7 +159,6 @@ Fail if there are too many temporaries.</p>
|
|||||||
</div>
|
</div>
|
||||||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
||||||
<a href="Lib.LinearCode.html" class="btn btn-neutral float-left" title="Lib.LinearCode module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
<a href="Lib.LinearCode.html" class="btn btn-neutral float-left" title="Lib.LinearCode module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
||||||
<a href="Lib.CFG.html" class="btn btn-neutral float-right" title="Lib.CFG module" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@ -1,375 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html class="writer-html5" lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
|
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Lib.CFG module — MiniC documentation</title>
|
|
||||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="../_static/js/html5shiv.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
||||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
|
||||||
<script src="../_static/doctools.js"></script>
|
|
||||||
<script src="../_static/sphinx_highlight.js"></script>
|
|
||||||
<script src="../_static/js/theme.js"></script>
|
|
||||||
<link rel="index" title="Index" href="../genindex.html" />
|
|
||||||
<link rel="search" title="Search" href="../search.html" />
|
|
||||||
<link rel="next" title="Lib.Terminator module" href="Lib.Terminator.html" />
|
|
||||||
<link rel="prev" title="Lib.Allocator module" href="Lib.Allocator.html" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="wy-body-for-nav">
|
|
||||||
<div class="wy-grid-for-nav">
|
|
||||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
||||||
<div class="wy-side-scroll">
|
|
||||||
<div class="wy-side-nav-search" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="../index.html" class="icon icon-home">
|
|
||||||
MiniC
|
|
||||||
</a>
|
|
||||||
<div role="search">
|
|
||||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
|
||||||
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
|
||||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
|
||||||
<ul class="current">
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Errors.html">Base library - Errors</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Statement.html">Base library - Statement</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Operands.html">Base library - Operands</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.FunctionData.html">Base library - Function data</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.LinearCode.html">Linear intermediate representation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Allocator.html">Temporary allocation</a></li>
|
|
||||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Control Flow Graph - CFG and Basic blocks</a><ul>
|
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#Lib.CFG.Block"><code class="docutils literal notranslate"><span class="pre">Block</span></code></a><ul>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.to_dot"><code class="docutils literal notranslate"><span class="pre">Block.to_dot()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.get_body"><code class="docutils literal notranslate"><span class="pre">Block.get_body()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.get_all_statements"><code class="docutils literal notranslate"><span class="pre">Block.get_all_statements()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.get_body_and_terminator"><code class="docutils literal notranslate"><span class="pre">Block.get_body_and_terminator()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.get_label"><code class="docutils literal notranslate"><span class="pre">Block.get_label()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.get_in"><code class="docutils literal notranslate"><span class="pre">Block.get_in()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.get_terminator"><code class="docutils literal notranslate"><span class="pre">Block.get_terminator()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.set_terminator"><code class="docutils literal notranslate"><span class="pre">Block.set_terminator()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.get_phis"><code class="docutils literal notranslate"><span class="pre">Block.get_phis()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.add_phi"><code class="docutils literal notranslate"><span class="pre">Block.add_phi()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.set_phis"><code class="docutils literal notranslate"><span class="pre">Block.set_phis()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.remove_all_phis"><code class="docutils literal notranslate"><span class="pre">Block.remove_all_phis()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.iter_statements"><code class="docutils literal notranslate"><span class="pre">Block.iter_statements()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.Block.add_instruction"><code class="docutils literal notranslate"><span class="pre">Block.add_instruction()</span></code></a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#Lib.CFG.CFG"><code class="docutils literal notranslate"><span class="pre">CFG</span></code></a><ul>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.fdata"><code class="docutils literal notranslate"><span class="pre">CFG.fdata</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.get_start"><code class="docutils literal notranslate"><span class="pre">CFG.get_start()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.set_start"><code class="docutils literal notranslate"><span class="pre">CFG.set_start()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.get_end"><code class="docutils literal notranslate"><span class="pre">CFG.get_end()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.add_block"><code class="docutils literal notranslate"><span class="pre">CFG.add_block()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.get_block"><code class="docutils literal notranslate"><span class="pre">CFG.get_block()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.get_blocks"><code class="docutils literal notranslate"><span class="pre">CFG.get_blocks()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.get_entries"><code class="docutils literal notranslate"><span class="pre">CFG.get_entries()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.add_edge"><code class="docutils literal notranslate"><span class="pre">CFG.add_edge()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.remove_edge"><code class="docutils literal notranslate"><span class="pre">CFG.remove_edge()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.out_blocks"><code class="docutils literal notranslate"><span class="pre">CFG.out_blocks()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.gather_defs"><code class="docutils literal notranslate"><span class="pre">CFG.gather_defs()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.iter_statements"><code class="docutils literal notranslate"><span class="pre">CFG.iter_statements()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.linearize_naive"><code class="docutils literal notranslate"><span class="pre">CFG.linearize_naive()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.print_code"><code class="docutils literal notranslate"><span class="pre">CFG.print_code()</span></code></a></li>
|
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#Lib.CFG.CFG.print_dot"><code class="docutils literal notranslate"><span class="pre">CFG.print_dot()</span></code></a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Dominators.html">SSA form - Dominance frontier</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
|
||||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
||||||
<a href="../index.html">MiniC</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="wy-nav-content">
|
|
||||||
<div class="rst-content">
|
|
||||||
<div role="navigation" aria-label="Page navigation">
|
|
||||||
<ul class="wy-breadcrumbs">
|
|
||||||
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
|
|
||||||
<li class="breadcrumb-item active">Lib.CFG module</li>
|
|
||||||
<li class="wy-breadcrumbs-aside">
|
|
||||||
<a href="../_sources/api/Lib.CFG.rst.txt" rel="nofollow"> View page source</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
<div itemprop="articleBody">
|
|
||||||
|
|
||||||
<section id="module-Lib.CFG">
|
|
||||||
<span id="lib-cfg-module"></span><h1>Lib.CFG module<a class="headerlink" href="#module-Lib.CFG" title="Permalink to this heading"></a></h1>
|
|
||||||
<p>Classes for a RiscV CFG: <a class="reference internal" href="#Lib.CFG.CFG" title="Lib.CFG.CFG"><code class="xref py py-class docutils literal notranslate"><span class="pre">CFG</span></code></a> for the CFG itself,
|
|
||||||
and <a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><code class="xref py py-class docutils literal notranslate"><span class="pre">Block</span></code></a> for its basic blocks.</p>
|
|
||||||
<dl class="py class">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block">
|
|
||||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.CFG.</span></span><span class="sig-name descname"><span class="pre">Block</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">label</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Label</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">insts</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Instru3A" title="Lib.Statement.Instru3A"><span class="pre">Instru3A</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Comment" title="Lib.Statement.Comment"><span class="pre">Comment</span></a><span class="p"><span class="pre">]</span></span></span></em>, <em class="sig-param"><span class="n"><span class="pre">terminator</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Terminator.html#Lib.Terminator.Return" title="Lib.Terminator.Return"><span class="pre">Return</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.AbsoluteJump" title="Lib.Statement.AbsoluteJump"><span class="pre">AbsoluteJump</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Terminator.html#Lib.Terminator.BranchingTerminator" title="Lib.Terminator.BranchingTerminator"><span class="pre">BranchingTerminator</span></a></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/CFG.html#Block"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
|
|
||||||
<p>A basic block of a <a class="reference internal" href="#Lib.CFG.CFG" title="Lib.CFG.CFG"><code class="xref py py-class docutils literal notranslate"><span class="pre">CFG</span></code></a> is made of three main parts:</p>
|
|
||||||
<ul class="simple">
|
|
||||||
<li><p>a start <a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><code class="xref py py-class docutils literal notranslate"><span class="pre">label</span></code></a> that uniquely identifies the block in the CFG</p></li>
|
|
||||||
<li><p>the main body of the block, a list of instructions
|
|
||||||
(excluding labels, jumps and branching instructions)</p></li>
|
|
||||||
<li><p>a <a class="reference internal" href="Lib.Terminator.html#Lib.Terminator.Terminator" title="Lib.Terminator.Terminator"><code class="xref py py-class docutils literal notranslate"><span class="pre">terminator</span></code></a>
|
|
||||||
that represents the final jump or branching instruction of the block,
|
|
||||||
and points to the successors of the block.
|
|
||||||
See the documentation for <a class="reference internal" href="Lib.Terminator.html#Lib.Terminator.Terminator" title="Lib.Terminator.Terminator"><code class="xref py py-class docutils literal notranslate"><span class="pre">Lib.Terminator.Terminator</span></code></a> for further explanations.</p></li>
|
|
||||||
</ul>
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.to_dot">
|
|
||||||
<span class="sig-name descname"><span class="pre">to_dot</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">str</span></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#Block.to_dot"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.to_dot" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Outputs all statements of the block as a string.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.get_body">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_body</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.Instru3A" title="Lib.Statement.Instru3A"><span class="pre">Instru3A</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Comment" title="Lib.Statement.Comment"><span class="pre">Comment</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#Block.get_body"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.get_body" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return the statements in the body of the block (no phi-node nor the terminator).</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.get_all_statements">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_all_statements</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_all_statements"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.get_all_statements" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return all statements of the block
|
|
||||||
(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>
|
|
||||||
<dd><p>Return the label of the block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.get_in">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_in</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.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#Block.get_in"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.get_in" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return the list of blocks with an edge to the considered block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.get_terminator">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_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"><a class="reference internal" href="Lib.Terminator.html#Lib.Terminator.Return" title="Lib.Terminator.Return"><span class="pre">Return</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.AbsoluteJump" title="Lib.Statement.AbsoluteJump"><span class="pre">AbsoluteJump</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Terminator.html#Lib.Terminator.BranchingTerminator" title="Lib.Terminator.BranchingTerminator"><span class="pre">BranchingTerminator</span></a></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#Block.get_terminator"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.get_terminator" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return the terminator of the block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.set_terminator">
|
|
||||||
<span class="sig-name descname"><span class="pre">set_terminator</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">term</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Terminator.html#Lib.Terminator.Return" title="Lib.Terminator.Return"><span class="pre">Return</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.AbsoluteJump" title="Lib.Statement.AbsoluteJump"><span class="pre">AbsoluteJump</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Terminator.html#Lib.Terminator.BranchingTerminator" title="Lib.Terminator.BranchingTerminator"><span class="pre">BranchingTerminator</span></a></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/CFG.html#Block.set_terminator"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.set_terminator" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Set the terminator of the block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.get_phis">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_phis</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_phis"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.get_phis" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return the list of all φ instructions of the block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.add_phi">
|
|
||||||
<span class="sig-name descname"><span class="pre">add_phi</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">phi</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Statement" title="Lib.Statement.Statement"><span class="pre">Statement</span></a></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/CFG.html#Block.add_phi"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.add_phi" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Add a φ instruction to the block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.set_phis">
|
|
||||||
<span class="sig-name descname"><span class="pre">set_phis</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">phis</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><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></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/CFG.html#Block.set_phis"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.set_phis" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Replace the φ instructions in the block by the given list <cite>phis</cite>.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.remove_all_phis">
|
|
||||||
<span class="sig-name descname"><span class="pre">remove_all_phis</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">None</span></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#Block.remove_all_phis"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.remove_all_phis" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Remove all φ instructions in the block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.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/CFG.html#Block.iter_statements"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.iter_statements" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Iterate over instructions.
|
|
||||||
For each real instruction i (not label or comment), replace it
|
|
||||||
with the list of instructions given by f(i).</p>
|
|
||||||
<p>Assume there is no phi-node.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.Block.add_instruction">
|
|
||||||
<span class="sig-name descname"><span class="pre">add_instruction</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">instr</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Instru3A" title="Lib.Statement.Instru3A"><span class="pre">Instru3A</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Comment" title="Lib.Statement.Comment"><span class="pre">Comment</span></a></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/CFG.html#Block.add_instruction"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.Block.add_instruction" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Add an instruction to the body of the block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py class">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG">
|
|
||||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.CFG.</span></span><span class="sig-name descname"><span class="pre">CFG</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">fdata</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.FunctionData.html#Lib.FunctionData.FunctionData" title="Lib.FunctionData.FunctionData"><span class="pre">FunctionData</span></a></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/CFG.html#CFG"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
|
|
||||||
<p>A complete control-flow graph representing a function.
|
|
||||||
This class is mainly made of a list of basic <a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><code class="xref py py-class docutils literal notranslate"><span class="pre">Block</span></code></a>,
|
|
||||||
a label indicating the <a class="reference internal" href="#Lib.CFG.CFG.get_start" title="Lib.CFG.CFG.get_start"><code class="xref py py-meth docutils literal notranslate"><span class="pre">entry</span> <span class="pre">point</span> <span class="pre">of</span> <span class="pre">the</span> <span class="pre">function</span></code></a>,
|
|
||||||
and an <a class="reference internal" href="#Lib.CFG.CFG.get_end" title="Lib.CFG.CFG.get_end"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exit</span> <span class="pre">label</span></code></a>.</p>
|
|
||||||
<p>As with linear code, metadata about the function can be found
|
|
||||||
in the <a class="reference internal" href="#Lib.CFG.CFG.fdata" title="Lib.CFG.CFG.fdata"><code class="xref py py-attr docutils literal notranslate"><span class="pre">fdata</span></code></a> member variable.</p>
|
|
||||||
<dl class="py attribute">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.fdata">
|
|
||||||
<span class="sig-name descname"><span class="pre">fdata</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><a class="reference internal" href="Lib.FunctionData.html#Lib.FunctionData.FunctionData" title="Lib.FunctionData.FunctionData"><span class="pre">FunctionData</span></a></em><a class="headerlink" href="#Lib.CFG.CFG.fdata" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Metadata about the function represented by this CFG</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.get_start">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_start</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#CFG.get_start"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.get_start" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return the entry label of the CFG.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.set_start">
|
|
||||||
<span class="sig-name descname"><span class="pre">set_start</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">start</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Label</span></a></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/CFG.html#CFG.set_start"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.set_start" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Set the entry label of the CFG.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.get_end">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_end</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#CFG.get_end"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.get_end" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return the exit label of the CFG.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.add_block">
|
|
||||||
<span class="sig-name descname"><span class="pre">add_block</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">blk</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a></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/CFG.html#CFG.add_block"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.add_block" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Add a new block to the CFG.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.get_block">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_block</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Label</span></a></span></em><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.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#CFG.get_block"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.get_block" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return the block with label <cite>name</cite>.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.get_blocks">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_blocks</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.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#CFG.get_blocks"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.get_blocks" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return all the blocks.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.get_entries">
|
|
||||||
<span class="sig-name descname"><span class="pre">get_entries</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.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#CFG.get_entries"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.get_entries" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return all the blocks with no predecessors.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.add_edge">
|
|
||||||
<span class="sig-name descname"><span class="pre">add_edge</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">src</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">dest</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a></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/CFG.html#CFG.add_edge"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.add_edge" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Add the edge src -> dest in the control flow graph.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.remove_edge">
|
|
||||||
<span class="sig-name descname"><span class="pre">remove_edge</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">src</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">dest</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a></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/CFG.html#CFG.remove_edge"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.remove_edge" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Remove the edge src -> dest in the control flow graph.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.out_blocks">
|
|
||||||
<span class="sig-name descname"><span class="pre">out_blocks</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">block</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a></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">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/CFG.html#CFG.out_blocks"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.out_blocks" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return the list of blocks in the CFG targeted by
|
|
||||||
the Terminator of Block block.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.gather_defs">
|
|
||||||
<span class="sig-name descname"><span class="pre">gather_defs</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">Dict</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><a class="reference internal" href="#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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/CFG.html#CFG.gather_defs"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.gather_defs" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Return a dictionary associating variables to all the blocks
|
|
||||||
containing one of their definitions.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.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/CFG.html#CFG.iter_statements"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.iter_statements" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Apply f to all instructions in all the blocks.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.linearize_naive">
|
|
||||||
<span class="sig-name descname"><span class="pre">linearize_naive</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">Iterator</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#CFG.linearize_naive"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.linearize_naive" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Linearize the given control flow graph as a list of instructions.
|
|
||||||
Naive procedure that adds jumps everywhere.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.print_code">
|
|
||||||
<span class="sig-name descname"><span class="pre">print_code</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">output</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">linearize=<function</span> <span class="pre">CFG.<lambda>></span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comment=None</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/CFG.html#CFG.print_code"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.print_code" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Print the linearization of the CFG.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py method">
|
|
||||||
<dt class="sig sig-object py" id="Lib.CFG.CFG.print_dot">
|
|
||||||
<span class="sig-name descname"><span class="pre">print_dot</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">filename</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">DF</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">view</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</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/CFG.html#CFG.print_dot"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.CFG.CFG.print_dot" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Print the CFG as a graph.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
|
||||||
<a href="Lib.Allocator.html" class="btn btn-neutral float-left" title="Lib.Allocator module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
|
||||||
<a href="Lib.Terminator.html" class="btn btn-neutral float-right" title="Lib.Terminator module" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<div role="contentinfo">
|
|
||||||
<p>© Copyright 2023, compil-lyon.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
|
||||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
|
||||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
|
||||||
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
jQuery(function () {
|
|
||||||
SphinxRtdTheme.Navigation.enable(true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,161 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html class="writer-html5" lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
|
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Lib.Dominators module — MiniC documentation</title>
|
|
||||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="../_static/js/html5shiv.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
||||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
|
||||||
<script src="../_static/doctools.js"></script>
|
|
||||||
<script src="../_static/sphinx_highlight.js"></script>
|
|
||||||
<script src="../_static/js/theme.js"></script>
|
|
||||||
<link rel="index" title="Index" href="../genindex.html" />
|
|
||||||
<link rel="search" title="Search" href="../search.html" />
|
|
||||||
<link rel="next" title="Lib.PhiNode module" href="Lib.PhiNode.html" />
|
|
||||||
<link rel="prev" title="Lib.Terminator module" href="Lib.Terminator.html" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="wy-body-for-nav">
|
|
||||||
<div class="wy-grid-for-nav">
|
|
||||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
||||||
<div class="wy-side-scroll">
|
|
||||||
<div class="wy-side-nav-search" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="../index.html" class="icon icon-home">
|
|
||||||
MiniC
|
|
||||||
</a>
|
|
||||||
<div role="search">
|
|
||||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
|
||||||
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
|
||||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
|
||||||
<ul class="current">
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Errors.html">Base library - Errors</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Statement.html">Base library - Statement</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Operands.html">Base library - Operands</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.FunctionData.html">Base library - Function data</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Graphes.html">Base library - Graphs</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.LinearCode.html">Linear intermediate representation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Allocator.html">Temporary allocation</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.CFG.html">Control Flow Graph - CFG and Basic blocks</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Terminator.html">Control Flow Graph - Terminators</a></li>
|
|
||||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">SSA form - Dominance frontier</a><ul>
|
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#Lib.Dominators.computeDom"><code class="docutils literal notranslate"><span class="pre">computeDom()</span></code></a></li>
|
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#Lib.Dominators.printDT"><code class="docutils literal notranslate"><span class="pre">printDT()</span></code></a></li>
|
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#Lib.Dominators.computeDT"><code class="docutils literal notranslate"><span class="pre">computeDT()</span></code></a></li>
|
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#Lib.Dominators.computeDF"><code class="docutils literal notranslate"><span class="pre">computeDF()</span></code></a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Lib.PhiNode.html">SSA form - Phi Nodes</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
|
||||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
||||||
<a href="../index.html">MiniC</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="wy-nav-content">
|
|
||||||
<div class="rst-content">
|
|
||||||
<div role="navigation" aria-label="Page navigation">
|
|
||||||
<ul class="wy-breadcrumbs">
|
|
||||||
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
|
|
||||||
<li class="breadcrumb-item active">Lib.Dominators module</li>
|
|
||||||
<li class="wy-breadcrumbs-aside">
|
|
||||||
<a href="../_sources/api/Lib.Dominators.rst.txt" rel="nofollow"> View page source</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
||||||
<div itemprop="articleBody">
|
|
||||||
|
|
||||||
<section id="module-Lib.Dominators">
|
|
||||||
<span id="lib-dominators-module"></span><h1>Lib.Dominators module<a class="headerlink" href="#module-Lib.Dominators" title="Permalink to this heading"></a></h1>
|
|
||||||
<p>Utility functions to work with dominators in a <a class="reference internal" href="Lib.CFG.html#Lib.CFG.CFG" title="Lib.CFG.CFG"><code class="xref py py-class docutils literal notranslate"><span class="pre">CFG</span></code></a>.</p>
|
|
||||||
<p>Do not hesitate to look at the source of the functions
|
|
||||||
to get a better understanding of the algorithms.</p>
|
|
||||||
<dl class="py function">
|
|
||||||
<dt class="sig sig-object py" id="Lib.Dominators.computeDom">
|
|
||||||
<span class="sig-prename descclassname"><span class="pre">Lib.Dominators.</span></span><span class="sig-name descname"><span class="pre">computeDom</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cfg</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.CFG.html#Lib.CFG.CFG" title="Lib.CFG.CFG"><span class="pre">CFG</span></a></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">Dict</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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/Dominators.html#computeDom"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Dominators.computeDom" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p><cite>computeDom(cfg)</cite> computes the table associating blocks to their
|
|
||||||
dominators in <cite>cfg</cite>.
|
|
||||||
It works by solving the equation system.</p>
|
|
||||||
<p>This is an helper function called during SSA entry.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py function">
|
|
||||||
<dt class="sig sig-object py" id="Lib.Dominators.printDT">
|
|
||||||
<span class="sig-prename descclassname"><span class="pre">Lib.Dominators.</span></span><span class="sig-name descname"><span class="pre">printDT</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">filename</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">graph</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></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/Dominators.html#printDT"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Dominators.printDT" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p>Display a graphical rendering of the given domination tree.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py function">
|
|
||||||
<dt class="sig sig-object py" id="Lib.Dominators.computeDT">
|
|
||||||
<span class="sig-prename descclassname"><span class="pre">Lib.Dominators.</span></span><span class="sig-name descname"><span class="pre">computeDT</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cfg</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.CFG.html#Lib.CFG.CFG" title="Lib.CFG.CFG"><span class="pre">CFG</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">dominators</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span></em>, <em class="sig-param"><span class="n"><span class="pre">dom_graphs</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">basename</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</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">Dict</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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/Dominators.html#computeDT"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Dominators.computeDT" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p><cite>computeDT(cfg, dominators)</cite> computes the domination tree of <cite>cfg</cite>
|
|
||||||
using the previously computed <cite>dominators</cite>.
|
|
||||||
It returns <cite>DT</cite>, a dictionary which associates a block with its children
|
|
||||||
in the dominator tree.</p>
|
|
||||||
<p>This is an helper function called during SSA entry.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
<dl class="py function">
|
|
||||||
<dt class="sig sig-object py" id="Lib.Dominators.computeDF">
|
|
||||||
<span class="sig-prename descclassname"><span class="pre">Lib.Dominators.</span></span><span class="sig-name descname"><span class="pre">computeDF</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cfg</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.CFG.html#Lib.CFG.CFG" title="Lib.CFG.CFG"><span class="pre">CFG</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">dominators</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span></em>, <em class="sig-param"><span class="n"><span class="pre">DT</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span></em>, <em class="sig-param"><span class="n"><span class="pre">dom_graphs</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">basename</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</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">Dict</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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><a class="reference internal" href="Lib.CFG.html#Lib.CFG.Block" title="Lib.CFG.Block"><span class="pre">Block</span></a><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/Dominators.html#computeDF"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Dominators.computeDF" title="Permalink to this definition"></a></dt>
|
|
||||||
<dd><p><cite>computeDF(…)</cite> computes the dominance frontier of a CFG.
|
|
||||||
It returns <cite>DF</cite> which associates a block to its frontier.</p>
|
|
||||||
<p>This is an helper function called during SSA entry.</p>
|
|
||||||
</dd></dl>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
|
||||||
<a href="Lib.Terminator.html" class="btn btn-neutral float-left" title="Lib.Terminator module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
|
||||||
<a href="Lib.PhiNode.html" class="btn btn-neutral float-right" title="Lib.PhiNode module" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<div role="contentinfo">
|
|
||||||
<p>© Copyright 2023, compil-lyon.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
|
||||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
|
||||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
|
||||||
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
jQuery(function () {
|
|
||||||
SphinxRtdTheme.Navigation.enable(true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user