Skip to content

Commit

Permalink
Remove UnaryOp ARTIQ IR instruction; rename BinaryOp to Arith.
Browse files Browse the repository at this point in the history
Everything it can express can also be expressed via Arith.
whitequark committed Jul 19, 2015
1 parent ac491fa commit 2c010b1
Showing 2 changed files with 55 additions and 74 deletions.
31 changes: 4 additions & 27 deletions artiq/compiler/ir.py
Original file line number Diff line number Diff line change
@@ -658,29 +658,6 @@ def index(self):
def value(self):
return self.operands[2]

class UnaryOp(Instruction):
"""
An unary operation on numbers.
:ivar op: (:class:`pythonparser.ast.unaryop`) operation
"""

"""
:param op: (:class:`pythonparser.ast.unaryop`) operation
:param operand: (:class:`Value`) operand
"""
def __init__(self, op, operand, name=""):
assert isinstance(op, ast.unaryop)
assert isinstance(operand, Value)
super().__init__([operand], operand.type, name)
self.op = op

def opcode(self):
return "unaryop({})".format(type(self.op).__name__)

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

class Coerce(Instruction):
"""
A coercion operation for numbers.
@@ -697,11 +674,11 @@ def opcode(self):
def value(self):
return self.operands[0]

class BinaryOp(Instruction):
class Arith(Instruction):
"""
A binary operation on numbers.
An arithmetic operation on numbers.
:ivar op: (:class:`pythonparser.ast.unaryop`) operation
:ivar op: (:class:`pythonparser.ast.operator`) operation
"""

"""
@@ -718,7 +695,7 @@ def __init__(self, op, lhs, rhs, name=""):
self.op = op

def opcode(self):
return "binaryop({})".format(type(self.op).__name__)
return "arith({})".format(type(self.op).__name__)

def lhs(self):
return self.operands[0]
98 changes: 51 additions & 47 deletions artiq/compiler/transforms/ir_generator.py
Original file line number Diff line number Diff line change
@@ -255,8 +255,8 @@ def visit_Expr(self, 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)))
self.append(ir.Arith(ast.Add(loc=None),
ir.Constant(0, self._size_type), ir.Constant(0, self._size_type)))

def visit_Assign(self, node):
try:
@@ -270,7 +270,7 @@ def visit_Assign(self, node):
def visit_AugAssign(self, node):
lhs = self.visit(target)
rhs = self.visit(node.value)
value = self.append(ir.BinaryOp(node.op, lhs, rhs))
value = self.append(ir.Arith(node.op, lhs, rhs))
try:
self.current_assign = value
self.visit(node.target)
@@ -346,8 +346,8 @@ def _iterable_len(self, value, typ=builtins.TInt(types.TValue(32))):
start = self.append(ir.GetAttr(value, "start"))
stop = self.append(ir.GetAttr(value, "stop"))
step = self.append(ir.GetAttr(value, "step"))
spread = self.append(ir.BinaryOp(ast.Sub(loc=None), stop, start))
return self.append(ir.BinaryOp(ast.FloorDiv(loc=None), spread, step))
spread = self.append(ir.Arith(ast.Sub(loc=None), stop, start))
return self.append(ir.Arith(ast.FloorDiv(loc=None), spread, step))
else:
assert False

@@ -358,8 +358,8 @@ def _iterable_get(self, value, index):
elif builtins.is_range(value.type):
start = self.append(ir.GetAttr(value, "start"))
step = self.append(ir.GetAttr(value, "step"))
offset = self.append(ir.BinaryOp(ast.Mult(loc=None), step, index))
return self.append(ir.BinaryOp(ast.Add(loc=None), start, offset))
offset = self.append(ir.Arith(ast.Mult(loc=None), step, index))
return self.append(ir.Arith(ast.Add(loc=None), start, offset))
else:
assert False

@@ -382,8 +382,7 @@ def visit_For(self, node):
old_continue, self.continue_target = self.continue_target, continue_block
self.current_block = continue_block

updated_index = self.append(ir.BinaryOp(ast.Add(loc=None), phi,
ir.Constant(1, phi.type)))
updated_index = self.append(ir.Arith(ast.Add(loc=None), phi, ir.Constant(1, phi.type)))
phi.add_incoming(updated_index, continue_block)
self.append(ir.Branch(head))

@@ -604,7 +603,7 @@ def visit_AttributeT(self, node):
def _map_index(self, length, index):
lt_0 = self.append(ir.Compare(ast.Lt(loc=None),
index, ir.Constant(0, index.type)))
from_end = self.append(ir.BinaryOp(ast.Add(loc=None), length, index))
from_end = self.append(ir.Arith(ast.Add(loc=None), length, index))
mapped_index = self.append(ir.Select(lt_0, from_end, index))
mapped_ge_0 = self.append(ir.Compare(ast.GtE(loc=None),
mapped_index, ir.Constant(0, mapped_index.type)))
@@ -696,9 +695,9 @@ def visit_SubscriptT(self, node):
else:
step = ir.Constant(1, node.slice.type)

unstepped_size = self.append(ir.BinaryOp(ast.Sub(loc=None),
mapped_max_index, mapped_min_index))
slice_size = self.append(ir.BinaryOp(ast.FloorDiv(loc=None), unstepped_size, step))
unstepped_size = self.append(ir.Arith(ast.Sub(loc=None),
mapped_max_index, mapped_min_index))
slice_size = self.append(ir.Arith(ast.FloorDiv(loc=None), unstepped_size, step))

self._make_check(self.append(ir.Compare(ast.Eq(loc=None), slice_size, length)),
lambda: self.append(ir.Alloc([], builtins.TValueError())))
@@ -709,8 +708,8 @@ def visit_SubscriptT(self, node):
other_value = self.current_assign

def body_gen(other_index):
offset = self.append(ir.BinaryOp(ast.Mult(loc=None), step, other_index))
index = self.append(ir.BinaryOp(ast.Add(loc=None), min_index, offset))
offset = self.append(ir.Arith(ast.Mult(loc=None), step, other_index))
index = self.append(ir.Arith(ast.Add(loc=None), min_index, offset))

if self.current_assign is None:
elem = self._iterable_get(value, index)
@@ -719,8 +718,8 @@ def body_gen(other_index):
elem = self.append(ir.GetElem(self.current_assign, other_index))
self.append(ir.SetElem(value, index, elem))

return self.append(ir.BinaryOp(ast.Add(loc=None), other_index,
ir.Constant(1, node.slice.type)))
return self.append(ir.Arith(ast.Add(loc=None), other_index,
ir.Constant(1, node.slice.type)))
self._make_loop(ir.Constant(0, node.slice.type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, slice_size)),
body_gen)
@@ -790,8 +789,8 @@ def body_gen(index):

mapped_elt = self.visit(node.elt)
self.append(ir.SetElem(result, index, mapped_elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), index,
ir.Constant(1, length.type)))
return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, length.type)))
self._make_loop(ir.Constant(0, length.type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)),
body_gen)
@@ -822,8 +821,15 @@ def visit_UnaryOpT(self, node):
return self.append(ir.Select(node.operand,
ir.Constant(False, builtins.TBool()),
ir.Constant(True, builtins.TBool())))
else: # Numeric operators
return self.append(ir.UnaryOp(node.op, self.visit(node.operand)))
elif isinstance(node.op, ast.USub):
operand = self.visit(node.operand)
return self.append(ir.Arith(ast.Sub(loc=None),
ir.Constant(0, operand.type), operand))
elif isinstance(node.op, ast.UAdd):
# No-op.
return self.visit(node.operand)
else:
assert False

def visit_CoerceT(self, node):
value = self.visit(node.value)
@@ -836,9 +842,7 @@ def visit_CoerceT(self, node):

def visit_BinOpT(self, node):
if builtins.is_numeric(node.type):
return self.append(ir.BinaryOp(node.op,
self.visit(node.left),
self.visit(node.right)))
return self.append(ir.Arith(node.op, self.visit(node.left), self.visit(node.right)))
elif isinstance(node.op, ast.Add): # list + list, tuple + tuple
lhs, rhs = self.visit(node.left), self.visit(node.right)
if types.is_tuple(node.left.type) and builtins.is_tuple(node.right.type):
@@ -852,26 +856,26 @@ def visit_BinOpT(self, node):
lhs_length = self.append(ir.Builtin("len", [lhs], self._size_type))
rhs_length = self.append(ir.Builtin("len", [rhs], self._size_type))

result_length = self.append(ir.BinaryOp(ast.Add(loc=None), lhs_length, rhs_length))
result_length = self.append(ir.Arith(ast.Add(loc=None), lhs_length, rhs_length))
result = self.append(ir.Alloc([result_length], node.type))

# Copy lhs
def body_gen(index):
elt = self.append(ir.GetElem(lhs, index))
self.append(ir.SetElem(result, index, elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), index,
ir.Constant(1, self._size_type)))
return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, self._size_type)))
self._make_loop(ir.Constant(0, self._size_type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, lhs_length)),
body_gen)

# Copy rhs
def body_gen(index):
elt = self.append(ir.GetElem(rhs, index))
result_index = self.append(ir.BinaryOp(ast.Add(loc=None), index, lhs_length))
result_index = self.append(ir.Arith(ast.Add(loc=None), index, lhs_length))
self.append(ir.SetElem(result, result_index, elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), index,
ir.Constant(1, self._size_type)))
return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, self._size_type)))
self._make_loop(ir.Constant(0, self._size_type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, rhs_length)),
body_gen)
@@ -890,27 +894,27 @@ def body_gen(index):

lst_length = self.append(ir.Builtin("len", [lst], self._size_type))

result_length = self.append(ir.BinaryOp(ast.Mult(loc=None), lst_length, num))
result_length = self.append(ir.Arith(ast.Mult(loc=None), lst_length, num))
result = self.append(ir.Alloc([result_length], node.type))

# num times...
def body_gen(num_index):
# ... copy the list
def body_gen(lst_index):
elt = self.append(ir.GetElem(lst, lst_index))
base_index = self.append(ir.BinaryOp(ast.Mult(loc=None),
num_index, lst_length))
result_index = self.append(ir.BinaryOp(ast.Add(loc=None),
base_index, lst_index))
base_index = self.append(ir.Arith(ast.Mult(loc=None),
num_index, lst_length))
result_index = self.append(ir.Arith(ast.Add(loc=None),
base_index, lst_index))
self.append(ir.SetElem(result, base_index, elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), lst_index,
ir.Constant(1, self._size_type)))
return self.append(ir.Arith(ast.Add(loc=None), lst_index,
ir.Constant(1, self._size_type)))
self._make_loop(ir.Constant(0, self._size_type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, lst_length)),
body_gen)

return self.append(ir.BinaryOp(ast.Add(loc=None), lst_length,
ir.Constant(1, self._size_type)))
return self.append(ir.Arith(ast.Add(loc=None), lst_length,
ir.Constant(1, self._size_type)))
self._make_loop(ir.Constant(0, self._size_type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, num)),
body_gen)
@@ -955,8 +959,8 @@ def _compare_pair_order(self, op, lhs, rhs):

loop_body2 = self.add_block()
self.current_block = loop_body2
index_next = self.append(ir.BinaryOp(ast.Add(loc=None), index_phi,
ir.Constant(1, self._size_type)))
index_next = self.append(ir.Arith(ast.Add(loc=None), index_phi,
ir.Constant(1, self._size_type)))
self.append(ir.Branch(loop_head))
index_phi.add_incoming(index_next, loop_body2)

@@ -988,8 +992,8 @@ def _compare_pair_inclusion(self, op, needle, haystack):
step = self.append(ir.GetAttr(haystack, "step"))
after_start = self.append(ir.Compare(ast.GtE(loc=None), needle, start))
after_stop = self.append(ir.Compare(ast.Lt(loc=None), needle, stop))
from_start = self.append(ir.BinaryOp(ast.Sub(loc=None), needle, start))
mod_step = self.append(ir.BinaryOp(ast.Mod(loc=None), from_start, step))
from_start = self.append(ir.Arith(ast.Sub(loc=None), needle, start))
mod_step = self.append(ir.Arith(ast.Mod(loc=None), from_start, step))
on_step = self.append(ir.Compare(ast.Eq(loc=None), mod_step,
ir.Constant(0, mod_step.type)))
result = self.append(ir.Select(after_start, after_stop,
@@ -1008,8 +1012,8 @@ def body_gen(index):

loop_body2 = self.add_block()
self.current_block = loop_body2
return self.append(ir.BinaryOp(ast.Add(loc=None), index,
ir.Constant(1, length.type)))
return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, length.type)))
loop_head, loop_body, loop_tail = \
self._make_loop(ir.Constant(0, length.type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)),
@@ -1117,8 +1121,8 @@ def visit_builtin_call(self, node):
def body_gen(index):
elt = self._iterable_get(arg, index)
self.append(ir.SetElem(result, index, elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), index,
ir.Constant(1, length.type)))
return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, length.type)))
self._make_loop(ir.Constant(0, length.type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)),
body_gen)

0 comments on commit 2c010b1

Please sign in to comment.