forked from M-Labs/artiq
Remove UnaryOp ARTIQ IR instruction; rename BinaryOp to Arith.
Everything it can express can also be expressed via Arith.
This commit is contained in:
parent
ac491fae47
commit
2c010b10ee
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue