Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f510d3aa4996
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2b948ba26779
Choose a head ref
  • 3 commits
  • 2 files changed
  • 1 contributor

Commits on Sep 26, 2014

  1. Copy the full SHA
    89fdab2 View commit details
  2. Copy the full SHA
    4a5e398 View commit details
  3. Copy the full SHA
    2b948ba View commit details
Showing with 49 additions and 26 deletions.
  1. +47 −26 artiq/py2llvm/ast_body.py
  2. +2 −0 test/py2llvm.py
73 changes: 47 additions & 26 deletions artiq/py2llvm/ast_body.py
Original file line number Diff line number Diff line change
@@ -43,6 +43,7 @@ def __init__(self, env, ns, builder=None):
self.ns = ns
self.builder = builder
self._break_stack = []
self._continue_stack = []
self._active_exception_stack = []
self._exception_level_stack = [0]

@@ -170,6 +171,9 @@ def visit_statements(self, stmts):
if node_type in ("Return", "Break", "Continue"):
break

def _bb_terminated(self):
return is_terminated(self.builder.basic_block)

def _visit_stmt_Assign(self, node):
val = self.visit_expression(node.value)
for target in node.targets:
@@ -197,85 +201,102 @@ def _visit_stmt_If(self, node):

self.builder.position_at_end(then_block)
self.visit_statements(node.body)
if not is_terminated(self.builder.basic_block):
if not self._bb_terminated():
self.builder.branch(merge_block)

self.builder.position_at_end(else_block)
self.visit_statements(node.orelse)
if not is_terminated(self.builder.basic_block):
if not self._bb_terminated():
self.builder.branch(merge_block)

self.builder.position_at_end(merge_block)

def _enter_loop_body(self, break_block):
def _enter_loop_body(self, break_block, continue_block):
self._break_stack.append(break_block)
self._continue_stack.append(continue_block)
self._exception_level_stack.append(0)

def _leave_loop_body(self):
self._exception_level_stack.pop()
self._continue_stack.pop()
self._break_stack.pop()

def _visit_stmt_While(self, node):
function = self.builder.basic_block.function

body_block = function.append_basic_block("w_body")
else_block = function.append_basic_block("w_else")
merge_block = function.append_basic_block("w_merge")

condition = self.visit_expression(node.test).o_bool(self.builder)
self.builder.cbranch(
condition.auto_load(self.builder), body_block, else_block)

continue_block = function.append_basic_block("w_continue")
merge_block = function.append_basic_block("w_merge")
self.builder.position_at_end(body_block)
self._enter_loop_body(merge_block)
self._enter_loop_body(merge_block, continue_block)
self.visit_statements(node.body)
self._leave_loop_body()
if not is_terminated(self.builder.basic_block):
condition = self.visit_expression(node.test).o_bool(self.builder)
self.builder.cbranch(
condition.auto_load(self.builder), body_block, merge_block)
if not self._bb_terminated():
self.builder.branch(continue_block)

self.builder.position_at_end(continue_block)
condition = self.visit_expression(node.test).o_bool(self.builder)
self.builder.cbranch(
condition.auto_load(self.builder), body_block, merge_block)

self.builder.position_at_end(else_block)
self.visit_statements(node.orelse)
if not is_terminated(self.builder.basic_block):
if not self._bb_terminated():
self.builder.branch(merge_block)

self.builder.position_at_end(merge_block)

def _visit_stmt_For(self, node):
function = self.builder.basic_block.function
body_block = function.append_basic_block("f_body")
else_block = function.append_basic_block("f_else")
merge_block = function.append_basic_block("f_merge")

it = self.visit_expression(node.iter)
target = self.visit_expression(node.target)
itval = it.get_value_ptr()

body_block = function.append_basic_block("f_body")
else_block = function.append_basic_block("f_else")
cont = it.o_next(self.builder)
self.builder.cbranch(
cont.auto_load(self.builder), body_block, else_block)

continue_block = function.append_basic_block("f_continue")
merge_block = function.append_basic_block("f_merge")
self.builder.position_at_end(body_block)
target.set_value(self.builder, itval)
self._enter_loop_body(merge_block)
self._enter_loop_body(merge_block, continue_block)
self.visit_statements(node.body)
self._leave_loop_body()
if not is_terminated(self.builder.basic_block):
cont = it.o_next(self.builder)
self.builder.cbranch(
cont.auto_load(self.builder), body_block, merge_block)
if not self._bb_terminated():
self.builder.branch(continue_block)

self.builder.position_at_end(continue_block)
cont = it.o_next(self.builder)
self.builder.cbranch(
cont.auto_load(self.builder), body_block, merge_block)

self.builder.position_at_end(else_block)
self.visit_statements(node.orelse)
if not is_terminated(self.builder.basic_block):
if not self._bb_terminated():
self.builder.branch(merge_block)

self.builder.position_at_end(merge_block)

def _visit_stmt_Break(self, node):
def _break_loop_body(self, target_block):
exception_levels = self._exception_level_stack[-1]
if exception_levels:
self.env.build_pop(self.builder, exception_levels)
self.builder.branch(self._break_stack[-1])
self.builder.branch(target_block)

def _visit_stmt_Break(self, node):
self._break_loop_body(self._break_stack[-1])

def _visit_stmt_Continue(self, node):
self._break_loop_body(self._continue_stack[-1])

def _visit_stmt_Return(self, node):
if node.value is None:
@@ -337,7 +358,7 @@ def _handle_exception(self, function, finally_block, propagate, propagate_eid, h
self.builder.position_at_end(handled_exc_block)
self.builder.store(lc.Constant.int(lc.Type.int(1), 0), propagate)
self.visit_statements(handler.body)
if not is_terminated(self.builder.basic_block):
if not self._bb_terminated():
self.builder.branch(finally_block)
self.builder.position_at_end(cont_exc_block)
self.builder.branch(finally_block)
@@ -360,10 +381,10 @@ def _visit_stmt_Try(self, node):
self._exception_level_stack[-1] += 1
self.visit_statements(node.body)
self._exception_level_stack[-1] -= 1
if not is_terminated(self.builder.basic_block):
if not self._bb_terminated():
self.env.build_pop(self.builder, 1)
self.visit_statements(node.orelse)
if not is_terminated(self.builder.basic_block):
if not self._bb_terminated():
self.builder.branch(finally_block)
self.builder.position_at_end(exc_block)
self._handle_exception(function, finally_block,
@@ -373,7 +394,7 @@ def _visit_stmt_Try(self, node):
merge_block = function.append_basic_block("try_merge")
self.builder.position_at_end(finally_block)
self.visit_statements(node.finalbody)
if not is_terminated(self.builder.basic_block):
if not self._bb_terminated():
self.builder.cbranch(
self.builder.load(propagate),
propagate_block, merge_block)
2 changes: 2 additions & 0 deletions test/py2llvm.py
Original file line number Diff line number Diff line change
@@ -181,6 +181,8 @@ def array_test():
acc = 0
for i in range(5):
for j in range(5):
if i + j == 2:
continue
acc += a[i][j]
return acc