Skip to content

Commit a557445

Browse files
author
whitequark
committedAug 22, 2015
LocalAccessValidator: assume variables with "$" in name are internal.
Internal variables are assumed to be scoped correctly (including not being accessed uninitialized). This was changed from "." because artiq.compiler.embedding uses "." in module prefix of function names.
1 parent 0e26cfb commit a557445

File tree

5 files changed

+36
-33
lines changed

5 files changed

+36
-33
lines changed
 

Diff for: ‎artiq/compiler/embedding.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,11 @@ def _quote_foreign_function(self, function, loc, syscall):
366366
if syscall is None:
367367
function_type = types.TRPCFunction(arg_types, optarg_types, ret_type,
368368
service=self._map(function))
369-
function_name = "__rpc_{}__".format(function_type.service)
369+
function_name = "rpc${}".format(function_type.service)
370370
else:
371371
function_type = types.TCFunction(arg_types, ret_type,
372372
name=syscall)
373-
function_name = "__ffi_{}__".format(function_type.name)
373+
function_name = "ffi${}".format(function_type.name)
374374

375375
self.globals[function_name] = function_type
376376
self.functions[function] = function_name

Diff for: ‎artiq/compiler/ir.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ class TEnvironment(types.TMono):
465465
def __init__(self, vars, outer=None):
466466
if outer is not None:
467467
assert isinstance(outer, TEnvironment)
468-
env = OrderedDict({".outer": outer})
468+
env = OrderedDict({"$outer": outer})
469469
env.update(vars)
470470
else:
471471
env = OrderedDict(vars)
@@ -475,14 +475,14 @@ def __init__(self, vars, outer=None):
475475
def type_of(self, name):
476476
if name in self.params:
477477
return self.params[name].find()
478-
elif ".outer" in self.params:
479-
return self.params[".outer"].type_of(name)
478+
elif "$outer" in self.params:
479+
return self.params["$outer"].type_of(name)
480480
else:
481481
assert False
482482

483483
def outermost(self):
484-
if ".outer" in self.params:
485-
return self.params[".outer"].outermost()
484+
if "$outer" in self.params:
485+
return self.params["$outer"].outermost()
486486
else:
487487
return self
488488

Diff for: ‎artiq/compiler/transforms/artiq_ir_generator.py

+17-17
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def visit_ModuleT(self, node):
141141
env = self.append(ir.Alloc([], ir.TEnvironment(node.typing_env), name="env"))
142142
old_env, self.current_env = self.current_env, env
143143

144-
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ ".return": typ.ret }),
144+
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ "$return": typ.ret }),
145145
name="privenv"))
146146
old_priv_env, self.current_private_env = self.current_private_env, priv_env
147147

@@ -181,7 +181,7 @@ def visit_function(self, node, is_lambda, is_internal):
181181
for arg_name, default_node in zip(typ.optargs, node.args.defaults):
182182
default = self.visit(default_node)
183183
env_default_name = \
184-
self.current_env.type.add("default." + arg_name, default.type)
184+
self.current_env.type.add("default$" + arg_name, default.type)
185185
self.append(ir.SetLocal(self.current_env, env_default_name, default))
186186
defaults.append(env_default_name)
187187

@@ -217,11 +217,11 @@ def visit_function(self, node, is_lambda, is_internal):
217217
old_env, self.current_env = self.current_env, env
218218

219219
if not is_lambda:
220-
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ ".return": typ.ret }),
220+
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ "$return": typ.ret }),
221221
name="privenv"))
222222
old_priv_env, self.current_private_env = self.current_private_env, priv_env
223223

224-
self.append(ir.SetLocal(env, ".outer", env_arg))
224+
self.append(ir.SetLocal(env, "$outer", env_arg))
225225
for index, arg_name in enumerate(typ.args):
226226
self.append(ir.SetLocal(env, arg_name, args[index]))
227227
for index, (arg_name, env_default_name) in enumerate(zip(typ.optargs, defaults)):
@@ -267,7 +267,7 @@ def visit_Return(self, node):
267267
if self.return_target is None:
268268
self.append(ir.Return(return_value))
269269
else:
270-
self.append(ir.SetLocal(self.current_private_env, ".return", return_value))
270+
self.append(ir.SetLocal(self.current_private_env, "$return", return_value))
271271
self.append(ir.Branch(self.return_target))
272272

273273
def visit_Expr(self, node):
@@ -516,30 +516,30 @@ def visit_Try(self, node):
516516

517517
if any(node.finalbody):
518518
# k for continuation
519-
final_state = self.append(ir.Alloc([], ir.TEnvironment({ ".k": ir.TBasicBlock() })))
519+
final_state = self.append(ir.Alloc([], ir.TEnvironment({ "$k": ir.TBasicBlock() })))
520520
final_targets = []
521521

522522
if self.break_target is not None:
523523
break_proxy = self.add_block("try.break")
524524
old_break, self.break_target = self.break_target, break_proxy
525-
break_proxy.append(ir.SetLocal(final_state, ".k", old_break))
525+
break_proxy.append(ir.SetLocal(final_state, "$k", old_break))
526526
final_targets.append(old_break)
527527
if self.continue_target is not None:
528528
continue_proxy = self.add_block("try.continue")
529529
old_continue, self.continue_target = self.continue_target, continue_proxy
530-
continue_proxy.append(ir.SetLocal(final_state, ".k", old_continue))
530+
continue_proxy.append(ir.SetLocal(final_state, "$k", old_continue))
531531
final_targets.append(old_continue)
532532

533533
return_proxy = self.add_block("try.return")
534534
old_return, self.return_target = self.return_target, return_proxy
535535
if old_return is not None:
536-
return_proxy.append(ir.SetLocal(final_state, ".k", old_return))
536+
return_proxy.append(ir.SetLocal(final_state, "$k", old_return))
537537
final_targets.append(old_return)
538538
else:
539539
return_action = self.add_block("try.doreturn")
540-
value = return_action.append(ir.GetLocal(self.current_private_env, ".return"))
540+
value = return_action.append(ir.GetLocal(self.current_private_env, "$return"))
541541
return_action.append(ir.Return(value))
542-
return_proxy.append(ir.SetLocal(final_state, ".k", return_action))
542+
return_proxy.append(ir.SetLocal(final_state, "$k", return_action))
543543
final_targets.append(return_action)
544544

545545
body = self.add_block("try.body")
@@ -607,19 +607,19 @@ def visit_Try(self, node):
607607
return_proxy.append(ir.Branch(finalizer))
608608

609609
if not body.is_terminated():
610-
body.append(ir.SetLocal(final_state, ".k", tail))
610+
body.append(ir.SetLocal(final_state, "$k", tail))
611611
body.append(ir.Branch(finalizer))
612612

613-
cleanup.append(ir.SetLocal(final_state, ".k", reraise))
613+
cleanup.append(ir.SetLocal(final_state, "$k", reraise))
614614
cleanup.append(ir.Branch(finalizer))
615615

616616
for handler, post_handler in handlers:
617617
if not post_handler.is_terminated():
618-
post_handler.append(ir.SetLocal(final_state, ".k", tail))
618+
post_handler.append(ir.SetLocal(final_state, "$k", tail))
619619
post_handler.append(ir.Branch(finalizer))
620620

621621
if not post_finalizer.is_terminated():
622-
dest = post_finalizer.append(ir.GetLocal(final_state, ".k"))
622+
dest = post_finalizer.append(ir.GetLocal(final_state, "$k"))
623623
post_finalizer.append(ir.IndirectBranch(dest, final_targets))
624624
else:
625625
if not body.is_terminated():
@@ -961,7 +961,7 @@ def visit_ListCompT(self, node):
961961
env = self.append(ir.Alloc([], env_type, name="env.gen"))
962962
old_env, self.current_env = self.current_env, env
963963

964-
self.append(ir.SetLocal(env, ".outer", old_env))
964+
self.append(ir.SetLocal(env, "$outer", old_env))
965965

966966
def body_gen(index):
967967
elt = self.iterable_get(iterable, index)
@@ -1483,7 +1483,7 @@ def instrument_assert(self, node, value):
14831483
for (subexpr, name) in self.current_assert_subexprs]):
14841484
return # don't display the same subexpression twice
14851485

1486-
name = self.current_assert_env.type.add(".subexpr", ir.TOption(node.type))
1486+
name = self.current_assert_env.type.add("$subexpr", ir.TOption(node.type))
14871487
value_opt = self.append(ir.Alloc([value], ir.TOption(node.type)),
14881488
loc=node.loc)
14891489
self.append(ir.SetLocal(self.current_assert_env, name, value_opt),

Diff for: ‎artiq/compiler/transforms/llvm_ir_generator.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -495,10 +495,10 @@ def llptr_to_var(self, llenv, env_ty, var_name, var_type=None):
495495
var_index = list(env_ty.params.keys()).index(var_name)
496496
return self.llbuilder.gep(llenv, [self.llindex(0), self.llindex(var_index)])
497497
else:
498-
outer_index = list(env_ty.params.keys()).index(".outer")
498+
outer_index = list(env_ty.params.keys()).index("$outer")
499499
llptr = self.llbuilder.gep(llenv, [self.llindex(0), self.llindex(outer_index)])
500500
llouterenv = self.llbuilder.load(llptr)
501-
return self.llptr_to_var(llouterenv, env_ty.params[".outer"], var_name)
501+
return self.llptr_to_var(llouterenv, env_ty.params["$outer"], var_name)
502502

503503
def process_GetLocal(self, insn):
504504
env = insn.environment()
@@ -519,7 +519,7 @@ def process_SetLocal(self, insn):
519519
if llptr.type.pointee != llvalue.type:
520520
# The environment argument is an i8*, so that all closures can
521521
# unify with each other regardless of environment type or size.
522-
# We fixup the type on assignment into the ".outer" slot.
522+
# We fixup the type on assignment into the "$outer" slot.
523523
assert isinstance(insn.value(), ir.EnvironmentArgument)
524524
llvalue = self.llbuilder.bitcast(llvalue, llptr.type.pointee)
525525
return self.llbuilder.store(llvalue, llptr)
@@ -740,11 +740,11 @@ def process_Builtin(self, insn):
740740
name=insn.name)
741741
elif insn.op == "globalenv":
742742
def get_outer(llenv, env_ty):
743-
if ".outer" in env_ty.params:
744-
outer_index = list(env_ty.params.keys()).index(".outer")
743+
if "$outer" in env_ty.params:
744+
outer_index = list(env_ty.params.keys()).index("$outer")
745745
llptr = self.llbuilder.gep(llenv, [self.llindex(0), self.llindex(outer_index)])
746746
llouterenv = self.llbuilder.load(llptr)
747-
return self.llptr_to_var(llouterenv, env_ty.params[".outer"], var_name)
747+
return self.llptr_to_var(llouterenv, env_ty.params["$outer"], var_name)
748748
else:
749749
return llenv
750750

Diff for: ‎artiq/compiler/validators/local_access.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
from pythonparser import diagnostic
88
from .. import ir, analyses
99

10+
def is_special_variable(name):
11+
return "$" in name
12+
1013
class LocalAccessValidator:
1114
def __init__(self, engine):
1215
self.engine = engine
@@ -85,8 +88,8 @@ def pred_at_fault(env, var_name):
8588
return None
8689

8790
set_local_in_this_frame = False
88-
if isinstance(insn, (ir.SetLocal, ir.GetLocal)) and \
89-
"." not in insn.var_name:
91+
if (isinstance(insn, (ir.SetLocal, ir.GetLocal)) and
92+
not is_special_variable(insn.var_name)):
9093
env, var_name = insn.environment(), insn.var_name
9194

9295
# Make sure that the variable is defined in the scope of this function.
@@ -124,7 +127,7 @@ def pred_at_fault(env, var_name):
124127
# Make sure this environment has any interesting variables.
125128
if env in block_state:
126129
for var_name in block_state[env]:
127-
if not block_state[env][var_name]:
130+
if not block_state[env][var_name] and not is_special_variable(var_name):
128131
# A closure would capture this variable while it is not always
129132
# initialized. Note that this check is transitive.
130133
self._uninitialized_access(closure, var_name,

0 commit comments

Comments
 (0)
Please sign in to comment.