Skip to content

Commit

Permalink
add transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
jiamo committed Mar 10, 2022
1 parent 3ddd44a commit 07cc71e
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 6 deletions.
47 changes: 46 additions & 1 deletion compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from re import T
from utils import *
from x86_ast import *
from collections import deque
from functools import reduce
import os
from graph import UndirectedAdjList, transpose, topological_sort
from priority_queue import PriorityQueue
Expand Down Expand Up @@ -92,6 +94,10 @@ def shrink_stmt(self, s: stmt) -> stmt:
body = [self.shrink_stmt(s) for s in body]
orelse = [self.shrink_stmt(s) for s in orelse]
result = If(test_expr, body, orelse)
case While(test, body, []):
test_expr = self.shrink_exp(test)
body = [self.shrink_stmt(s) for s in body]
result = While(test_expr, body, [])
case _:
raise Exception('error in rco_stmt, unexpected ' + repr(s))
return result
Expand Down Expand Up @@ -173,6 +179,7 @@ def rco_exp(self, e: expr, need_atomic: bool) -> Tuple[expr, Temporaries]:
return tmp, test_tmps
else:
return return_expr, test_tmps

case _:
raise Exception('error in rco_exp, unexpected ' + repr(e))

Expand Down Expand Up @@ -209,6 +216,14 @@ def rco_stmt(self, s: stmt) -> List[stmt]:
for s in orelse:
orelse_stmts.extend(self.rco_stmt(s))
result.append(If(test_expr, body_stmts, orelse_stmts))
case While(test, body, []):
test_expr, test_tmps = self.rco_exp(test, False)
body_stmts = []
for name, t_expr in test_tmps:
result.append(Assign([name], t_expr))
for s in body:
body_stmts.extend(self.rco_stmt(s))
result.append(While(test_expr, body_stmts, []))
case _:
raise Exception('error in rco_stmt, unexpected ' + repr(s))
return result
Expand Down Expand Up @@ -331,13 +346,27 @@ def explicate_stmt(self, s: stmt, cont: List[stmt],
new_orelse = self.explicate_stmt(s, new_orelse, basic_blocks)

return self.explicate_pred(test, new_body, new_orelse, basic_blocks)
case While(test, body, []):
# after_while = create_block(cont, basic_blocks)
# goto_after_while = [after_while]
test_label = label_name(generate_name('block'))
new_body = [Goto(test_label)]
for s in reversed(body):
# the new_body was after s we need do the new_body
new_body = self.explicate_stmt(s, new_body, basic_blocks)
test_stmts = self.explicate_pred(test, new_body, cont, basic_blocks)
basic_blocks[test_label] = test_stmts
return [Goto(test_label)]
# case Expr(Call(Name('print'), [arg])):
# return [s] + cont

def explicate_control(self, p):
match p:
case Module(body):
new_body = [Return(Constant(0))]
# 也许这里是一个 newblock conclude = block(Return(Constant(0))])
# create_block 是 goto 那个 bloc
# conclude 这里是从那里 goto 到这里
basic_blocks = {}
for s in reversed(body):
# the new_body was after s we need do the new_body
Expand Down Expand Up @@ -375,7 +404,7 @@ def select_compare(self, expr, then_label, else_label) -> List[instr]:
x = self.select_arg(x)
y = self.select_arg(y)
return [
Instr('cmpq', [x, y]),
Instr('cmpq', [y, x]),
# Instr('j{}'.format(op_dict[str(op)]), [then_label]),
JumpIf(op_dict[str(op)], then_label),
Jump(else_label)
Expand Down Expand Up @@ -598,6 +627,18 @@ def uncover_live(self, ss: List[instr], live_before_block) -> Dict[instr, Set[lo
return live_after


def analyze_dataflow(self, G, transfer, bottom, join):
trans_G = transpose(G)
mapping = dict((v, bottom) for v in G.vertices())
worklist = deque(G.vertices)
while worklist:
node = worklist.pop()
inputs = [mapping[v] for v in trans_G.adjacent(node)]
input = reduce(join, inputs, bottom)
output = transfer(node, input)
if output != mapping[node]:
worklist.extend(G.adjacent(node))

def build_interference(self, blocks) -> UndirectedAdjList:
cfg = UndirectedAdjList()
for label, body in blocks.items():
Expand All @@ -611,9 +652,13 @@ def build_interference(self, blocks) -> UndirectedAdjList:
self.sort_cfg = topological_sort(cfg)
live_before_block = {}
live_after = {}

for label in reversed(self.sort_cfg):
ss = blocks[label]
tmp = self.uncover_live(ss, live_before_block)
# live update bind instr with
# flow 分析解决的是 block 的分析问题。
# 在解决 block 的
live_before_block[label] = tmp[ss[0]]
live_after.update(tmp)

Expand Down
2 changes: 1 addition & 1 deletion interp_Cif.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class InterpCif(InterpLif):
def interp_stmts(self, ss, env):
if len(ss) == 0:
return
trace("trace {}".format(ss[0]))
# trace("trace {}".format(ss[0]))

match ss[0]:
case Return(value):
Expand Down
10 changes: 6 additions & 4 deletions run-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import interp_Pvar
import interp_Lvar
import interp_Lif
import interp_Lwhile
import type_check_Pvar
import type_check_Lvar
import interp_Cif
Expand All @@ -21,8 +22,9 @@
interp_dict = {
"var": interp_Lvar.InterpLvar().interp,
"cond": interp_Lif.InterpLif().interp,
"shrink": interp_Lif.InterpLif().interp,
"remove_complex_operands": interp_Lif.InterpLif().interp,
"while": interp_Lwhile.InterpLwhile().interp,
"shrink": interp_Lwhile.InterpLwhile().interp,
"remove_complex_operands": interp_Lwhile.InterpLwhile().interp,
"explicate_control": interp_Cif.InterpCif().interp,
"select_instructions": interp_x86,
"assign_homes": interp_x86,
Expand All @@ -33,8 +35,8 @@

if len(sys.argv) == 2:
one_test_file = sys.argv[1]
run_one_test(one_test_file, 'cond',
compiler, 'cond',
run_one_test(one_test_file, 'while',
compiler, 'while',
#type_check_Pvar.TypeCheckPvar().type_check_P,
type_check_dict,
# interp_Pvar.InterpPvar().interp_P,
Expand Down
1 change: 1 addition & 0 deletions tests/while/add.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42
1 change: 1 addition & 0 deletions tests/while/add.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

7 changes: 7 additions & 0 deletions tests/while/add.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
x = 2
y = 2
g = x == y
if g:
print(42)
else:
print(1)
1 change: 1 addition & 0 deletions tests/while/add1.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
55
2 changes: 2 additions & 0 deletions tests/while/add1.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
10
32
6 changes: 6 additions & 0 deletions tests/while/add1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sum = 0
i = 10
while i > 0:
sum = sum + i
i = i - 1
print(sum)
1 change: 1 addition & 0 deletions tests/while/input.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42
1 change: 1 addition & 0 deletions tests/while/input.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42
1 change: 1 addition & 0 deletions tests/while/input.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print(input_int())
1 change: 1 addition & 0 deletions tests/while/zero.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions tests/while/zero.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

6 changes: 6 additions & 0 deletions tests/while/zero.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
var = True
var = not False
if var:
print(0)
else:
print(0)

0 comments on commit 07cc71e

Please sign in to comment.