[pypy-commit] pypy vecopt-merge: input arg bytesize default to the hardware offered precision (word size)
plan_rich
noreply at buildbot.pypy.org
Tue Sep 15 12:49:07 CEST 2015
Author: Richard Plangger <planrichi at gmail.com>
Branch: vecopt-merge
Changeset: r79644:b57463d82b50
Date: 2015-09-15 12:49 +0200
http://bitbucket.org/pypy/pypy/changeset/b57463d82b50/
Log: input arg bytesize default to the hardware offered precision (word
size)
diff --git a/rpython/jit/metainterp/optimizeopt/schedule.py b/rpython/jit/metainterp/optimizeopt/schedule.py
--- a/rpython/jit/metainterp/optimizeopt/schedule.py
+++ b/rpython/jit/metainterp/optimizeopt/schedule.py
@@ -19,6 +19,7 @@
def post_schedule(self):
loop = self.graph.loop
self.renamer.rename(loop.jump)
+ loop.operations = self.oplist
def profitable(self):
return self.costmodel.profitable()
@@ -93,7 +94,7 @@
node.clear_dependencies()
node.emitted = True
- def walk_and_emit(self, state): # TODO oplist, renamer, unpack=False):
+ def walk_and_emit(self, state):
""" Emit all the operations into the oplist parameter.
Initiates the scheduling. """
assert isinstance(state, SchedulerState)
@@ -515,9 +516,6 @@
#assert vecop is not None
#args[i] = vecop
-def before_argument_transform(self, args):
- pass
-
def check_if_pack_supported(self, pack):
op0 = pack.operations[0].getoperation()
if self.input_type is None:
@@ -534,90 +532,6 @@
# see assembler for comment why
raise NotAProfitableLoop
-#def transform_result(self, result):
-# if result is None:
-# return None
-# vbox = self.new_result_vector_box()
-# #
-# # mark the position and the vbox in the hash
-# for i, node in enumerate(self.getoperations()):
-# if i >= vbox.getcount():
-# break
-# op = node.getoperation()
-# self.sched_data.setvector_of_box(op, i, vbox)
-# return vbox
-
-#def new_result_vector_box(self):
-# type = self.output_type.gettype()
-# size = self.output_type.getsize()
-# count = min(self.output_type.getcount(), len(self.pack.operations))
-# signed = self.output_type.signed
-# return BoxVector(type, count, size, signed)
-
-#def getoperations(self):
-# return self.pack.operations
-
-#def transform_arguments(self, args):
-# """ Transforming one argument to a vector box argument
-# The following cases can occur:
-# 1) argument is present in the box_to_vbox map.
-# a) vector can be reused immediatly (simple case)
-# b) vector is to big
-# c) vector is to small
-# 2) argument is not known to reside in a vector
-# a) expand vars/consts before the label and add as argument
-# b) expand vars created in the loop body
-# """
-# for i,arg in enumerate(args):
-# if arg.returns_vector():
-# continue
-# if not self.is_vector_arg(i):
-# continue
-# box_pos, vbox = self.sched_data.getvector_of_box(arg)
-# if not vbox:
-# # constant/variable expand this box
-# vbox = self.expand(arg, i)
-# self.sched_data.setvector_of_box(arg, 0, vbox)
-# box_pos = 0
-# # convert size i64 -> i32, i32 -> i64, ...
-# if self.input_type.getsize() > 0 and \
-# self.input_type.getsize() != vbox.getsize():
-# vbox = self.extend(vbox, self.input_type)
-
-# # use the input as an indicator for the pack type
-# packable = self.input_type.getcount()
-# packed = vbox.getcount()
-# assert packed >= 0
-# assert packable >= 0
-# if packed > packable:
-# # the argument has more items than the operation is able to process!
-# # box_pos == 0 then it is already at the right place
-# if box_pos != 0:
-# args[i] = self.unpack(vbox, box_pos, packed - box_pos, self.input_type)
-# self.update_arg_in_vector_pos(i, args[i])
-# #self.update_input_output(self.pack)
-# continue
-# else:
-# assert vbox is not None
-# args[i] = vbox
-# continue
-# vboxes = self.vector_boxes_for_args(i)
-# if packed < packable and len(vboxes) > 1:
-# # the argument is scattered along different vector boxes
-# args[i] = self.gather(vboxes, packable)
-# self.update_arg_in_vector_pos(i, args[i])
-# continue
-# if box_pos != 0:
-# # The vector box is at a position != 0 but it
-# # is required to be at position 0. Unpack it!
-# args[i] = self.unpack(vbox, box_pos, packed - box_pos, self.input_type)
-# self.update_arg_in_vector_pos(i, args[i])
-# continue
-# #self.update_input_output(self.pack)
-# #
-# assert vbox is not None
-# args[i] = vbox
-
def extend(self, vbox, newtype):
assert vbox.gettype() == newtype.gettype()
if vbox.gettype() == INT:
@@ -734,154 +648,6 @@
variables.append(vecop)
args[index] = vecop
-class OpToVectorOp(object):
- def __init__(self): #, restrictargs, typeoutput):
- pass
- #self.args = list(restrictargs) # do not use a tuple. rpython cannot union
- #self.out = typeoutput
-
-class OpToVectorOpConv(OpToVectorOp):
- def __init__(self, intype, outtype):
- #self.from_size = intype.getsize()
- #self.to_size = outtype.getsize()
- #OpToVectorOp.__init__(self, (intype, ), outtype)
- pass
-
- def new_result_vector_box(self):
- type = self.output_type.gettype()
- size = self.to_size
- count = self.output_type.getcount()
- vec_reg_size = self.sched_data.vec_reg_size
- if count * size > vec_reg_size:
- count = vec_reg_size // size
- signed = self.output_type.signed
- assert type in ('i','f')
- assert size > 0
- assert count > 1
- return BoxVector(type, count, size, signed)
-
- def get_output_type_given(self, input_type, op):
- return self.result_ptype
-
- def get_input_type_given(self, output_type, op):
- return self.arg_ptypes[0]
-
- def force_input(self, ptype):
- return self.arg_ptypes[0]
-
-class SignExtToVectorOp(OpToVectorOp):
- def __init__(self, intype, outtype):
- OpToVectorOp.__init__(self, intype, outtype)
- self.size = -1
-
- def before_argument_transform(self, args):
- sizearg = args[1]
- assert isinstance(sizearg, ConstInt)
- self.size = sizearg.value
-
- def new_result_vector_box(self):
- type = self.output_type.gettype()
- count = self.input_type.getcount()
- vec_reg_size = self.sched_data.vec_reg_size
- if count * self.size > vec_reg_size:
- count = vec_reg_size // self.size
- signed = self.input_type.signed
- assert type in ('i','f')
- assert self.size > 0
- assert count > 1
- return BoxVector(type, count, self.size, signed)
-
- def get_output_type_given(self, input_type, op):
- sizearg = op.getarg(1)
- assert isinstance(sizearg, ConstInt)
- output_type = input_type.clone()
- output_type.setsize(sizearg.value)
- return output_type
-
- def get_input_type_given(self, output_type, op):
- raise AssertionError("can never infer input type!")
-
-class LoadToVectorLoad(OpToVectorOp):
- def __init__(self):
- OpToVectorOp.__init__(self, (), TypeRestrict())
-
- # OLD def before_argument_transform(self, args):
- #count = min(self.output_type.getcount(), len(self.getoperations()))
- #args.append(ConstInt(count))
-
- def get_output_type_given(self, input_type, op):
- return xxx#Type.by_descr(op.getdescr(), self.sched_data.vec_reg_size)
-
- def get_input_type_given(self, output_type, op):
- return None
-
-class StoreToVectorStore(OpToVectorOp):
- """ Storing operations are special because they are not allowed
- to store to memory if the vector is not fully filled.
- Thus a modified split_pack function.
- """
- def __init__(self):
- OpToVectorOp.__init__(self, (None, None, TypeRestrict()), None)
- self.has_descr = True
-
- def must_be_full_but_is_not(self, pack):
- vrs = self.sched_data.vec_reg_size
- it = pack.input_type
- return it.getsize() * it.getcount() < vrs
-
- def get_output_type_given(self, input_type, op):
- return None
-
- def get_input_type_given(self, output_type, op):
- return xxx#Type.by_descr(op.getdescr(), self.sched_data.vec_reg_size)
-
-class PassThroughOp(OpToVectorOp):
- """ This pass through is only applicable if the target
- operation is capable of handling vector operations.
- Guard true/false is such an example.
- """
- def __init__(self, args):
- OpToVectorOp.__init__(self, args, None)
-
- def get_output_type_given(self, input_type, op):
- return None
-
- def get_input_type_given(self, output_type, op):
- raise AssertionError("cannot infer input type from output type")
-
-
-
-#def determine_input_output_types(pack, node, forward):
-# """ This function is two fold. If moving forward, it
-# gets an input type from the packs output type and returns
-# the transformed packtype.
-#
-# Moving backward, the origins pack input type is the output
-# type and the transformation of the packtype (in reverse direction)
-# is the input
-# """
-# op = node.getoperation()
-# op2vecop = determine_trans(op)
-# if forward:
-# input_type = op2vecop.force_input(pack.output_type)
-# output_type = op2vecop.get_output_type_given(input_type, op)
-# if output_type:
-# output_type = output_type.clone()
-# else:
-# # going backwards, things are not that easy anymore
-# output_type = pack.input_type
-# input_type = op2vecop.get_input_type_given(output_type, op)
-# if input_type:
-# input_type = input_type.clone()
-#
-# return input_type, output_type
-
-def determine_trans(op):
- op2vecop = trans.MAPPING.get(op.vector, None)
- if op2vecop is None:
- raise NotImplementedError("missing vecop for '%s'" % (op.getopname(),))
- return op2vecop
-
class VecScheduleState(SchedulerState):
def __init__(self, graph, packset, cpu, costmodel):
SchedulerState.__init__(self, graph)
@@ -903,8 +669,6 @@
self.unpack_from_vector(loop.jump)
SchedulerState.post_schedule(self)
- self.graph.loop.operations = self.oplist
-
# add accumulation info to the descriptor
#for version in self.loop.versions:
# # this needs to be done for renamed (accum arguments)
@@ -945,7 +709,6 @@
assert node.pack.numops() > 1
for node in node.pack.operations:
scheduler.mark_emitted(node, self)
- # TODO op2vecop = determine_trans(node.pack.leftmost())
turn_to_vector(self, node.pack)
return True
return False
@@ -1219,3 +982,239 @@
self.left = left
self.right = right
self.accum = accum
+
+#class OpToVectorOp(object):
+# def __init__(self): #, restrictargs, typeoutput):
+# pass
+# #self.args = list(restrictargs) # do not use a tuple. rpython cannot union
+# #self.out = typeoutput
+#
+#class OpToVectorOpConv(OpToVectorOp):
+# def __init__(self, intype, outtype):
+# #self.from_size = intype.getsize()
+# #self.to_size = outtype.getsize()
+# #OpToVectorOp.__init__(self, (intype, ), outtype)
+# pass
+#
+# def new_result_vector_box(self):
+# type = self.output_type.gettype()
+# size = self.to_size
+# count = self.output_type.getcount()
+# vec_reg_size = self.sched_data.vec_reg_size
+# if count * size > vec_reg_size:
+# count = vec_reg_size // size
+# signed = self.output_type.signed
+# assert type in ('i','f')
+# assert size > 0
+# assert count > 1
+# return BoxVector(type, count, size, signed)
+#
+# def get_output_type_given(self, input_type, op):
+# return self.result_ptype
+#
+# def get_input_type_given(self, output_type, op):
+# return self.arg_ptypes[0]
+#
+# def force_input(self, ptype):
+# return self.arg_ptypes[0]
+#
+#class SignExtToVectorOp(OpToVectorOp):
+# def __init__(self, intype, outtype):
+# OpToVectorOp.__init__(self, intype, outtype)
+# self.size = -1
+#
+# def before_argument_transform(self, args):
+# sizearg = args[1]
+# assert isinstance(sizearg, ConstInt)
+# self.size = sizearg.value
+#
+# def new_result_vector_box(self):
+# type = self.output_type.gettype()
+# count = self.input_type.getcount()
+# vec_reg_size = self.sched_data.vec_reg_size
+# if count * self.size > vec_reg_size:
+# count = vec_reg_size // self.size
+# signed = self.input_type.signed
+# assert type in ('i','f')
+# assert self.size > 0
+# assert count > 1
+# return BoxVector(type, count, self.size, signed)
+#
+# def get_output_type_given(self, input_type, op):
+# sizearg = op.getarg(1)
+# assert isinstance(sizearg, ConstInt)
+# output_type = input_type.clone()
+# output_type.setsize(sizearg.value)
+# return output_type
+#
+# def get_input_type_given(self, output_type, op):
+# raise AssertionError("can never infer input type!")
+#
+#class LoadToVectorLoad(OpToVectorOp):
+# def __init__(self):
+# OpToVectorOp.__init__(self, (), TypeRestrict())
+#
+# # OLD def before_argument_transform(self, args):
+# #count = min(self.output_type.getcount(), len(self.getoperations()))
+# #args.append(ConstInt(count))
+#
+# def get_output_type_given(self, input_type, op):
+# return xxx#Type.by_descr(op.getdescr(), self.sched_data.vec_reg_size)
+#
+# def get_input_type_given(self, output_type, op):
+# return None
+#
+#class StoreToVectorStore(OpToVectorOp):
+# """ Storing operations are special because they are not allowed
+# to store to memory if the vector is not fully filled.
+# Thus a modified split_pack function.
+# """
+# def __init__(self):
+# OpToVectorOp.__init__(self, (None, None, TypeRestrict()), None)
+# self.has_descr = True
+#
+# def must_be_full_but_is_not(self, pack):
+# vrs = self.sched_data.vec_reg_size
+# it = pack.input_type
+# return it.getsize() * it.getcount() < vrs
+#
+# def get_output_type_given(self, input_type, op):
+# return None
+#
+# def get_input_type_given(self, output_type, op):
+# return xxx#Type.by_descr(op.getdescr(), self.sched_data.vec_reg_size)
+#
+#class PassThroughOp(OpToVectorOp):
+# """ This pass through is only applicable if the target
+# operation is capable of handling vector operations.
+# Guard true/false is such an example.
+# """
+# def __init__(self, args):
+# OpToVectorOp.__init__(self, args, None)
+#
+# def get_output_type_given(self, input_type, op):
+# return None
+#
+# def get_input_type_given(self, output_type, op):
+# raise AssertionError("cannot infer input type from output type")
+#
+#
+#
+##def determine_input_output_types(pack, node, forward):
+## """ This function is two fold. If moving forward, it
+## gets an input type from the packs output type and returns
+## the transformed packtype.
+##
+## Moving backward, the origins pack input type is the output
+## type and the transformation of the packtype (in reverse direction)
+## is the input
+## """
+## op = node.getoperation()
+## op2vecop = determine_trans(op)
+## if forward:
+## input_type = op2vecop.force_input(pack.output_type)
+## output_type = op2vecop.get_output_type_given(input_type, op)
+## if output_type:
+## output_type = output_type.clone()
+## else:
+## # going backwards, things are not that easy anymore
+## output_type = pack.input_type
+## input_type = op2vecop.get_input_type_given(output_type, op)
+## if input_type:
+## input_type = input_type.clone()
+##
+## return input_type, output_type
+#
+#def determine_trans(op):
+# op2vecop = trans.MAPPING.get(op.vector, None)
+# if op2vecop is None:
+# raise NotImplementedError("missing vecop for '%s'" % (op.getopname(),))
+# return op2vecop
+
+
+#def before_argument_transform(self, args):
+# pass
+
+#def transform_result(self, result):
+# if result is None:
+# return None
+# vbox = self.new_result_vector_box()
+# #
+# # mark the position and the vbox in the hash
+# for i, node in enumerate(self.getoperations()):
+# if i >= vbox.getcount():
+# break
+# op = node.getoperation()
+# self.sched_data.setvector_of_box(op, i, vbox)
+# return vbox
+
+#def new_result_vector_box(self):
+# type = self.output_type.gettype()
+# size = self.output_type.getsize()
+# count = min(self.output_type.getcount(), len(self.pack.operations))
+# signed = self.output_type.signed
+# return BoxVector(type, count, size, signed)
+
+#def getoperations(self):
+# return self.pack.operations
+
+#def transform_arguments(self, args):
+# """ Transforming one argument to a vector box argument
+# The following cases can occur:
+# 1) argument is present in the box_to_vbox map.
+# a) vector can be reused immediatly (simple case)
+# b) vector is to big
+# c) vector is to small
+# 2) argument is not known to reside in a vector
+# a) expand vars/consts before the label and add as argument
+# b) expand vars created in the loop body
+# """
+# for i,arg in enumerate(args):
+# if arg.returns_vector():
+# continue
+# if not self.is_vector_arg(i):
+# continue
+# box_pos, vbox = self.sched_data.getvector_of_box(arg)
+# if not vbox:
+# # constant/variable expand this box
+# vbox = self.expand(arg, i)
+# self.sched_data.setvector_of_box(arg, 0, vbox)
+# box_pos = 0
+# # convert size i64 -> i32, i32 -> i64, ...
+# if self.input_type.getsize() > 0 and \
+# self.input_type.getsize() != vbox.getsize():
+# vbox = self.extend(vbox, self.input_type)
+
+# # use the input as an indicator for the pack type
+# packable = self.input_type.getcount()
+# packed = vbox.getcount()
+# assert packed >= 0
+# assert packable >= 0
+# if packed > packable:
+# # the argument has more items than the operation is able to process!
+# # box_pos == 0 then it is already at the right place
+# if box_pos != 0:
+# args[i] = self.unpack(vbox, box_pos, packed - box_pos, self.input_type)
+# self.update_arg_in_vector_pos(i, args[i])
+# #self.update_input_output(self.pack)
+# continue
+# else:
+# assert vbox is not None
+# args[i] = vbox
+# continue
+# vboxes = self.vector_boxes_for_args(i)
+# if packed < packable and len(vboxes) > 1:
+# # the argument is scattered along different vector boxes
+# args[i] = self.gather(vboxes, packable)
+# self.update_arg_in_vector_pos(i, args[i])
+# continue
+# if box_pos != 0:
+# # The vector box is at a position != 0 but it
+# # is required to be at position 0. Unpack it!
+# args[i] = self.unpack(vbox, box_pos, packed - box_pos, self.input_type)
+# self.update_arg_in_vector_pos(i, args[i])
+# continue
+# #self.update_input_output(self.pack)
+# #
+# assert vbox is not None
+# args[i] = vbox
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_schedule.py b/rpython/jit/metainterp/optimizeopt/test/test_schedule.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_schedule.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_schedule.py
@@ -226,12 +226,10 @@
i11 = int_signext(i1, 4)
""", additional_args=['v10[2xi64]'])
pack1 = self.pack(loop1, 0, 2)
- var = self.find_input_arg('v10', loop1)
- def i1inv103204(v):
- return 0, var
+ var = loop1.inputargs[-1]
loop2 = self.schedule(loop1, [pack1], prepend_invariant=True,
overwrite_funcs = {
- 'getvector_of_box': i1inv103204,
+ 'getvector_of_box': lambda v: (0, var),
})
loop3 = self.parse_trace("""
v11[2xi32] = vec_int_signext(v10[2xi64], 4)
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -734,11 +734,15 @@
def __init__(self, intval=0):
self.setint(intval)
self.datatype = 'i'
+ self.bytesize = INT_WORD
+ self.signed = True
class InputArgFloat(FloatOp, AbstractInputArg):
def __init__(self, f=longlong.ZEROF):
self.setfloatstorage(f)
self.datatype = 'f'
+ self.bytesize = FLOAT_WORD
+ self.signed = True
@staticmethod
def fromfloat(x):
More information about the pypy-commit
mailing list