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

Commits on Jul 19, 2015

  1. Remove irgen tests.

    These are too hard to write and will be replaced by integration
    tests of ARTIQ IR generator + LLVM IR generator once the latter
    gets implemented.
    whitequark committed Jul 19, 2015
    Copy the full SHA
    f5d9e11 View commit details
  2. Add LocalAccessValidator.

    whitequark committed Jul 19, 2015
    Copy the full SHA
    ac491fa View commit details
73 changes: 38 additions & 35 deletions artiq/compiler/ir.py
Original file line number Diff line number Diff line change
@@ -395,6 +395,9 @@ def entry(self):
assert any(self.basic_blocks)
return self.basic_blocks[0]

def exits(self):
return [block for block in self.basic_blocks if not any(block.successors())]

def instructions(self):
for basic_block in self.basic_blocks:
yield from iter(basic_block.instructions)
@@ -508,7 +511,7 @@ def __init__(self, env, var_name, name=""):
def opcode(self):
return "getlocal({})".format(self.var_name)

def get_env(self):
def environment(self):
return self.operands[0]

class SetLocal(Instruction):
@@ -536,10 +539,10 @@ def __init__(self, env, var_name, value, name=""):
def opcode(self):
return "setlocal({})".format(self.var_name)

def get_env(self):
def environment(self):
return self.operands[0]

def get_value(self):
def value(self):
return self.operands[1]

class GetAttr(Instruction):
@@ -568,7 +571,7 @@ def __init__(self, obj, attr, name=""):
def opcode(self):
return "getattr({})".format(repr(self.attr))

def get_env(self):
def env(self):
return self.operands[0]

class SetAttr(Instruction):
@@ -597,10 +600,10 @@ def __init__(self, obj, attr, value, name=""):
def opcode(self):
return "setattr({})".format(repr(self.attr))

def get_env(self):
def env(self):
return self.operands[0]

def get_value(self):
def value(self):
return self.operands[1]

class GetElem(Instruction):
@@ -620,10 +623,10 @@ def __init__(self, lst, index, name=""):
def opcode(self):
return "getelem"

def get_list(self):
def list(self):
return self.operands[0]

def get_index(self):
def index(self):
return self.operands[1]

class SetElem(Instruction):
@@ -646,13 +649,13 @@ def __init__(self, lst, index, value, name=""):
def opcode(self):
return "setelem"

def get_list(self):
def list(self):
return self.operands[0]

def get_index(self):
def index(self):
return self.operands[1]

def get_value(self):
def value(self):
return self.operands[2]

class UnaryOp(Instruction):
@@ -675,7 +678,7 @@ def __init__(self, op, operand, name=""):
def opcode(self):
return "unaryop({})".format(type(self.op).__name__)

def get_operand(self):
def operand(self):
return self.operands[0]

class Coerce(Instruction):
@@ -691,7 +694,7 @@ def __init__(self, value, typ, name=""):
def opcode(self):
return "coerce"

def get_value(self):
def value(self):
return self.operands[0]

class BinaryOp(Instruction):
@@ -717,10 +720,10 @@ def __init__(self, op, lhs, rhs, name=""):
def opcode(self):
return "binaryop({})".format(type(self.op).__name__)

def get_lhs(self):
def lhs(self):
return self.operands[0]

def get_rhs(self):
def rhs(self):
return self.operands[1]

class Compare(Instruction):
@@ -746,10 +749,10 @@ def __init__(self, op, lhs, rhs, name=""):
def opcode(self):
return "compare({})".format(type(self.op).__name__)

def get_lhs(self):
def lhs(self):
return self.operands[0]

def get_rhs(self):
def rhs(self):
return self.operands[1]

class Builtin(Instruction):
@@ -793,7 +796,7 @@ def __init__(self, func, env, name=""):
def opcode(self):
return "closure({})".format(self.target_function.name)

def get_environment(self):
def environment(self):
return self.operands[0]

class Call(Instruction):
@@ -813,10 +816,10 @@ def __init__(self, func, args, name=""):
def opcode(self):
return "call"

def get_function(self):
def function(self):
return self.operands[0]

def get_arguments(self):
def arguments(self):
return self.operands[1:]

class Select(Instruction):
@@ -839,13 +842,13 @@ def __init__(self, cond, if_true, if_false, name=""):
def opcode(self):
return "select"

def get_condition(self):
def condition(self):
return self.operands[0]

def get_if_true(self):
def if_true(self):
return self.operands[1]

def get_if_false(self):
def if_false(self):
return self.operands[2]

class Branch(Terminator):
@@ -863,7 +866,7 @@ def __init__(self, target, name=""):
def opcode(self):
return "branch"

def get_target(self):
def target(self):
return self.operands[0]

class BranchIf(Terminator):
@@ -885,13 +888,13 @@ def __init__(self, cond, if_true, if_false, name=""):
def opcode(self):
return "branchif"

def get_condition(self):
def condition(self):
return self.operands[0]

def get_if_true(self):
def if_true(self):
return self.operands[1]

def get_if_false(self):
def if_false(self):
return self.operands[2]

class IndirectBranch(Terminator):
@@ -911,10 +914,10 @@ def __init__(self, target, destinations, name=""):
def opcode(self):
return "indirectbranch"

def get_target(self):
def target(self):
return self.operands[0]

def get_destinations(self):
def destinations(self):
return self.operands[1:]

def add_destination(self, destination):
@@ -939,7 +942,7 @@ def __init__(self, value, name=""):
def opcode(self):
return "return"

def get_value(self):
def value(self):
return self.operands[0]

class Unreachable(Terminator):
@@ -971,7 +974,7 @@ def __init__(self, value, name=""):
def opcode(self):
return "raise"

def get_value(self):
def value(self):
return self.operands[0]

class Invoke(Terminator):
@@ -995,16 +998,16 @@ def __init__(self, func, args, normal, exn, name=""):
def opcode(self):
return "invoke"

def get_function(self):
def function(self):
return self.operands[0]

def get_arguments(self):
def arguments(self):
return self.operands[1:-2]

def get_normal_target(self):
def normal_target(self):
return self.operands[-2]

def get_exception_target(self):
def exception_target(self):
return self.operands[-1]

def _operands_as_string(self):
29 changes: 15 additions & 14 deletions artiq/compiler/module.py
Original file line number Diff line number Diff line change
@@ -11,27 +11,28 @@ def __init__(self, source_buffer, engine=None):
if engine is None:
engine = diagnostic.Engine(all_errors_are_fatal=True)

module_name, _ = os.path.splitext(os.path.basename(source_buffer.name))
self.name, _ = os.path.splitext(os.path.basename(source_buffer.name))

asttyped_rewriter = transforms.ASTTypedRewriter(engine=engine)
inferencer = transforms.Inferencer(engine=engine)
int_monomorphizer = transforms.IntMonomorphizer(engine=engine)
monomorphism_validator = validators.MonomorphismValidator(engine=engine)
escape_validator = validators.EscapeValidator(engine=engine)
ir_generator = transforms.IRGenerator(engine=engine, module_name=module_name)

parsetree, comments = parse_buffer(source_buffer, engine=engine)
typedtree = asttyped_rewriter.visit(parsetree)
inferencer.visit(typedtree)
int_monomorphizer.visit(typedtree)
inferencer.visit(typedtree)
monomorphism_validator.visit(typedtree)
escape_validator.visit(typedtree)
ir_generator.visit(typedtree)

self.name = module_name
ir_generator = transforms.IRGenerator(engine=engine, module_name=self.name)
dead_code_eliminator = transforms.DeadCodeEliminator(engine=engine)
local_access_validator = validators.LocalAccessValidator(engine=engine)

self.parsetree, self.comments = parse_buffer(source_buffer, engine=engine)
self.typedtree = asttyped_rewriter.visit(self.parsetree)
self.globals = asttyped_rewriter.globals
self.ir = ir_generator.functions
inferencer.visit(self.typedtree)
int_monomorphizer.visit(self.typedtree)
inferencer.visit(self.typedtree)
monomorphism_validator.visit(self.typedtree)
escape_validator.visit(self.typedtree)
self.ir = ir_generator.visit(self.typedtree)
dead_code_eliminator.process(self.ir)
local_access_validator.process(self.ir)

@classmethod
def from_string(cls, source_string, name="input.py", first_line=1, engine=None):
20 changes: 15 additions & 5 deletions artiq/compiler/transforms/ir_generator.py
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ def visit_ModuleT(self, node):
self.generic_visit(node)
self.terminate(ir.Return(ir.Constant(None, builtins.TNone())))

return func
return self.functions
finally:
self.current_function = old_func
self.current_block = old_block
@@ -245,8 +245,18 @@ def visit_Return(self, node):
self.append(ir.Branch(self.return_target))

def visit_Expr(self, node):
# ignore the value, do it for side effects
self.visit(node.value)
# Ignore the value, do it for side effects.
result = self.visit(node.value)

# See comment in visit_Pass.
if isinstance(result, ir.Constant):
self.visit_Pass(node)

def visit_Pass(self, node):
# Insert a dummy instruction so that analyses which extract
# locations from CFG have something to use.
self.append(ir.BinaryOp(ast.Add(loc=None),
ir.Constant(0, self._size_type), ir.Constant(0, self._size_type)))

def visit_Assign(self, node):
try:
@@ -288,9 +298,9 @@ def visit_If(self, node):
if any(node.orelse):
if not if_false.is_terminated():
if_false.append(ir.Branch(tail))
head.append(ir.BranchIf(cond, if_true, if_false))
self.append(ir.BranchIf(cond, if_true, if_false), block=head)
else:
head.append(ir.BranchIf(cond, if_true, tail))
self.append(ir.BranchIf(cond, if_true, tail), block=head)

def visit_While(self, node):
try:
1 change: 1 addition & 0 deletions artiq/compiler/validators/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .monomorphism import MonomorphismValidator
from .escape import EscapeValidator
from .local_access import LocalAccessValidator
Loading