Mon commit avec mes modifs à moi ! Na

This commit is contained in:
2022-10-26 11:51:37 +02:00
parent 52ce1488c5
commit 62d045512a
62 changed files with 2342 additions and 77 deletions
+3 -1
View File
@@ -86,7 +86,9 @@ define CLEAN
import glob
import os
for f in glob.glob("**/tests/**/*.c", recursive=True):
for s in ("{}-{}.s".format(f[:-2], test) for test in ("naive", "smart", "gcc", "all-in-mem")):
files = ["{}-{}.{}".format(f[:-2], test,ext) for test in ("naive", "smart", "gcc", "all-in-mem") for ext in ("s","riscv","pdf")]
files += ["{}.{}.{}.{}".format(f[:-2], funct, test,ext for funct in ("main") for test in ("enterssa","exitssa") for ext in ("dot.pdf","dot")
for s in files:
try:
os.remove(s)
print("Removed {}".format(s))
+1 -1
View File
@@ -52,7 +52,7 @@ print_stat
expr
: MINUS expr #unaryMinusExpr
| NOT expr #notExpr
| expr myop=(MULT|DIV|MOD) expr #multiplicativeExpr
| 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
+34 -25
View File
@@ -3,23 +3,32 @@ LAB4 (simple code generation), MIF08 / CAP 2022-23
# Authors
YOUR NAME HERE
Samy Avrillon
# Contents
TODO for STUDENTS : Say a bit about the code infrastructure ...
Same as the first lab, you did the structure, so i have litle interest in commenting it.
# Test design
TODO: explain your tests
- folder *operators* checks all operations on operators (additive, multiplicative, relations, unary minus, boolean)
- *nested{While,For,Ifs}* checks with structures of nested blocks.
- *forTests* and *whileClauseSyntax* tests for the well-execution of for and while loops.
- *testTooManyVariables* tries initializing many variables in order to make the naive allocator fail.
# Design choices
TODO: explain your choices. How did you implement boolean not? Did you implement an extension?
Boolean Not has been implemented using an immediate 1 and the opreator xor, even though such operator exists in riscV (see Known bugs).
I did implement C-like loops with the same system used in the interpreter.
# Known bugs
TODO: Bugs and limitations.
There is a lot of RiscV instruction that are not implemented in Lib, and that makes bigger and less readable code (for exemple, slt would be better than blt for integer comparison).
By design, we always use a jump statement before a label. Otherwise, the CFG linearization fails. This is intended (the missing jump could be added in *prepare_chunk*).
So, there is one line in *BuildCFG.c* that sould never be executed (that's why the coverage is not 100% complete), when a label is detected as a leader, as the preceding jump will always have been detected as a leader before it.
# Checklists
@@ -28,30 +37,30 @@ and *tested* with appropriate test cases.
## Code generation
- [ ] Number Atom
- [ ] Boolean Atom
- [ ] Id Atom
- [ ] Additive expression
- [ ] Multiplicative expression
- [ ] UnaryMinus expression
- [ ] Or expression
- [ ] And expression
- [ ] Equality expression
- [ ] Relational expression (! many cases -> many tests)
- [ ] Not expression
- [X] Number Atom
- [X] Boolean Atom
- [X] Id Atom
- [X] Additive expression
- [X] Multiplicative expression
- [X] UnaryMinus expression
- [X] Or expression
- [X] And expression
- [X] Equality expression
- [X] Relational expression (! many cases -> many tests)
- [X] Not expression
## Statements
- [ ] Prog, assignements
- [ ] While
- [ ] Cond Block
- [ ] If
- [ ] Nested ifs
- [ ] Nested whiles
- [X] Prog, assignements
- [X] While
- [X] Cond Block
- [X] If
- [X] Nested ifs
- [X] Nested whiles
## Allocation
- [ ] Naive allocation
- [ ] All in memory allocation
- [ ] Massive tests of memory allocation
- [X] Naive allocation
- [X] All in memory allocation
- [X] Massive tests of memory allocation
+6 -6
View File
@@ -110,7 +110,7 @@ class MiniCTypingVisitor(MiniCVisitor):
else:
self._raise(ctx,"boolean operator", fstT)
else:
self._assertSameType(ctx,"boolean operator", fstT,sndT)
self._raise(ctx,"boolean operator", fstT,sndT)
def visitAndExpr(self, ctx):
fstT = self.visit(ctx.expr(0))
@@ -121,7 +121,7 @@ class MiniCTypingVisitor(MiniCVisitor):
else:
self._raise(ctx,"boolean operator", fstT)
else:
self._assertSameType(ctx,"boolean operator", fstT,sndT)
self._raise(ctx,"boolean operator", fstT,sndT)
def visitEqualityExpr(self, ctx):
fstT = self.visit(ctx.expr(0))
@@ -140,7 +140,7 @@ class MiniCTypingVisitor(MiniCVisitor):
else:
self._raise(ctx, "comparaison operator", fstT)
else:
self._assertSameType(ctx,"comparaison operator", fstT,sndT)
self._raise(ctx,"comparaison operator", fstT,sndT)
def visitAdditiveExpr(self, ctx):
assert ctx.myop is not None
@@ -152,9 +152,9 @@ class MiniCTypingVisitor(MiniCVisitor):
elif (fstT == BaseType.String and ctx.myop.type == MiniCParser.PLUS):
return BaseType.String
else:
self._raise(ctx, "additive operands", fstT)
self._raise(ctx, "additive operands", fstT,sndT)
else:
self._assertSameType(ctx,"additive operator", fstT,sndT)
self._raise(ctx,"additive operator", fstT,sndT)
def visitMultiplicativeExpr(self, ctx):
fstT = self.visit(ctx.expr(0))
@@ -165,7 +165,7 @@ class MiniCTypingVisitor(MiniCVisitor):
else:
return fstT
else:
self._assertSameType(ctx,"multiplicative operator", fstT,sndT)
self._raise(ctx,"multiplicative operands", fstT,sndT)
def visitNotExpr(self, ctx):
fstT = self.visit(ctx.expr())
@@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 6: type mismatch for multiplicative operator: integer and string
// In function main: Line 8 col 6: invalid type for multiplicative operands: integer and string
@@ -6,4 +6,4 @@ int main(){
}
// EXITCODE 2
// EXPECTED
// In function main: Line 4 col 14: invalid type for additive operands: boolean
// In function main: Line 4 col 14: invalid type for additive operands: boolean and boolean
@@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 12: type mismatch for additive operator: integer and boolean
// In function main: Line 6 col 12: invalid type for additive operator: integer and boolean
@@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: invalid type for additive operands: boolean
// In function main: Line 8 col 8: invalid type for additive operands: boolean and boolean
@@ -13,4 +13,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 10 col 8: type mismatch for additive operator: integer and float
// In function main: Line 10 col 8: invalid type for additive operator: integer and float
@@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: type mismatch for boolean operator: integer and boolean
// In function main: Line 8 col 8: invalid type for boolean operator: integer and boolean
@@ -19,4 +19,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 16 col 8: type mismatch for comparaison operator: integer and float
// In function main: Line 16 col 8: invalid type for comparaison operator: integer and float
@@ -13,4 +13,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 10 col 8: type mismatch for multiplicative operator: integer and float
// In function main: Line 10 col 8: invalid type for multiplicative operands: integer and float
@@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: type mismatch for boolean operator: integer and boolean
// In function main: Line 8 col 8: invalid type for boolean operator: integer and boolean
+21 -1
View File
@@ -14,12 +14,32 @@ class AllInMemAllocator(Allocator):
before: List[Instruction] = []
after: List[Instruction] = []
subst: Dict[Operand, Operand] = {}
old_args = old_instr.args()
for arg in old_args:
# We substitute
subst[arg] = S[numreg]
numreg += 1
for arg in old_instr.used():
# We have to read them from memory
if(isinstance(arg, Temporary)):
before.append(RiscV.ld(subst[arg],self._fdata._pool.get_alloced_loc(arg)))
for arg in old_instr.defined():
# We have to write them after to memory
if(isinstance(arg, Temporary)):
after.append(RiscV.sd(subst[arg],self._fdata._pool.get_alloced_loc(arg)))
# TODO (Exercise 7): compute before,after,args.
# TODO (Exercise 7): iterate over old_args, check which argument
# TODO (Exercise 7): is a temporary (e.g. isinstance(..., Temporary)),
# TODO (Exercise 7): and if so, generate ld/sd accordingly. Replace the
# TODO (Exercise 7): temporary with S[1], S[2] or S[3] physical registers.
new_instr = old_instr.substitute(subst)
try:
new_instr = old_instr.substitute(subst)
except Exception:
# We have an instruction that doesn't need substitution
return [old_instr]
return before + [new_instr] + after
def prepare(self):
+20 -3
View File
@@ -20,7 +20,14 @@ def find_leaders(instructions: List[CodeStatement]) -> List[int]:
last is len(instructions)
"""
leaders: List[int] = [0]
# TODO fill leaders (Lab4b, Exercise 3)
for i in range(1,len(instructions)):
if(isinstance(instructions[i],AbsoluteJump) or isinstance(instructions[i],ConditionalJump)):
# The block ends here and starts just after
leaders.append(i+1)
elif isinstance(instructions[i],Label) and leaders[-1] != i:
# The block starts here
leaders.append(i)
# Else, ignore
# The final "ret" is also a form of jump
leaders.append(len(instructions))
return leaders
@@ -64,9 +71,19 @@ def prepare_chunk(pre_chunk: List[CodeStatement], fdata: FunctionData) -> tuple[
jump = None
inner_statements: List[CodeStatement] = pre_chunk
# Extract the first instruction from inner_statements if it is a label, or create a fresh one
raise NotImplementedError() # TODO (Lab4b, Exercise 3)
firstStat = inner_statements.pop(0)
if(isinstance(firstStat, Label)):
label = firstStat
else:
inner_statements = [firstStat]+inner_statements
label = fdata.fresh_label(fdata._name)
# Extract the last instruction from inner_statements if it is a jump, or do nothing
raise NotImplementedError() # TODO (Lab4b, Exercise 3)
if(inner_statements != []):
lastStat = inner_statements.pop()
if(isinstance(lastStat, ConditionalJump) or isinstance(lastStat, AbsoluteJump)):
jump = lastStat
else:
inner_statements += [lastStat]
# Check that there is no other label or jump left in inner_statements
l: List[BlockInstr] = []
for i in inner_statements:
+24 -2
View File
@@ -23,10 +23,32 @@ def linearize(cfg) -> List[Statement]:
"""
Linearize the given control flow graph as a list of instructions.
"""
# TODO (Lab 4b, Exercise 5)
l: List[Statement] = [] # Linearized CFG
blocks: List[Block] = ordered_blocks_list(cfg)
for j, block in enumerate(blocks):
labdict = {}
# We make the label dictionary
for j,block in enumerate(blocks):
labdict[block.get_label()] = block
while blocks != []:
block = blocks[0]
if(l != [] and isinstance(l[-1],AbsoluteJump)):
ll : AbsoluteJump = l[-1]
# We try to find the next jump according to that.
try:
# If we find the instruction
b = labdict[ll.label]
if b in blocks:
# We remove the jump instruction and we select the block to use
l.pop()
block = b
except KeyError:
pass
# We remove the block we used
blocks.remove(block)
# 1. Add the label of the block to the linearization
l.append(block.get_label())
# 2. Add the body of the block to the linearization
+148 -12
View File
@@ -75,7 +75,13 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
# true is 1 false is 0
raise NotImplementedError() # TODO (Exercise 5)
dtemp = self._current_function.fdata.fresh_tmp()
if(ctx.getText() == "true"):
val = Operands.Immediate(1)
else:
val = Operands.Immediate(0)
self._current_function.add_instruction(RiscV.li(dtemp,val))
return dtemp
def visitIdAtom(self, ctx) -> Operands.Temporary:
try:
@@ -97,13 +103,52 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
def visitAdditiveExpr(self, ctx) -> Operands.Temporary:
assert ctx.myop is not None
raise NotImplementedError() # TODO (Exercise 2)
if self._debug:
print("additive expression, between:",
Trees.toStringTree(ctx.expr(0), None, self._parser),
"and",
Trees.toStringTree(ctx.expr(1), None, self._parser))
ltemp = self.visit(ctx.expr(0))
rtemp = self.visit(ctx.expr(1))
# Getting a fresh temporary for the result of the opreation
dtemp = self._current_function.fdata.fresh_tmp()
if(ctx.myop.type==MiniCParser.PLUS):
self._current_function.add_instruction(RiscV.add(dtemp,ltemp,rtemp))
elif(ctx.myop.type==MiniCParser.MINUS):
self._current_function.add_instruction(RiscV.sub(dtemp,ltemp,rtemp))
else:
raise MiniCInternalError("Unknown additive operator from the parser:",ctx.myop)
return dtemp
def visitOrExpr(self, ctx) -> Operands.Temporary:
raise NotImplementedError() # TODO (Exercise 5)
if self._debug:
print("or expression, between:",
Trees.toStringTree(ctx.expr(0), None, self._parser),
"and",
Trees.toStringTree(ctx.expr(1), None, self._parser))
ltemp = self.visit(ctx.expr(0))
rtemp = self.visit(ctx.expr(1))
# Getting a fresh temporary for the result of the opreation
# We could do only two instructions with slt
d0temp = self._current_function.fdata.fresh_tmp()
d1temp = self._current_function.fdata.fresh_tmp()
self._current_function.add_instruction(RiscV.add(d0temp,ltemp,rtemp))
self._current_function.add_instruction(RiscV.mul(d1temp,ltemp,rtemp))
self._current_function.add_instruction(RiscV.sub(d0temp,d0temp,d1temp))
return d0temp
def visitAndExpr(self, ctx) -> Operands.Temporary:
raise NotImplementedError() # TODO (Exercise 5)
if self._debug:
print("or expression, between:",
Trees.toStringTree(ctx.expr(0), None, self._parser),
"and",
Trees.toStringTree(ctx.expr(1), None, self._parser))
ltemp = self.visit(ctx.expr(0))
rtemp = self.visit(ctx.expr(1))
# Getting a fresh temporary for the result of the opreation
dtemp = self._current_function.fdata.fresh_tmp()
self._current_function.add_instruction(RiscV.mul(dtemp,ltemp,rtemp))
return dtemp
def visitEqualityExpr(self, ctx) -> Operands.Temporary:
return self.visitRelationalExpr(ctx)
@@ -115,18 +160,63 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
print("relational expression:")
print(Trees.toStringTree(ctx, None, self._parser))
print("Condition:", c)
raise NotImplementedError() # TODO (Exercise 5)
ltemp = self.visit(ctx.expr(0))
rtemp = self.visit(ctx.expr(1))
# Getting a fresh temporary for the result of the opreation
dtemp = self._current_function.fdata.fresh_tmp()
endlabel = self._current_function.fdata.fresh_label("ifverified")
self._current_function.add_instruction(RiscV.li(dtemp,Operands.Immediate(1)))
self._current_function.add_comment("If the result of the comparison is true, branch")
self._current_function.add_instruction(RiscV.conditional_jump(endlabel,ltemp,Operands.Condition(ctx.myop.type),rtemp))
self._current_function.add_instruction(RiscV.li(dtemp,Operands.Immediate(0)))
self._current_function.add_instruction(RiscV.jump(endlabel))
self._current_function.add_label(endlabel)
return dtemp
def visitMultiplicativeExpr(self, ctx) -> Operands.Temporary:
assert ctx.myop is not None
div_by_zero_lbl = self._current_function.fdata.get_label_div_by_zero()
raise NotImplementedError() # TODO (Exercise 8)
ltemp = self.visit(ctx.expr(0))
rtemp = self.visit(ctx.expr(1))
# Getting a fresh temporary for the result of the opreation
dtemp = self._current_function.fdata.fresh_tmp()
if(ctx.myop.type==MiniCParser.MULT):
self._current_function.add_instruction(RiscV.mul(dtemp,ltemp,rtemp))
else:
self._current_function.add_instruction(RiscV.conditional_jump(div_by_zero_lbl,rtemp,Operands.Condition('beq'),Operands.ZERO))
if(ctx.myop.type==MiniCParser.DIV):
self._current_function.add_instruction(RiscV.div(dtemp,ltemp,rtemp))
elif(ctx.myop.type==MiniCParser.MOD):
self._current_function.add_instruction(RiscV.rem(dtemp,ltemp,rtemp))
else:
raise MiniCInternalError("Unknown multiplicative operator from the parser:",ctx.myop)
return dtemp
def visitNotExpr(self, ctx) -> Operands.Temporary:
raise NotImplementedError() # TODO (Exercise 5)
if self._debug:
print("unitary not expression on expression:",
Trees.toStringTree(ctx.expr(), None, self._parser))
vtemp = self.visit(ctx.expr())
# Getting a fresh temporary for the result of the opreation
dtemp = self._current_function.fdata.fresh_tmp()
# (not a) is (1 xor a)
self._current_function.add_instruction(RiscV.li(dtemp,Operands.Immediate(1)))
self._current_function.add_instruction(RiscV.xor(dtemp,dtemp,vtemp))
return dtemp
def visitUnaryMinusExpr(self, ctx) -> Operands.Temporary:
raise NotImplementedError("unaryminusexpr") # TODO (Exercise 2)
if self._debug:
print("unitary minus expression on expression:",
Trees.toStringTree(ctx.expr(), None, self._parser))
vtemp = self.visit(ctx.expr())
# Getting a fresh temporary for the result of the opreation
dtemp = self._current_function.fdata.fresh_tmp()
self._current_function.add_instruction(RiscV.sub(dtemp,Operands.ZERO,vtemp))
return dtemp
def visitProgRule(self, ctx) -> None:
self.visitChildren(ctx)
@@ -158,9 +248,25 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
def visitIfStat(self, ctx) -> None:
if self._debug:
print("if statement")
end_if_label = self._current_function.fdata.fresh_label("end_if")
raise NotImplementedError() # TODO (Exercise 5)
self._current_function.add_label(end_if_label)
lendif = self._current_function.fdata.fresh_label("endif")
if(ctx.else_block!=None):
lelse = self._current_function.fdata.fresh_label("else")
dval = self.visit(ctx.expr())
self._current_function.add_instruction(RiscV.conditional_jump(lelse, dval, Operands.Condition('beq'), Operands.ZERO))
self.visit(ctx.then_block)
self._current_function.add_instruction(RiscV.jump(lendif))
self._current_function.add_label(lelse)
self.visit(ctx.else_block)
self._current_function.add_instruction(RiscV.jump(lendif))
self._current_function.add_label(lendif)
else:
dval = self.visit(ctx.expr())
self._current_function.add_instruction(RiscV.conditional_jump(lendif, dval, Operands.Condition('beq'), Operands.ZERO))
self.visit(ctx.then_block)
self._current_function.add_instruction(RiscV.jump(lendif))
self._current_function.add_label(lendif)
def visitWhileStat(self, ctx) -> None:
if self._debug:
@@ -168,7 +274,37 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
print(Trees.toStringTree(ctx.expr(), None, self._parser))
print("and block is:")
print(Trees.toStringTree(ctx.stat_block(), None, self._parser))
raise NotImplementedError() # TODO (Exercise 5)
ltest = self._current_function.fdata.fresh_label("testcond")
lendwhile = self._current_function.fdata.fresh_label("endwhile")
self._current_function.add_instruction(RiscV.jump(ltest))
self._current_function.add_label(ltest)
dcond = self.visit(ctx.expr())
self._current_function.add_instruction(RiscV.conditional_jump(lendwhile, dcond, Operands.Condition('beq'), Operands.ZERO))
self.visit(ctx.body)
self._current_function.add_instruction(RiscV.jump(ltest))
self._current_function.add_label(lendwhile)
def visitForStat(self, ctx):
init_stat = ctx.init_stat
cond = ctx.cond
loop_stat = ctx.loop_stat
body = ctx.stat_block()
ltest = self._current_function.fdata.fresh_label("testcond")
lendfor = self._current_function.fdata.fresh_label("endfor")
if(init_stat != None):
self.visit(init_stat)
self._current_function.add_instruction(RiscV.jump(ltest))
self._current_function.add_label(ltest)
dcond = self.visit(ctx.expr())
self._current_function.add_instruction(RiscV.conditional_jump(lendfor, dcond, Operands.Condition('beq'), Operands.ZERO))
self.visit(body)
if(loop_stat != None):
self.visit(loop_stat)
self._current_function.add_instruction(RiscV.jump(ltest))
self._current_function.add_label(lendfor)
# visit statements
def visitPrintlnintStat(self, ctx) -> None:
+32
View File
@@ -0,0 +1,32 @@
#include "printlib.h"
int main(){
int x;
x = 0;
for(;x<4;){
println_int(x);
x = x+1;
}
x = 69;
for(x=42;false;){
}
println_int(x);
for(x = 100;x>=4;x = x/2){
println_int(x+4);
}
return 0;
}
// EXITCODE 0
// EXPECTED
// 0
// 1
// 2
// 3
// 42
// 104
// 54
// 29
// 16
// 10
+31
View File
@@ -0,0 +1,31 @@
#include "printlib.h"
int main(){
int x,y,z,t;
t = 0;
x = 0;
for(x=0;x<10;x=x+1){
y = 0;
for(y=0;y<4;){
t = t + y;
z = 1;
for(z=1;z<13;z=2*z){
t = t + 1;
}
y = y + 1;
}
for(;y<7;y=y+2){
t = t + (y/2);
}
}
println_int(x);
println_int(y);
println_int(z);
return 0;
}
// EXPECTED
// 10
// 8
// 16
+48
View File
@@ -0,0 +1,48 @@
#include "printlib.h"
int main(){
int x,y,z;
if (10 == 10) {
println_int(44);
if (10 == 11) {
println_int(75);
} else if (10 == 10) {
println_int(42);
if (9 == 10) {
println_int(12);
} else if (10 == 9) {
println_int(15);
} else {
println_int(13);
}
println_int(19);
} else {
println_int(31);
}
println_int(25);
} else if (10 == 10) {
println_int(2);
} else {
println_int(89);
if (10 == 10) {
println_int(68);
} else if (10 == 10) {
println_int(46);
} else {
println_int(22);
}
println_int(43);
}
println_int(14);
return 0;
}
// EXPECTED
// 44
// 42
// 13
// 19
// 25
// 14
+34
View File
@@ -0,0 +1,34 @@
#include "printlib.h"
int main(){
int x,y,z,t;
t = 0;
x = 0;
while(x<10){
y = 0;
while(y<4){
t = t + y;
z = 1;
while(z<13){
t = t + 1;
z = 2 * z;
}
y = y + 1;
}
while(y<7){
t = t + (y/2);
y = y + 2;
}
x = x + 1;
}
println_int(x);
println_int(y);
println_int(z);
return 0;
}
// EXPECTED
// 10
// 8
// 16
@@ -0,0 +1,64 @@
#include "printlib.h"
int main() {
// Testing ==
if( 11 == 22 ){
println_int(420);
}else{
println_int(57);
}
if( -11 == 22 ){
println_int(420);
}else{
println_int(58);
}
if( 11 == -22 ){
println_int(420);
}else{
println_int(59);
}
if( -11 == -22 ){
println_int(420);
}else{
println_int(60);
}
if( 11 == 11 ){
println_int(61);
}else{
println_int(420);
}
if( -22 == -22 ){
println_int(62);
}else{
println_int(420);
}
if( true == true ){
println_int(63);
}else{
println_int(420);
}
if( true == false ){
println_int(420);
}else{
println_int(64);
}
if( false == false ){
println_int(65);
}else{
println_int(420);
}
return 0;
}
// EXPECTED
// 57
// 58
// 59
// 60
// 61
// 62
// 63
// 64
// 65
@@ -0,0 +1,94 @@
#include "printlib.h"
int main() {
// Testing >=
if( 11 >= 22 ){
println_int(420);
}else{
println_int(29);
}
if( -11 >= 22 ){
println_int(420);
}else{
println_int(30);
}
if( 11 >= -22 ){
println_int(31);
}else{
println_int(420);
}
if( -11 >= -22 ){
println_int(32);
}else{
println_int(420);
}
if( 22 >= 11 ){
println_int(33);
}else{
println_int(420);
}
if( 22 >= -11 ){
println_int(34);
}else{
println_int(420);
}
if( -22 >= 11 ){
println_int(420);
}else{
println_int(35);
}
if( -22 >= -11 ){
println_int(420);
}else{
println_int(36);
}
if( 11 >= 22 ){
println_int(420);
}else{
println_int(37);
}
if( -11 >= 22 ){
println_int(420);
}else{
println_int(38);
}
if( 11 >= -22 ){
println_int(39);
}else{
println_int(420);
}
if( -11 >= -22 ){
println_int(40);
}else{
println_int(420);
}
if( 22 >= 22 ){
println_int(41);
}else{
println_int(420);
}
if( -22 >= -22 ){
println_int(42);
}else{
println_int(420);
}
return 0;
}
// EXPECTED
// 29
// 30
// 31
// 32
// 33
// 34
// 35
// 36
// 37
// 38
// 39
// 40
// 41
// 42
@@ -0,0 +1,93 @@
#include "printlib.h"
int main() {
// Testing >
if( 11 > 22 ){
println_int(420);
}else{
println_int(43);
}
if( -11 > 22 ){
println_int(420);
}else{
println_int(44);
}
if( 11 > -22 ){
println_int(45);
}else{
println_int(420);
}
if( -11 > -22 ){
println_int(46);
}else{
println_int(420);
}
if( 22 > 11 ){
println_int(47);
}else{
println_int(420);
}
if( 22 > -11 ){
println_int(48);
}else{
println_int(420);
}
if( -22 > 11 ){
println_int(420);
}else{
println_int(49);
}
if( -22 > -11 ){
println_int(420);
}else{
println_int(50);
}
if( 11 > 22 ){
println_int(420);
}else{
println_int(51);
}
if( -11 > 22 ){
println_int(420);
}else{
println_int(52);
}
if( 11 > -22 ){
println_int(53);
}else{
println_int(420);
}
if( -11 > -22 ){
println_int(54);
}else{
println_int(420);
}
if( 22 > 22 ){
println_int(420);
}else{
println_int(55);
}
if( -22 > -22 ){
println_int(420);
}else{
println_int(56);
}
return 0;
}
// EXPECTED
// 43
// 44
// 45
// 46
// 47
// 48
// 49
// 50
// 51
// 52
// 53
// 54
// 55
// 56
@@ -0,0 +1,94 @@
#include "printlib.h"
int main() {
// Testing <=
if( 11 <= 22 ){
println_int(1);
}else{
println_int(420);
}
if( -11 <= 22 ){
println_int(2);
}else{
println_int(420);
}
if( 11 <= -22 ){
println_int(420);
}else{
println_int(3);
}
if( -11 <= -22 ){
println_int(420);
}else{
println_int(4);
}
if( 22 <= 11 ){
println_int(420);
}else{
println_int(5);
}
if( 22 <= -11 ){
println_int(420);
}else{
println_int(6);
}
if( -22 <= 11 ){
println_int(7);
}else{
println_int(420);
}
if( -22 <= -11 ){
println_int(8);
}else{
println_int(420);
}
if( 11 <= 22 ){
println_int(9);
}else{
println_int(420);
}
if( -11 <= 22 ){
println_int(10);
}else{
println_int(420);
}
if( 11 <= -22 ){
println_int(420);
}else{
println_int(11);
}
if( -11 <= -22 ){
println_int(420);
}else{
println_int(12);
}
if( 22 <= 22 ){
println_int(13);
}else{
println_int(420);
}
if( -22 <= -22 ){
println_int(14);
}else{
println_int(420);
}
return 0;
}
// EXPECTED
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10
// 11
// 12
// 13
// 14
@@ -0,0 +1,94 @@
#include "printlib.h"
int main() {
// Testing <
if( 11 < 22 ){
println_int(15);
}else{
println_int(420);
}
if( -11 < 22 ){
println_int(16);
}else{
println_int(420);
}
if( 11 < -22 ){
println_int(420);
}else{
println_int(17);
}
if( -11 < -22 ){
println_int(420);
}else{
println_int(18);
}
if( 22 < 11 ){
println_int(420);
}else{
println_int(19);
}
if( 22 < -11 ){
println_int(420);
}else{
println_int(20);
}
if( -22 < 11 ){
println_int(21);
}else{
println_int(420);
}
if( -22 < -11 ){
println_int(22);
}else{
println_int(420);
}
if( 11 < 22 ){
println_int(23);
}else{
println_int(420);
}
if( -11 < 22 ){
println_int(24);
}else{
println_int(420);
}
if( 11 < -22 ){
println_int(420);
}else{
println_int(25);
}
if( -11 < -22 ){
println_int(420);
}else{
println_int(26);
}
if( 22 < 22 ){
println_int(420);
}else{
println_int(27);
}
if( -22 < -22 ){
println_int(420);
}else{
println_int(28);
}
return 0;
}
// EXPECTED
// 15
// 16
// 17
// 18
// 19
// 20
// 21
// 22
// 23
// 24
// 25
// 26
// 27
// 28
@@ -0,0 +1,64 @@
#include "printlib.h"
int main() {
// Testing !=
if( 11 != 22 ){
println_int(66);
}else{
println_int(420);
}
if( -11 != 22 ){
println_int(67);
}else{
println_int(420);
}
if( 11 != -22 ){
println_int(68);
}else{
println_int(420);
}
if( -11 != -22 ){
println_int(69);
}else{
println_int(420);
}
if( 11 != 11 ){
println_int(420);
}else{
println_int(70);
}
if( -22 != -22 ){
println_int(420);
}else{
println_int(71);
}
if( true != true ){
println_int(420);
}else{
println_int(72);
}
if( true != false ){
println_int(73);
}else{
println_int(420);
}
if( false != false ){
println_int(420);
}else{
println_int(74);
}
return 0;
}
// EXPECTED
// 66
// 67
// 68
// 69
// 70
// 71
// 72
// 73
// 74
@@ -0,0 +1,26 @@
#include "printlib.h"
int main() {
int x,y,z;
x = 12;
y = -21;
z = 14;
println_int(x + y);
println_int(y + z);
println_int(z + x);
println_int(z + y);
println_int(y + x);
println_int(x + z);
return 0;
}
// EXPECTED
// -9
// -7
// 26
// -7
// -9
// 26
@@ -0,0 +1,26 @@
#include "printlib.h"
int main() {
bool x,y;
x = true;
y = false;
println_bool(x);
println_bool(y);
println_bool(x && x);
println_bool(y && x);
println_bool(x && y);
println_bool(y && y);
return 0;
}
// EXPECTED
// 1
// 0
// 1
// 0
// 0
// 0
@@ -0,0 +1,24 @@
#include "printlib.h"
int main() {
int x,y;
int u,v;
x = 3;
y = -4;
u = 41;
v = -31;
println_int(u / x);
println_int(v / x);
println_int(u / y);
println_int(v / y);
return 0;
}
// EXPECTED
// 13
// -10
// -10
// 7
@@ -0,0 +1,25 @@
#include "printlib.h"
int main() {
int x,y;
int u,v;
x = 3;
y = 0;
u = 41;
v = 0;
println_int(u / x);
println_int(v / x);
println_int(u / y);
println_int(v / y);
return 0;
}
// EXPECTED
// 13
// 0
// Division by 0
// SKIP TEST EXPECTED
// EXECCODE 1
@@ -0,0 +1,26 @@
#include "printlib.h"
int main() {
int x,y,z;
x = 12;
y = -21;
z = 14;
println_int(x - y);
println_int(y - z);
println_int(z - x);
println_int(z - y);
println_int(y - x);
println_int(x - z);
return 0;
}
// EXPECTED
// 33
// -35
// 2
// 35
// -33
// -2
@@ -0,0 +1,24 @@
#include "printlib.h"
int main() {
int x,y;
int u,v;
x = 3;
y = -4;
u = 41;
v = -31;
println_int(u % x);
println_int(v % x);
println_int(u % y);
println_int(v % y);
return 0;
}
// EXPECTED
// 2
// -1
// 1
// -3
@@ -0,0 +1,25 @@
#include "printlib.h"
int main() {
int x,y;
int u,v;
x = 3;
y = 0;
u = 41;
v = 0;
println_int(u % x);
println_int(v % x);
println_int(u % y);
println_int(v % y);
return 0;
}
// EXPECTED
// 2
// 0
// Division by 0
// SKIP TEST EXPECTED
// EXECCODE 1
@@ -0,0 +1,31 @@
#include "printlib.h"
int main() {
int x,y,z,t;
x = 12;
y = -21;
z = 14;
t = -4;
println_int(x * y);
println_int(y * z);
println_int(z * x);
println_int(y * t);
println_int(z * y);
println_int(y * x);
println_int(x * z);
println_int(t * y);
return 0;
}
// EXPECTED
// -252
// -294
// 168
// 84
// -294
// -252
// 168
// 84
@@ -0,0 +1,22 @@
#include "printlib.h"
int main() {
bool x,y;
x = true;
y = false;
println_bool(x);
println_bool(y);
println_bool(!x);
println_bool(!y);
return 0;
}
// EXPECTED
// 1
// 0
// 0
// 1
@@ -0,0 +1,26 @@
#include "printlib.h"
int main() {
bool x,y;
x = true;
y = false;
println_bool(x);
println_bool(y);
println_bool(x || x);
println_bool(y || x);
println_bool(x || y);
println_bool(y || y);
return 0;
}
// EXPECTED
// 1
// 0
// 1
// 1
// 1
// 0
@@ -0,0 +1,25 @@
#include "printlib.h"
int main() {
int x,y;
x = 12;
y = -21;
println_int(x);
println_int(y);
println_int(-x);
println_int(-y);
println_int(x + (-y));
println_int((-x) - (-y));
return 0;
}
// EXPECTED
// 12
// -21
// -12
// 21
// 33
// -33
@@ -0,0 +1,37 @@
#include "printlib.h"
int main() {
int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;
a = 5;
b = 2;
c = a + b;
d = a - b;
e = c + d;
f = d + e;
g = c - e;
h = f + g;
i = h - e;
j = d + g;
k = g + h;
l = c - d;
m = i + j;
n = j + k;
o = k + k;
p = j - e;
q = c + k;
r = d + e;
s = c + b;
t = l - p;
u = d + s;
v = m - r;
w = c + u;
x = k - m;
y = g + r;
z = l + n;
return 0;
}
// EXPECTED
@@ -0,0 +1,22 @@
#include "printlib.h"
int main(){
int x,y,z;
x = 42;
y = 0;
while(y<x){
y = y+1;
}
println_int(y);
y = 0;
while(y<x)
y = y+5;
println_int(y);
return 0;
}
// EXPECTED
// 42
// 45
+19 -9
View File
@@ -6,7 +6,7 @@ Functions to convert a CFG into SSA Form.
from typing import List, Dict, Set
from Lib.CFG import Block, CFG
from Lib.Operands import Renamer
from Lib.Statement import Instruction
from Lib.Statement import Instruction,Label,Operand
from Lib.PhiNode import PhiNode
from Lib.Dominators import computeDom, computeDT, computeDF
@@ -25,8 +25,13 @@ def insertPhis(cfg: CFG, DF: Dict[Block, Set[Block]]) -> None:
d = queue.pop(0)
for b in DF[d]:
if b not in has_phi:
# TODO add a phi node in block `b` (Lab 5a, Exercise 4)
raise NotImplementedError("insertPhis")
params : Dict[Label,Operand] = {}
for bi in (set(b.get_in())):
params[bi.get_label()] = var
phi = PhiNode(var,params)
b._phis.append(phi)
queue.append(b)
has_phi.add(b)
def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Block) -> None:
@@ -43,18 +48,19 @@ def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Blo
for i in succ._phis:
assert (isinstance(i, PhiNode))
i.rename_from(renamer, b.get_label())
# TODO recursive call(s) of rename_block (Lab 5a, Exercise 5)
for dtsucc in DT[b]:
rename_block(cfg,DT,renamer, dtsucc)
def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None:
"""
Rename variables in the CFG, to transform `temp_x = φ(temp_x, ..., temp_x)`
into `temp_x = φ(temp_0, ... temp_n)`.
into `temp_x = φ(temp_0, ..., temp_n)`.
This is an helper function called during SSA entry.
"""
renamer = Renamer(cfg.fdata._pool)
# TODO initial call(s) to rename_block (Lab 5a, Exercise 5)
for etr in cfg.get_entries():
rename_block(cfg,DT,renamer,etr)
def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
@@ -66,5 +72,9 @@ def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
`dom_graphs` indicates if we have to print the domination graphs.
`basename` is used for the names of the produced graphs.
"""
# TODO implement this function (Lab 5a, Exercise 2)
raise NotImplementedError("enter_ssa")
# Compute the DF
dom = computeDom(cfg)
dt = computeDT(cfg,dom,dom_graphs,basename)
df = computeDF(cfg,dom,dt,dom_graphs, basename)
insertPhis(cfg,df)
rename_variables(cfg,dt)
+34 -8
View File
@@ -4,6 +4,7 @@ Functions to convert a CFG out of SSA Form.
"""
from typing import cast, List, Set, Tuple
from Lib.Errors import MiniCInternalError
from Lib import RiscV
from Lib.Graphes import DiGraph
from Lib.CFG import Block, BlockInstr, CFG
@@ -24,8 +25,10 @@ def generate_moves_from_phis(phis: List[PhiNode], parent: Block) -> List[BlockIn
This is an helper function called during SSA exit.
"""
moves: List[BlockInstr] = []
# TODO compute 'moves', a list of 'mv' instructions to insert under parent
# (Lab 5a, Exercise 6)
plabel = parent.get_label()
for phi in phis:
if(plabel in phi.used()):
moves.append(RiscV.mv(phi.var,phi.used()[plabel]))
return moves
@@ -38,11 +41,34 @@ def exit_ssa(cfg: CFG, is_smart: bool) -> None:
for b in cfg.get_blocks():
phis = cast(List[PhiNode], b._phis) # Use cast for Pyright
b._phis = [] # Remove all phi nodes in the block
blabel = b.get_label()
parents: List[Block] = b.get_in().copy() # Copy as we modify it by adding blocks
for parent in parents:
moves = generate_moves_from_phis(phis, parent)
# TODO Add the block containing 'moves' to 'cfg'
# and update edges and jumps accordingly (Lab 5a, Exercise 6)
raise NotImplementedError("exit_ssa")
for p in parents:
moves = generate_moves_from_phis(phis, p)
if(len(moves)==0):
continue
# Creating the block
ilabel = cfg.fdata.fresh_label(p.get_label().name+"_to_"+b.get_label().name)
i = Block(ilabel,moves,AbsoluteJump(blabel))
# Add the block
cfg.add_block(i)
# Changing the jumps
ot = p.get_terminator()
if(isinstance(ot,BranchingTerminator)):
if(ot.label_then == blabel):
ot.label_then = ilabel
if(ot.label_else == blabel):
ot.label_else = ilabel
elif(isinstance(ot,AbsoluteJump)):
assert(ot.label == blabel)
ot = AbsoluteJump(ilabel)
elif(isinstance(ot,Return)):
raise MiniCInternalError("Malformed CFG, cannot have a return in a parent block")
else:
raise MiniCInternalError("I don't know of this terminator type:",type(ot))
p.set_terminator(ot) # This instruction might be useless
# Moving from p -> b to p -> i -> b
cfg.remove_edge(p,b)
cfg.add_edge(p,i)
cfg.add_edge(i,b)