Remove UnaryOp ARTIQ IR instruction; rename BinaryOp to Arith.

Everything it can express can also be expressed via Arith.
This commit is contained in:
whitequark 2015-07-19 11:51:53 +03:00
parent ac491fae47
commit 2c010b10ee
2 changed files with 55 additions and 74 deletions

View File

@ -658,29 +658,6 @@ class SetElem(Instruction):
def value(self): def value(self):
return self.operands[2] 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): class Coerce(Instruction):
""" """
A coercion operation for numbers. A coercion operation for numbers.
@ -697,11 +674,11 @@ class Coerce(Instruction):
def value(self): def value(self):
return self.operands[0] 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 @@ class BinaryOp(Instruction):
self.op = op self.op = op
def opcode(self): def opcode(self):
return "binaryop({})".format(type(self.op).__name__) return "arith({})".format(type(self.op).__name__)
def lhs(self): def lhs(self):
return self.operands[0] return self.operands[0]

View File

@ -255,8 +255,8 @@ class IRGenerator(algorithm.Visitor):
def visit_Pass(self, node): def visit_Pass(self, node):
# Insert a dummy instruction so that analyses which extract # Insert a dummy instruction so that analyses which extract
# locations from CFG have something to use. # locations from CFG have something to use.
self.append(ir.BinaryOp(ast.Add(loc=None), self.append(ir.Arith(ast.Add(loc=None),
ir.Constant(0, self._size_type), ir.Constant(0, self._size_type))) ir.Constant(0, self._size_type), ir.Constant(0, self._size_type)))
def visit_Assign(self, node): def visit_Assign(self, node):
try: try:
@ -270,7 +270,7 @@ class IRGenerator(algorithm.Visitor):
def visit_AugAssign(self, node): def visit_AugAssign(self, node):
lhs = self.visit(target) lhs = self.visit(target)
rhs = self.visit(node.value) rhs = self.visit(node.value)
value = self.append(ir.BinaryOp(node.op, lhs, rhs)) value = self.append(ir.Arith(node.op, lhs, rhs))
try: try:
self.current_assign = value self.current_assign = value
self.visit(node.target) self.visit(node.target)
@ -346,8 +346,8 @@ class IRGenerator(algorithm.Visitor):
start = self.append(ir.GetAttr(value, "start")) start = self.append(ir.GetAttr(value, "start"))
stop = self.append(ir.GetAttr(value, "stop")) stop = self.append(ir.GetAttr(value, "stop"))
step = self.append(ir.GetAttr(value, "step")) step = self.append(ir.GetAttr(value, "step"))
spread = self.append(ir.BinaryOp(ast.Sub(loc=None), stop, start)) spread = self.append(ir.Arith(ast.Sub(loc=None), stop, start))
return self.append(ir.BinaryOp(ast.FloorDiv(loc=None), spread, step)) return self.append(ir.Arith(ast.FloorDiv(loc=None), spread, step))
else: else:
assert False assert False
@ -358,8 +358,8 @@ class IRGenerator(algorithm.Visitor):
elif builtins.is_range(value.type): elif builtins.is_range(value.type):
start = self.append(ir.GetAttr(value, "start")) start = self.append(ir.GetAttr(value, "start"))
step = self.append(ir.GetAttr(value, "step")) step = self.append(ir.GetAttr(value, "step"))
offset = self.append(ir.BinaryOp(ast.Mult(loc=None), step, index)) offset = self.append(ir.Arith(ast.Mult(loc=None), step, index))
return self.append(ir.BinaryOp(ast.Add(loc=None), start, offset)) return self.append(ir.Arith(ast.Add(loc=None), start, offset))
else: else:
assert False assert False
@ -382,8 +382,7 @@ class IRGenerator(algorithm.Visitor):
old_continue, self.continue_target = self.continue_target, continue_block old_continue, self.continue_target = self.continue_target, continue_block
self.current_block = continue_block self.current_block = continue_block
updated_index = self.append(ir.BinaryOp(ast.Add(loc=None), phi, updated_index = self.append(ir.Arith(ast.Add(loc=None), phi, ir.Constant(1, phi.type)))
ir.Constant(1, phi.type)))
phi.add_incoming(updated_index, continue_block) phi.add_incoming(updated_index, continue_block)
self.append(ir.Branch(head)) self.append(ir.Branch(head))
@ -604,7 +603,7 @@ class IRGenerator(algorithm.Visitor):
def _map_index(self, length, index): def _map_index(self, length, index):
lt_0 = self.append(ir.Compare(ast.Lt(loc=None), lt_0 = self.append(ir.Compare(ast.Lt(loc=None),
index, ir.Constant(0, index.type))) 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_index = self.append(ir.Select(lt_0, from_end, index))
mapped_ge_0 = self.append(ir.Compare(ast.GtE(loc=None), mapped_ge_0 = self.append(ir.Compare(ast.GtE(loc=None),
mapped_index, ir.Constant(0, mapped_index.type))) mapped_index, ir.Constant(0, mapped_index.type)))
@ -696,9 +695,9 @@ class IRGenerator(algorithm.Visitor):
else: else:
step = ir.Constant(1, node.slice.type) step = ir.Constant(1, node.slice.type)
unstepped_size = self.append(ir.BinaryOp(ast.Sub(loc=None), unstepped_size = self.append(ir.Arith(ast.Sub(loc=None),
mapped_max_index, mapped_min_index)) mapped_max_index, mapped_min_index))
slice_size = self.append(ir.BinaryOp(ast.FloorDiv(loc=None), unstepped_size, step)) 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)), self._make_check(self.append(ir.Compare(ast.Eq(loc=None), slice_size, length)),
lambda: self.append(ir.Alloc([], builtins.TValueError()))) lambda: self.append(ir.Alloc([], builtins.TValueError())))
@ -709,8 +708,8 @@ class IRGenerator(algorithm.Visitor):
other_value = self.current_assign other_value = self.current_assign
def body_gen(other_index): def body_gen(other_index):
offset = self.append(ir.BinaryOp(ast.Mult(loc=None), step, other_index)) offset = self.append(ir.Arith(ast.Mult(loc=None), step, other_index))
index = self.append(ir.BinaryOp(ast.Add(loc=None), min_index, offset)) index = self.append(ir.Arith(ast.Add(loc=None), min_index, offset))
if self.current_assign is None: if self.current_assign is None:
elem = self._iterable_get(value, index) elem = self._iterable_get(value, index)
@ -719,8 +718,8 @@ class IRGenerator(algorithm.Visitor):
elem = self.append(ir.GetElem(self.current_assign, other_index)) elem = self.append(ir.GetElem(self.current_assign, other_index))
self.append(ir.SetElem(value, index, elem)) self.append(ir.SetElem(value, index, elem))
return self.append(ir.BinaryOp(ast.Add(loc=None), other_index, return self.append(ir.Arith(ast.Add(loc=None), other_index,
ir.Constant(1, node.slice.type))) ir.Constant(1, node.slice.type)))
self._make_loop(ir.Constant(0, 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)), lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, slice_size)),
body_gen) body_gen)
@ -790,8 +789,8 @@ class IRGenerator(algorithm.Visitor):
mapped_elt = self.visit(node.elt) mapped_elt = self.visit(node.elt)
self.append(ir.SetElem(result, index, mapped_elt)) self.append(ir.SetElem(result, index, mapped_elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), index, return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, length.type))) ir.Constant(1, length.type)))
self._make_loop(ir.Constant(0, length.type), self._make_loop(ir.Constant(0, length.type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)), lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)),
body_gen) body_gen)
@ -822,8 +821,15 @@ class IRGenerator(algorithm.Visitor):
return self.append(ir.Select(node.operand, return self.append(ir.Select(node.operand,
ir.Constant(False, builtins.TBool()), ir.Constant(False, builtins.TBool()),
ir.Constant(True, builtins.TBool()))) ir.Constant(True, builtins.TBool())))
else: # Numeric operators elif isinstance(node.op, ast.USub):
return self.append(ir.UnaryOp(node.op, self.visit(node.operand))) 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): def visit_CoerceT(self, node):
value = self.visit(node.value) value = self.visit(node.value)
@ -836,9 +842,7 @@ class IRGenerator(algorithm.Visitor):
def visit_BinOpT(self, node): def visit_BinOpT(self, node):
if builtins.is_numeric(node.type): if builtins.is_numeric(node.type):
return self.append(ir.BinaryOp(node.op, return self.append(ir.Arith(node.op, self.visit(node.left), self.visit(node.right)))
self.visit(node.left),
self.visit(node.right)))
elif isinstance(node.op, ast.Add): # list + list, tuple + tuple elif isinstance(node.op, ast.Add): # list + list, tuple + tuple
lhs, rhs = self.visit(node.left), self.visit(node.right) lhs, rhs = self.visit(node.left), self.visit(node.right)
if types.is_tuple(node.left.type) and builtins.is_tuple(node.right.type): if types.is_tuple(node.left.type) and builtins.is_tuple(node.right.type):
@ -852,15 +856,15 @@ class IRGenerator(algorithm.Visitor):
lhs_length = self.append(ir.Builtin("len", [lhs], self._size_type)) lhs_length = self.append(ir.Builtin("len", [lhs], self._size_type))
rhs_length = self.append(ir.Builtin("len", [rhs], 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)) result = self.append(ir.Alloc([result_length], node.type))
# Copy lhs # Copy lhs
def body_gen(index): def body_gen(index):
elt = self.append(ir.GetElem(lhs, index)) elt = self.append(ir.GetElem(lhs, index))
self.append(ir.SetElem(result, index, elt)) self.append(ir.SetElem(result, index, elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), index, return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, self._size_type))) ir.Constant(1, self._size_type)))
self._make_loop(ir.Constant(0, 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)), lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, lhs_length)),
body_gen) body_gen)
@ -868,10 +872,10 @@ class IRGenerator(algorithm.Visitor):
# Copy rhs # Copy rhs
def body_gen(index): def body_gen(index):
elt = self.append(ir.GetElem(rhs, 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)) self.append(ir.SetElem(result, result_index, elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), index, return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, self._size_type))) ir.Constant(1, self._size_type)))
self._make_loop(ir.Constant(0, 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)), lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, rhs_length)),
body_gen) body_gen)
@ -890,7 +894,7 @@ class IRGenerator(algorithm.Visitor):
lst_length = self.append(ir.Builtin("len", [lst], self._size_type)) 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)) result = self.append(ir.Alloc([result_length], node.type))
# num times... # num times...
@ -898,19 +902,19 @@ class IRGenerator(algorithm.Visitor):
# ... copy the list # ... copy the list
def body_gen(lst_index): def body_gen(lst_index):
elt = self.append(ir.GetElem(lst, lst_index)) elt = self.append(ir.GetElem(lst, lst_index))
base_index = self.append(ir.BinaryOp(ast.Mult(loc=None), base_index = self.append(ir.Arith(ast.Mult(loc=None),
num_index, lst_length)) num_index, lst_length))
result_index = self.append(ir.BinaryOp(ast.Add(loc=None), result_index = self.append(ir.Arith(ast.Add(loc=None),
base_index, lst_index)) base_index, lst_index))
self.append(ir.SetElem(result, base_index, elt)) self.append(ir.SetElem(result, base_index, elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), lst_index, return self.append(ir.Arith(ast.Add(loc=None), lst_index,
ir.Constant(1, self._size_type))) ir.Constant(1, self._size_type)))
self._make_loop(ir.Constant(0, 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)), lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, lst_length)),
body_gen) body_gen)
return self.append(ir.BinaryOp(ast.Add(loc=None), lst_length, return self.append(ir.Arith(ast.Add(loc=None), lst_length,
ir.Constant(1, self._size_type))) ir.Constant(1, self._size_type)))
self._make_loop(ir.Constant(0, self._size_type), self._make_loop(ir.Constant(0, self._size_type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, num)), lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, num)),
body_gen) body_gen)
@ -955,8 +959,8 @@ class IRGenerator(algorithm.Visitor):
loop_body2 = self.add_block() loop_body2 = self.add_block()
self.current_block = loop_body2 self.current_block = loop_body2
index_next = self.append(ir.BinaryOp(ast.Add(loc=None), index_phi, index_next = self.append(ir.Arith(ast.Add(loc=None), index_phi,
ir.Constant(1, self._size_type))) ir.Constant(1, self._size_type)))
self.append(ir.Branch(loop_head)) self.append(ir.Branch(loop_head))
index_phi.add_incoming(index_next, loop_body2) index_phi.add_incoming(index_next, loop_body2)
@ -988,8 +992,8 @@ class IRGenerator(algorithm.Visitor):
step = self.append(ir.GetAttr(haystack, "step")) step = self.append(ir.GetAttr(haystack, "step"))
after_start = self.append(ir.Compare(ast.GtE(loc=None), needle, start)) after_start = self.append(ir.Compare(ast.GtE(loc=None), needle, start))
after_stop = self.append(ir.Compare(ast.Lt(loc=None), needle, stop)) after_stop = self.append(ir.Compare(ast.Lt(loc=None), needle, stop))
from_start = self.append(ir.BinaryOp(ast.Sub(loc=None), needle, start)) from_start = self.append(ir.Arith(ast.Sub(loc=None), needle, start))
mod_step = self.append(ir.BinaryOp(ast.Mod(loc=None), from_start, step)) 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, on_step = self.append(ir.Compare(ast.Eq(loc=None), mod_step,
ir.Constant(0, mod_step.type))) ir.Constant(0, mod_step.type)))
result = self.append(ir.Select(after_start, after_stop, result = self.append(ir.Select(after_start, after_stop,
@ -1008,8 +1012,8 @@ class IRGenerator(algorithm.Visitor):
loop_body2 = self.add_block() loop_body2 = self.add_block()
self.current_block = loop_body2 self.current_block = loop_body2
return self.append(ir.BinaryOp(ast.Add(loc=None), index, return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, length.type))) ir.Constant(1, length.type)))
loop_head, loop_body, loop_tail = \ loop_head, loop_body, loop_tail = \
self._make_loop(ir.Constant(0, length.type), self._make_loop(ir.Constant(0, length.type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)), lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)),
@ -1117,8 +1121,8 @@ class IRGenerator(algorithm.Visitor):
def body_gen(index): def body_gen(index):
elt = self._iterable_get(arg, index) elt = self._iterable_get(arg, index)
self.append(ir.SetElem(result, index, elt)) self.append(ir.SetElem(result, index, elt))
return self.append(ir.BinaryOp(ast.Add(loc=None), index, return self.append(ir.Arith(ast.Add(loc=None), index,
ir.Constant(1, length.type))) ir.Constant(1, length.type)))
self._make_loop(ir.Constant(0, length.type), self._make_loop(ir.Constant(0, length.type),
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)), lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)),
body_gen) body_gen)