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: 6383253e03f6
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: 0acc86b3b39a
Choose a head ref
  • 2 commits
  • 10 files changed
  • 1 contributor

Commits on Jan 26, 2016

  1. Fix typo.

    whitequark committed Jan 26, 2016
    Copy the full SHA
    7f9a180 View commit details

Commits on Jan 27, 2016

  1. Copy the full SHA
    0acc86b View commit details
44 changes: 29 additions & 15 deletions artiq/compiler/transforms/iodelay_estimator.py
Original file line number Diff line number Diff line change
@@ -24,11 +24,11 @@ def __init__(self, engine, ref_period):
self.current_goto = None
self.current_return = None

def evaluate(self, node, abort):
def evaluate(self, node, abort, context):
if isinstance(node, asttyped.NumT):
return iodelay.Const(node.n)
elif isinstance(node, asttyped.CoerceT):
return self.evaluate(node.value, abort)
return self.evaluate(node.value, abort, context)
elif isinstance(node, asttyped.NameT):
if self.current_args is None:
note = diagnostic.Diagnostic("note",
@@ -48,8 +48,8 @@ def evaluate(self, node, abort):
]
abort(notes)
elif isinstance(node, asttyped.BinOpT):
lhs = self.evaluate(node.left, abort)
rhs = self.evaluate(node.right, abort)
lhs = self.evaluate(node.left, abort, context)
rhs = self.evaluate(node.right, abort, context)
if isinstance(node.op, ast.Add):
return lhs + rhs
elif isinstance(node.op, ast.Sub):
@@ -62,12 +62,14 @@ def evaluate(self, node, abort):
return lhs // rhs
else:
note = diagnostic.Diagnostic("note",
"this operator is not supported", {},
"this operator is not supported {context}",
{"context": context},
node.op.loc)
abort([note])
else:
note = diagnostic.Diagnostic("note",
"this expression is not supported", {},
"this expression is not supported {context}",
{"context": context},
node.loc)
abort([note])

@@ -143,14 +145,14 @@ def visit_FunctionDefT(self, node):
def visit_LambdaT(self, node):
self.visit_function(node.args, node.body, node.type.find(), node.loc)

def get_iterable_length(self, node):
def get_iterable_length(self, node, context):
def abort(notes):
self.abort("for statement cannot be interleaved because "
"trip count is indeterminate",
"iteration count is indeterminate",
node.loc, notes)

def evaluate(node):
return self.evaluate(node, abort)
return self.evaluate(node, abort, context)

if isinstance(node, asttyped.CallT) and types.is_builtin(node.func.type, "range"):
range_min, range_max, range_step = iodelay.Const(0), None, iodelay.Const(1)
@@ -177,10 +179,11 @@ def visit_ForT(self, node):
self.current_delay = old_delay
else:
if self.current_goto is not None:
self.abort("loop trip count is indeterminate because of control flow",
self.abort("loop iteration count is indeterminate because of control flow",
self.current_goto.loc)

node.trip_count = self.get_iterable_length(node.iter).fold()
context = "in an iterable used in a for loop that is being interleaved"
node.trip_count = self.get_iterable_length(node.iter, context).fold()
node.trip_interval = self.current_delay.fold()
self.current_delay = old_delay + node.trip_interval * node.trip_count
self.current_goto = old_goto
@@ -231,6 +234,10 @@ def visit_With(self, node):
# Interleave failures inside `with` statements are hard failures,
# since there's no chance that the code will never actually execute
# inside a `with` statement after all.
note = diagnostic.Diagnostic("note",
"while interleaving this 'with parallel:' statement", {},
node.loc)
error.cause.notes += [note]
self.engine.process(error.cause)

flow_stmt = None
@@ -258,15 +265,17 @@ def visit_With(self, node):
def visit_CallT(self, node):
typ = node.func.type.find()
def abort(notes):
self.abort("this call cannot be interleaved because "
self.abort("call cannot be interleaved because "
"an argument cannot be statically evaluated",
node.loc, notes)

if types.is_builtin(typ, "delay"):
value = self.evaluate(node.args[0], abort=abort)
value = self.evaluate(node.args[0], abort=abort,
context="as an argument for delay()")
call_delay = iodelay.SToMU(value, ref_period=self.ref_period)
elif types.is_builtin(typ, "delay_mu"):
value = self.evaluate(node.args[0], abort=abort)
value = self.evaluate(node.args[0], abort=abort,
context="as an argument for delay_mu()")
call_delay = value
elif not types.is_builtin(typ):
if types.is_function(typ):
@@ -297,7 +306,12 @@ def abort(notes):
args[arg_name] = arg_node

free_vars = delay.duration.free_vars()
node.arg_exprs = { arg: self.evaluate(args[arg], abort=abort) for arg in free_vars }
node.arg_exprs = {
arg: self.evaluate(args[arg], abort=abort,
context="in the expression for argument '{}' "
"that affects I/O delay".format(arg))
for arg in free_vars
}
call_delay = delay.duration.fold(node.arg_exprs)
else:
assert False
2 changes: 1 addition & 1 deletion artiq/coredevice/core.py
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
def _render_diagnostic(diagnostic, colored):
def shorten_path(path):
return path.replace(artiq_dir, "<artiq>")
lines = [shorten_path(path) for path in diagnostic.render(colored)]
lines = [shorten_path(path) for path in diagnostic.render(colored=colored)]
return "\n".join(lines)

class _DiagnosticEngine(diagnostic.Engine):
12 changes: 12 additions & 0 deletions artiq/test/lit/iodelay/error_argument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# RUN: %python -m artiq.compiler.testbench.signature +diag +delay %s >%t
# RUN: OutputCheck %s --file-to-check=%t

def f(x):
delay_mu(x)

x = 1

def g():
# CHECK-L: ${LINE:+2}: error: call cannot be interleaved because an argument cannot be statically evaluated
# CHECK-L: ${LINE:+1}: note: this expression is not supported in the expression for argument 'x' that affects I/O delay
f(x if True else x)
10 changes: 5 additions & 5 deletions artiq/test/lit/iodelay/error_arith.py
Original file line number Diff line number Diff line change
@@ -3,19 +3,19 @@

def f(a):
b = 1.0
# CHECK-L: ${LINE:+3}: error: this call cannot be interleaved
# CHECK-L: ${LINE:+3}: error: call cannot be interleaved
# CHECK-L: ${LINE:+2}: note: this variable is not an argument of the innermost function
# CHECK-L: ${LINE:-4}: note: only these arguments are in scope of analysis
delay(b)

def g():
# CHECK-L: ${LINE:+2}: error: this call cannot be interleaved
# CHECK-L: ${LINE:+1}: note: this operator is not supported
# CHECK-L: ${LINE:+2}: error: call cannot be interleaved
# CHECK-L: ${LINE:+1}: note: this operator is not supported as an argument for delay()
delay(2.0**2)

def h():
# CHECK-L: ${LINE:+2}: error: this call cannot be interleaved
# CHECK-L: ${LINE:+1}: note: this expression is not supported
# CHECK-L: ${LINE:+2}: error: call cannot be interleaved
# CHECK-L: ${LINE:+1}: note: this expression is not supported as an argument for delay_mu()
delay_mu(1 if False else 2)

f(1)
4 changes: 2 additions & 2 deletions artiq/test/lit/iodelay/error_builtinfn.py
Original file line number Diff line number Diff line change
@@ -3,12 +3,12 @@

def f():
x = 1
# CHECK-L: ${LINE:+1}: error: this call cannot be interleaved because an argument cannot be statically evaluated
# CHECK-L: ${LINE:+1}: error: call cannot be interleaved because an argument cannot be statically evaluated
delay_mu(x)

def g():
x = 1.0
# CHECK-L: ${LINE:+1}: error: this call cannot be interleaved
# CHECK-L: ${LINE:+1}: error: call cannot be interleaved
delay(x)


2 changes: 1 addition & 1 deletion artiq/test/lit/iodelay/error_call_nested.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
# RUN: OutputCheck %s --file-to-check=%t

def f():
# CHECK-L: ${LINE:+1}: error: this call cannot be interleaved
# CHECK-L: ${LINE:+1}: error: call cannot be interleaved
delay(1.0**2)

def g():
2 changes: 1 addition & 1 deletion artiq/test/lit/iodelay/error_call_subst.py
Original file line number Diff line number Diff line change
@@ -9,5 +9,5 @@ def pulse(len):

def f():
a = 100
# CHECK-L: ${LINE:+1}: error: this call cannot be interleaved
# CHECK-L: ${LINE:+1}: error: call cannot be interleaved
pulse(a)
2 changes: 1 addition & 1 deletion artiq/test/lit/iodelay/error_for.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

def f():
r = range(10)
# CHECK-L: ${LINE:+2}: error: for statement cannot be interleaved because trip count is indeterminate
# CHECK-L: ${LINE:+2}: error: for statement cannot be interleaved because iteration count is indeterminate
# CHECK-L: ${LINE:+1}: note: this value is not a constant range literal
for _ in r:
delay_mu(1)
4 changes: 2 additions & 2 deletions artiq/test/lit/iodelay/error_goto.py
Original file line number Diff line number Diff line change
@@ -4,11 +4,11 @@
def f():
for _ in range(10):
delay_mu(10)
# CHECK-L: ${LINE:+1}: error: loop trip count is indeterminate because of control flow
# CHECK-L: ${LINE:+1}: error: loop iteration count is indeterminate because of control flow
break

def g():
for _ in range(10):
delay_mu(10)
# CHECK-L: ${LINE:+1}: error: loop trip count is indeterminate because of control flow
# CHECK-L: ${LINE:+1}: error: loop iteration count is indeterminate because of control flow
continue
10 changes: 10 additions & 0 deletions artiq/test/lit/iodelay/error_iterable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# RUN: %python -m artiq.compiler.testbench.signature +diag +delay %s >%t
# RUN: OutputCheck %s --file-to-check=%t

x = 1

def f():
# CHECK-L: ${LINE:+2}: error: for statement cannot be interleaved because iteration count is indeterminate
# CHECK-L: ${LINE:+1}: note: this expression is not supported in an iterable used in a for loop that is being interleaved
for _ in range(x if True else x):
delay_mu(10)