forked from M-Labs/artiq
Handle closure effects appropriately in LocalAccessValidator.
This commit is contained in:
parent
acb8810e62
commit
9db199cad9
|
@ -32,8 +32,6 @@ class Module:
|
||||||
monomorphism_validator.visit(self.typedtree)
|
monomorphism_validator.visit(self.typedtree)
|
||||||
escape_validator.visit(self.typedtree)
|
escape_validator.visit(self.typedtree)
|
||||||
self.artiq_ir = artiq_ir_generator.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)
|
dead_code_eliminator.process(self.artiq_ir)
|
||||||
local_access_validator.process(self.artiq_ir)
|
local_access_validator.process(self.artiq_ir)
|
||||||
self.llvm_ir = llvm_ir_generator.process(self.artiq_ir)
|
self.llvm_ir = llvm_ir_generator.process(self.artiq_ir)
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Printer(algorithm.Visitor):
|
||||||
":{}".format(self.type_printer.name(node.type)))
|
":{}".format(self.type_printer.name(node.type)))
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if sys.argv[1] == "+mono":
|
if len(sys.argv) > 1 and sys.argv[1] == "+mono":
|
||||||
del sys.argv[1]
|
del sys.argv[1]
|
||||||
monomorphize = True
|
monomorphize = True
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -17,8 +17,9 @@ class LLVMIRGenerator:
|
||||||
self.fixups = []
|
self.fixups = []
|
||||||
|
|
||||||
def llty_of_type(self, typ, bare=False, for_return=False):
|
def llty_of_type(self, typ, bare=False, for_return=False):
|
||||||
|
typ = typ.find()
|
||||||
if types.is_tuple(typ):
|
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):
|
elif types.is_function(typ):
|
||||||
envarg = ll.IntType(8).as_pointer()
|
envarg = ll.IntType(8).as_pointer()
|
||||||
llty = ll.FunctionType(args=[envarg] +
|
llty = ll.FunctionType(args=[envarg] +
|
||||||
|
|
|
@ -97,16 +97,18 @@ class LocalAccessValidator:
|
||||||
self._uninitialized_access(insn, var_name,
|
self._uninitialized_access(insn, var_name,
|
||||||
pred_at_fault(env, var_name))
|
pred_at_fault(env, var_name))
|
||||||
|
|
||||||
if isinstance(insn, ir.Closure):
|
# Creating a closure has no side effects. However, using a closure does.
|
||||||
env = insn.environment()
|
for operand in insn.operands:
|
||||||
# Make sure this environment has any interesting variables.
|
if isinstance(operand, ir.Closure):
|
||||||
if env in block_state:
|
env = operand.environment()
|
||||||
for var_name in block_state[env]:
|
# Make sure this environment has any interesting variables.
|
||||||
if not block_state[env][var_name]:
|
if env in block_state:
|
||||||
# A closure would capture this variable while it is not always
|
for var_name in block_state[env]:
|
||||||
# initialized. Note that this check is transitive.
|
if not block_state[env][var_name]:
|
||||||
self._uninitialized_access(insn, var_name,
|
# A closure would capture this variable while it is not always
|
||||||
pred_at_fault(env, var_name))
|
# initialized. Note that this check is transitive.
|
||||||
|
self._uninitialized_access(operand, var_name,
|
||||||
|
pred_at_fault(env, var_name))
|
||||||
|
|
||||||
# Save the state.
|
# Save the state.
|
||||||
state[block] = block_state
|
state[block] = block_state
|
||||||
|
|
|
@ -20,7 +20,7 @@ else:
|
||||||
-t
|
-t
|
||||||
|
|
||||||
# CHECK-L: ${LINE:+1}: error: variable 't' can be captured in a closure uninitialized
|
# 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
|
# CHECK-L: ${LINE:+1}: error: variable 't' can be captured in a closure uninitialized
|
||||||
def f():
|
def f():
|
||||||
|
|
Loading…
Reference in New Issue