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: ec9d40b04f53
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: 49ece6a12a37
Choose a head ref
  • 3 commits
  • 8 files changed
  • 1 contributor

Commits on Jul 21, 2015

  1. Fix tests broken by fixed FloorDiv.

    whitequark committed Jul 21, 2015
    Copy the full SHA
    e58b811 View commit details
  2. Copy the full SHA
    64d2604 View commit details
  3. Add support for string literals.

    whitequark committed Jul 21, 2015
    6
    Copy the full SHA
    49ece6a View commit details
14 changes: 12 additions & 2 deletions artiq/compiler/builtins.py
Original file line number Diff line number Diff line change
@@ -50,6 +50,10 @@ def zero():
def one():
return 1.0

class TStr(types.TMono):
def __init__(self):
super().__init__("str")

class TList(types.TMono):
def __init__(self, elt=None):
if elt is None:
@@ -88,6 +92,9 @@ def fn_int():
def fn_float():
return types.TConstructor("float")

def fn_str():
return types.TConstructor("str")

def fn_list():
return types.TConstructor("list")

@@ -133,6 +140,9 @@ def get_int_width(typ):
def is_float(typ):
return types.is_mono(typ, "float")

def is_str(typ):
return types.is_mono(typ, "str")

def is_numeric(typ):
typ = typ.find()
return isinstance(typ, types.TMono) and \
@@ -167,6 +177,6 @@ def is_collection(typ):
return isinstance(typ, types.TTuple) or \
types.is_mono(typ, "list")

def is_mutable(typ):
def is_allocated(typ):
return typ.fold(False, lambda accum, typ:
is_list(typ) or types.is_function(typ))
is_list(typ) or is_str(typ) or types.is_function(typ))
9 changes: 7 additions & 2 deletions artiq/compiler/testbench/module.py
Original file line number Diff line number Diff line change
@@ -5,11 +5,13 @@
def main():
if len(sys.argv) > 1 and sys.argv[1] == "+diag":
del sys.argv[1]
diag = True
def process_diagnostic(diag):
print("\n".join(diag.render(only_line=True)))
if diag.level == "fatal":
exit()
else:
diag = False
def process_diagnostic(diag):
print("\n".join(diag.render()))
if diag.level in ("fatal", "error"):
@@ -18,8 +20,11 @@ def process_diagnostic(diag):
engine = diagnostic.Engine()
engine.process = process_diagnostic

mod = Module.from_string("".join(fileinput.input()).expandtabs(), engine=engine)
print(repr(mod))
try:
mod = Module.from_string("".join(fileinput.input()).expandtabs(), engine=engine)
print(repr(mod))
except:
if not diag: raise

if __name__ == "__main__":
main()
5 changes: 4 additions & 1 deletion artiq/compiler/transforms/artiq_ir_generator.py
Original file line number Diff line number Diff line change
@@ -565,6 +565,9 @@ def visit_IfExpT(self, node):
def visit_NumT(self, node):
return ir.Constant(node.n, node.type)

def visit_StrT(self, node):
return ir.Constant(node.s, node.type)

def visit_NameConstantT(self, node):
return ir.Constant(node.value, node.type)

@@ -1038,7 +1041,7 @@ def body_gen(index):
return result

def _compare_pair_identity(self, op, lhs, rhs):
if builtins.is_mutable(lhs) and builtins.is_mutable(rhs):
if builtins.is_allocated(lhs) and builtins.is_allocated(rhs):
# These are actually pointers, compare directly.
return self.append(ir.Compare(op, lhs, rhs))
else:
6 changes: 5 additions & 1 deletion artiq/compiler/transforms/asttyped_rewriter.py
Original file line number Diff line number Diff line change
@@ -252,6 +252,11 @@ def visit_Num(self, node):
return asttyped.NumT(type=typ,
n=node.n, loc=node.loc)

def visit_Str(self, node):
return asttyped.StrT(type=builtins.TStr(),
s=node.s,
begin_loc=node.begin_loc, end_loc=node.end_loc, loc=node.loc)

def visit_Name(self, node):
return asttyped.NameT(type=self._find_name(node.id, node.loc),
id=node.id, ctx=node.ctx, loc=node.loc)
@@ -411,7 +416,6 @@ def visit_unsupported(self, node):
visit_GeneratorExp = visit_unsupported
visit_Set = visit_unsupported
visit_SetComp = visit_unsupported
visit_Str = visit_unsupported
visit_Starred = visit_unsupported
visit_Yield = visit_unsupported
visit_YieldFrom = visit_unsupported
18 changes: 14 additions & 4 deletions artiq/compiler/transforms/llvm_ir_generator.py
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ def __init__(self, engine, module_name, context=ll.Context()):

def llty_of_type(self, typ, bare=False, for_return=False):
if types.is_tuple(typ):
return ll.LiteralStructType([self.llty_of_type(eltty) for eltty in typ.elts])
return ll.LiteralStructType([self.llty_of_type(eltty) for eltty in typ.find().elts])
elif types.is_function(typ):
envarg = ll.IntType(8).as_pointer()
llty = ll.FunctionType(args=[envarg] +
@@ -42,6 +42,8 @@ def llty_of_type(self, typ, bare=False, for_return=False):
return ll.IntType(builtins.get_int_width(typ))
elif builtins.is_float(typ):
return ll.DoubleType()
elif builtins.is_str(typ):
return ll.IntType(8).as_pointer()
elif builtins.is_list(typ):
lleltty = self.llty_of_type(builtins.get_iterable_elt(typ))
return ll.LiteralStructType([ll.IntType(32), lleltty.as_pointer()])
@@ -75,6 +77,14 @@ def llconst_of_const(self, const):
return ll.Constant(llty, False)
elif isinstance(const.value, (int, float)):
return ll.Constant(llty, const.value)
elif isinstance(const.value, str):
as_bytes = const.value.encode('utf-8')
llstrty = ll.ArrayType(ll.IntType(8), len(as_bytes))
llconst = ll.GlobalVariable(self.llmodule, llstrty,
name=self.llmodule.get_unique_name("str"))
llconst.global_constant = True
llconst.initializer = ll.Constant(llstrty, bytearray(as_bytes))
return llconst.bitcast(ll.IntType(8).as_pointer())
else:
assert False

@@ -157,7 +167,7 @@ def process_Alloc(self, insn):
size=llsize)
llvalue = self.llbuilder.insert_value(llvalue, llalloc, 1, name=insn.name)
return llvalue
elif builtins.is_mutable(insn.type):
elif builtins.is_allocated(insn.type):
assert False
else: # immutable
llvalue = ll.Constant(self.llty_of_type(insn.type), ll.Undefined)
@@ -203,7 +213,7 @@ def process_GetAttr(self, insn):
if types.is_tuple(insn.object().type):
return self.llbuilder.extract_value(self.map(insn.object()), self.attr_index(insn),
name=insn.name)
elif not builtins.is_mutable(insn.object().type):
elif not builtins.is_allocated(insn.object().type):
return self.llbuilder.extract_value(self.map(insn.object()), self.attr_index(insn),
name=insn.name)
else:
@@ -213,7 +223,7 @@ def process_GetAttr(self, insn):
return self.llbuilder.load(llptr)

def process_SetAttr(self, insn):
assert builtins.is_mutable(insns.object().type)
assert builtins.is_allocated(insns.object().type)
llptr = self.llbuilder.gep(self.map(insn.object()),
[self.llindex(0), self.llindex(self.attr_index(insn))],
name=insn.name)
21 changes: 12 additions & 9 deletions artiq/compiler/validators/escape.py
Original file line number Diff line number Diff line change
@@ -78,15 +78,15 @@ def visit_NameT(self, node):
# Value lives as long as the current scope, if it's mutable,
# or else forever
def visit_BinOpT(self, node):
if builtins.is_mutable(node.type):
if builtins.is_allocated(node.type):
return self.youngest_region
else:
return None

# Value lives as long as the object/container, if it's mutable,
# or else forever
def visit_accessor(self, node):
if builtins.is_mutable(node.type):
if builtins.is_allocated(node.type):
return self.visit(node.value)
else:
return None
@@ -125,20 +125,23 @@ def visit_allocating(self, node):
visit_ListCompT = visit_allocating
visit_SetT = visit_allocating
visit_SetCompT = visit_allocating
visit_StrT = visit_allocating

# Value lives forever
def visit_immutable(self, node):
assert not builtins.is_mutable(node.type)
assert not builtins.is_allocated(node.type)
return None

visit_CompareT = visit_immutable
visit_EllipsisT = visit_immutable
visit_NameConstantT = visit_immutable
visit_NumT = visit_immutable
visit_EllipsisT = visit_immutable
visit_UnaryOpT = visit_immutable
visit_CompareT = visit_immutable
visit_CallT = visit_immutable

# Value is mutable, but still lives forever
def visit_StrT(self, node):
return None

# Not implemented
def visit_unimplemented(self, node):
assert False
@@ -212,7 +215,7 @@ def visit_in_region(self, node, region):
self.youngest_env = {}

for name in node.typing_env:
if builtins.is_mutable(node.typing_env[name]):
if builtins.is_allocated(node.typing_env[name]):
self.youngest_env[name] = Region(None) # not yet known
else:
self.youngest_env[name] = None # lives forever
@@ -277,7 +280,7 @@ def visit_Assign(self, node):
self.visit_assignment(target, node.value)

def visit_AugAssign(self, node):
if builtins.is_mutable(node.target.type):
if builtins.is_allocated(node.target.type):
# If the target is mutable, op-assignment will allocate
# in the youngest region.
self.visit_assignment(node.target, node.value, is_aug_assign=True)
@@ -295,7 +298,7 @@ def visit_Return(self, node):
self.engine.process(diag)

def visit_Raise(self, node):
if builtins.is_mutable(node.exc.type):
if builtins.is_allocated(node.exc.type):
note = diagnostic.Diagnostic("note",
"this expression has type {type}",
{"type": types.TypePrinter().name(node.exc.type)},
4 changes: 2 additions & 2 deletions lit-test/compiler/inferencer/coerce.py
Original file line number Diff line number Diff line change
@@ -19,8 +19,8 @@
[1] * 2
# CHECK-L: [1:int(width='l)]:list(elt=int(width='l)) * 2:int(width='m):list(elt=int(width='l))

1 / 2
# CHECK-L: 1:int(width='n):int(width='o) / 2:int(width='p):int(width='o):int(width='o)
1 // 2
# CHECK-L: 1:int(width='n):int(width='o) // 2:int(width='p):int(width='o):int(width='o)

1 + 1.0
# CHECK-L: 1:int(width='q):float + 1.0:float:float
2 changes: 2 additions & 0 deletions lit-test/compiler/inferencer/unify.py
Original file line number Diff line number Diff line change
@@ -54,3 +54,5 @@
lambda x, y=1: x
# CHECK-L: lambda x:'k, y:int(width='l)=1:int(width='l): x:'k:(x:'k, ?y:int(width='l))->'k

k = "x"
# CHECK-L: k:str