Skip to content

Commit

Permalink
Handle closure effects appropriately in LocalAccessValidator.
Browse files Browse the repository at this point in the history
whitequark committed Jul 23, 2015
1 parent acb8810 commit 9db199c
Showing 5 changed files with 16 additions and 15 deletions.
2 changes: 0 additions & 2 deletions artiq/compiler/module.py
Original file line number Diff line number Diff line change
@@ -32,8 +32,6 @@ def __init__(self, source_buffer, engine=None):
monomorphism_validator.visit(self.typedtree)
escape_validator.visit(self.typedtree)
self.artiq_ir = artiq_ir_generator.visit(self.typedtree)
print(self.artiq_ir[0])
print(self.artiq_ir[1])
dead_code_eliminator.process(self.artiq_ir)
local_access_validator.process(self.artiq_ir)
self.llvm_ir = llvm_ir_generator.process(self.artiq_ir)
2 changes: 1 addition & 1 deletion artiq/compiler/testbench/inferencer.py
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ def generic_visit(self, node):
":{}".format(self.type_printer.name(node.type)))

def main():
if sys.argv[1] == "+mono":
if len(sys.argv) > 1 and sys.argv[1] == "+mono":
del sys.argv[1]
monomorphize = True
else:
3 changes: 2 additions & 1 deletion artiq/compiler/transforms/llvm_ir_generator.py
Original file line number Diff line number Diff line change
@@ -17,8 +17,9 @@ def __init__(self, engine, module_name, context=ll.Context()):
self.fixups = []

def llty_of_type(self, typ, bare=False, for_return=False):
typ = typ.find()
if types.is_tuple(typ):
return ll.LiteralStructType([self.llty_of_type(eltty) for eltty in typ.find().elts])
return ll.LiteralStructType([self.llty_of_type(eltty) for eltty in typ.elts])
elif types.is_function(typ):
envarg = ll.IntType(8).as_pointer()
llty = ll.FunctionType(args=[envarg] +
22 changes: 12 additions & 10 deletions artiq/compiler/validators/local_access.py
Original file line number Diff line number Diff line change
@@ -97,16 +97,18 @@ def pred_at_fault(env, var_name):
self._uninitialized_access(insn, var_name,
pred_at_fault(env, var_name))

if isinstance(insn, ir.Closure):
env = insn.environment()
# Make sure this environment has any interesting variables.
if env in block_state:
for var_name in block_state[env]:
if not block_state[env][var_name]:
# A closure would capture this variable while it is not always
# initialized. Note that this check is transitive.
self._uninitialized_access(insn, var_name,
pred_at_fault(env, var_name))
# Creating a closure has no side effects. However, using a closure does.
for operand in insn.operands:
if isinstance(operand, ir.Closure):
env = operand.environment()
# Make sure this environment has any interesting variables.
if env in block_state:
for var_name in block_state[env]:
if not block_state[env][var_name]:
# A closure would capture this variable while it is not always
# initialized. Note that this check is transitive.
self._uninitialized_access(operand, var_name,
pred_at_fault(env, var_name))

# Save the state.
state[block] = block_state
2 changes: 1 addition & 1 deletion lit-test/compiler/local_access/invalid.py
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
-t

# CHECK-L: ${LINE:+1}: error: variable 't' can be captured in a closure uninitialized
lambda: t
l = lambda: t

# CHECK-L: ${LINE:+1}: error: variable 't' can be captured in a closure uninitialized
def f():

0 comments on commit 9db199c

Please sign in to comment.