Skip to content

Commit 8e1cc8d

Browse files
author
whitequark
committedJul 18, 2015
Add an explicit ARTIQ IR instruction to create a closure.
1 parent 5ad02d5 commit 8e1cc8d

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed
 

Diff for: ‎artiq/compiler/ir.py

+26-8
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,13 @@ class Argument(NamedValue):
344344
def __str__(self):
345345
return self.as_operand()
346346

347-
class Function(Value):
347+
class Function:
348348
"""
349349
A function containing SSA IR.
350350
"""
351351

352352
def __init__(self, typ, name, arguments):
353-
super().__init__(typ)
354-
self.name = name
353+
self.type, self.name = typ, name
355354
self.names, self.arguments, self.basic_blocks = set(), [], []
356355
self.set_arguments(arguments)
357356

@@ -389,10 +388,6 @@ def predecessors_of(self, successor):
389388
return [block for block in self.basic_blocks
390389
if block.is_terminated() and successor in block.successors()]
391390

392-
def as_operand(self):
393-
return "{} @{}".format(types.TypePrinter().name(self.type),
394-
escape_name(self.name))
395-
396391
def __str__(self):
397392
printer = types.TypePrinter()
398393
lines = []
@@ -766,6 +761,30 @@ def __init__(self, op, operands, typ, name=""):
766761
def opcode(self):
767762
return "builtin({})".format(self.op)
768763

764+
class Closure(Instruction):
765+
"""
766+
A closure creation operation.
767+
768+
:ivar target_function: (:class:`Function`) function to invoke
769+
"""
770+
771+
"""
772+
:param func: (:class:`Function`) function
773+
:param env: (:class:`Value`) outer environment
774+
"""
775+
def __init__(self, func, env, name=""):
776+
assert isinstance(func, Function)
777+
assert isinstance(env, Value)
778+
assert is_environment(env.type)
779+
super().__init__([env], func.type, name)
780+
self.target_function = func
781+
782+
def opcode(self):
783+
return "closure({})".format(self.target_function.name)
784+
785+
def get_environment(self):
786+
return self.operands[0]
787+
769788
class Call(Instruction):
770789
"""
771790
A function call operation.
@@ -776,7 +795,6 @@ class Call(Instruction):
776795
:param args: (list of :class:`Value`) function arguments
777796
"""
778797
def __init__(self, func, args, name=""):
779-
print(func)
780798
assert isinstance(func, Value)
781799
for arg in args: assert isinstance(arg, Value)
782800
super().__init__([func] + args, func.type.ret, name)

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ def visit_ModuleT(self, node):
131131
env = self.append(ir.Alloc([], ir.TEnvironment(node.typing_env), name="env"))
132132
old_env, self.current_env = self.current_env, env
133133

134-
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ ".return": typ.ret })))
134+
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ ".return": typ.ret }),
135+
name="privenv"))
135136
old_priv_env, self.current_private_env = self.current_private_env, priv_env
136137

137138
self.generic_visit(node)
@@ -193,7 +194,8 @@ def visit_function(self, node, is_lambda):
193194
old_env, self.current_env = self.current_env, env
194195

195196
if not is_lambda:
196-
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ ".return": typ.ret })))
197+
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ ".return": typ.ret }),
198+
name="privenv"))
197199
old_priv_env, self.current_private_env = self.current_private_env, priv_env
198200

199201
self.append(ir.SetLocal(env, ".outer", env_arg))
@@ -215,8 +217,6 @@ def visit_function(self, node, is_lambda):
215217
else:
216218
if not self.current_block.is_terminated():
217219
self.current_block.append(ir.Unreachable())
218-
219-
return func
220220
finally:
221221
self.name = old_name
222222
self.current_function = old_func
@@ -226,6 +226,8 @@ def visit_function(self, node, is_lambda):
226226
if not is_lambda:
227227
self.current_private_env = old_priv_env
228228

229+
return self.append(ir.Closure(func, self.current_env))
230+
229231
def visit_FunctionDefT(self, node):
230232
func = self.visit_function(node, is_lambda=False)
231233
self._set_local(node.name, func)

0 commit comments

Comments
 (0)
Please sign in to comment.