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: cb225269ff1d
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: c62b16d5e1b1
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Aug 27, 2015

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    04bd242 View commit details
  2. Copy the full SHA
    c62b16d View commit details
Showing with 38 additions and 41 deletions.
  1. +30 −35 artiq/compiler/embedding.py
  2. +8 −6 artiq/compiler/transforms/llvm_ir_generator.py
65 changes: 30 additions & 35 deletions artiq/compiler/embedding.py
Original file line number Diff line number Diff line change
@@ -5,14 +5,13 @@
annotated as ``@kernel`` when they are referenced.
"""

import os, re, linecache, inspect
import os, re, linecache, inspect, textwrap
from collections import OrderedDict, defaultdict

from pythonparser import ast, source, diagnostic, parse_buffer

from . import types, builtins, asttyped, prelude
from .transforms import ASTTypedRewriter, Inferencer, IntMonomorphizer
from .validators import MonomorphismValidator


class ObjectMap:
@@ -156,16 +155,13 @@ def call(self, function_node, args, kwargs):
loc=name_loc.join(end_loc))

class StitchingASTTypedRewriter(ASTTypedRewriter):
def __init__(self, engine, prelude, globals, host_environment, quote_function,
type_map, value_map):
def __init__(self, engine, prelude, globals, host_environment, quote):
super().__init__(engine, prelude)
self.globals = globals
self.env_stack.append(self.globals)

self.host_environment = host_environment
self.quote_function = quote_function
self.type_map = type_map
self.value_map = value_map
self.quote = quote

def visit_Name(self, node):
typ = super()._try_find_name(node.id)
@@ -176,33 +172,18 @@ def visit_Name(self, node):
else:
# Try to find this value in the host environment and quote it.
if node.id in self.host_environment:
value = self.host_environment[node.id]
if inspect.isfunction(value):
# It's a function. We need to translate the function and insert
# a reference to it.
function_name = self.quote_function(value, node.loc)
return asttyped.NameT(id=function_name, ctx=None,
type=self.globals[function_name],
loc=node.loc)

else:
# It's just a value. Quote it.
synthesizer = ASTSynthesizer(expanded_from=node.loc,
type_map=self.type_map,
value_map=self.value_map)
node = synthesizer.quote(value)
synthesizer.finalize()
return node
return self.quote(self.host_environment[node.id], node.loc)
else:
diag = diagnostic.Diagnostic("fatal",
"name '{name}' is not bound to anything", {"name":node.id},
node.loc)
self.engine.process(diag)

class StitchingInferencer(Inferencer):
def __init__(self, engine, type_map, value_map):
def __init__(self, engine, value_map, quote):
super().__init__(engine)
self.type_map, self.value_map = type_map, value_map
self.value_map = value_map
self.quote = quote

def visit_AttributeT(self, node):
self.generic_visit(node)
@@ -239,10 +220,7 @@ def visit_AttributeT(self, node):
# overhead (i.e. synthesizing a source buffer), but has the advantage
# of having the host-to-ARTIQ mapping code in only one place and
# also immediately getting proper diagnostics on type errors.
synthesizer = ASTSynthesizer(type_map=self.type_map,
value_map=self.value_map)
ast = synthesizer.quote(getattr(object_value, node.attr))
synthesizer.finalize()
ast = self.quote(getattr(object_value, node.attr), object_loc.expanded_from)

def proxy_diagnostic(diag):
note = diagnostic.Diagnostic("note",
@@ -258,7 +236,6 @@ def proxy_diagnostic(diag):
proxy_engine.process = proxy_diagnostic
Inferencer(engine=proxy_engine).visit(ast)
IntMonomorphizer(engine=proxy_engine).visit(ast)
MonomorphismValidator(engine=proxy_engine).visit(ast)

if node.attr not in object_type.attributes:
# We just figured out what the type should be. Add it.
@@ -296,7 +273,8 @@ def __init__(self, engine=None):

def finalize(self):
inferencer = StitchingInferencer(engine=self.engine,
type_map=self.type_map, value_map=self.value_map)
value_map=self.value_map,
quote=self._quote)

# Iterate inference to fixed point.
self.inference_finished = False
@@ -316,7 +294,7 @@ def _quote_embedded_function(self, function):

# Extract function source.
embedded_function = function.artiq_embedded.function
source_code = inspect.getsource(embedded_function)
source_code = textwrap.dedent(inspect.getsource(embedded_function))
filename = embedded_function.__code__.co_filename
module_name, _ = os.path.splitext(os.path.basename(filename))
first_line = embedded_function.__code__.co_firstlineno
@@ -350,8 +328,7 @@ def _quote_embedded_function(self, function):
asttyped_rewriter = StitchingASTTypedRewriter(
engine=self.engine, prelude=self.prelude,
globals=self.globals, host_environment=host_environment,
quote_function=self._quote_function,
type_map=self.type_map, value_map=self.value_map)
quote=self._quote)
return asttyped_rewriter.visit(function_node)

def _function_loc(self, function):
@@ -526,6 +503,24 @@ def _quote_function(self, function, loc):
return self._quote_foreign_function(function, loc,
syscall=None)

def _quote(self, value, loc):
if inspect.isfunction(value):
# It's a function. We need to translate the function and insert
# a reference to it.
function_name = self._quote_function(value, loc)
return asttyped.NameT(id=function_name, ctx=None,
type=self.globals[function_name],
loc=loc)

else:
# It's just a value. Quote it.
synthesizer = ASTSynthesizer(expanded_from=loc,
type_map=self.type_map,
value_map=self.value_map)
node = synthesizer.quote(value)
synthesizer.finalize()
return node

def stitch_call(self, function, args, kwargs):
function_node = self._quote_embedded_function(function)
self.typedtree.append(function_node)
14 changes: 8 additions & 6 deletions artiq/compiler/transforms/llvm_ir_generator.py
Original file line number Diff line number Diff line change
@@ -991,6 +991,11 @@ def _quote(self, value, typ, path):
lambda: path() + [attr]))

llvalue = ll.Constant.literal_struct(llfields)
llconst = ll.GlobalVariable(self.llmodule, llvalue.type, global_name)
llconst.initializer = llvalue
llconst.linkage = "private"
self.llobject_map[value_id] = llconst
return llconst
elif builtins.is_none(typ):
assert value is None
return ll.Constant.literal_struct([])
@@ -1006,15 +1011,12 @@ def _quote(self, value, typ, path):
elif builtins.is_str(typ):
assert isinstance(value, (str, bytes))
return self.llstr_of_str(value)
elif types.is_rpc_function(typ):
return ll.Constant.literal_struct([])
else:
print(typ)
assert False

llconst = ll.GlobalVariable(self.llmodule, llvalue.type, global_name)
llconst.initializer = llvalue
llconst.linkage = "private"
self.llobject_map[value_id] = llconst
return llconst

def process_Quote(self, insn):
assert self.object_map is not None
return self._quote(insn.value, insn.type, lambda: [repr(insn.value)])