Add initial vector support

This commit is contained in:
Siu Kwan Lam 2012-08-21 12:25:48 -05:00
commit 5319fb8c98
3 changed files with 74 additions and 8 deletions

View file

@ -26,6 +26,14 @@ def _is_real(ty):
lc.Type.ppc_fp128() ]
return any(ty == x for x in tys)
def _is_vector(ty, of=None):
if isinstance(ty, lc.VectorType):
if of is not None:
return of(ty.element)
return True
else:
return False
def _is_pointer(ty):
return isinstance(ty, lc.PointerType)
@ -42,6 +50,11 @@ def _is_cstruct(ty):
def _list_values(iterable):
return [i.value for i in iterable]
def _auto_coerce_index(cbldr, idx):
if not isinstance(idx, CValue):
idx = cbldr.constant(types.int, idx)
return idx
@contextlib.contextmanager
def _change_block_temporarily(builder, bb):
origbb = builder.basic_block
@ -892,11 +905,11 @@ class CValue(object):
@property
def is_int(self):
return _is_int(self.type)
return _is_int(self.type) or _is_vector(self.type, _is_int)
@property
def is_real(self):
return _is_real(self.type)
return _is_real(self.type) or _is_vector(self.type, _is_real)
def cast(self, ty, unsigned=False):
'''cast to another type
@ -984,6 +997,10 @@ class CValue(object):
return self._cmp_op('ge')(rhs)
@property
def is_vector(self):
return _is_vector(self.type)
@property
def is_pointer(self):
return _is_pointer(self.type)
@ -992,17 +1009,41 @@ class CValue(object):
if not self.is_pointer:
raise TypeError("Must be a pointer; got %s" % self.type)
def _ensure_is_vector(self):
if not self.is_vector:
raise TypeError("Must be a vector; got %s" % self.type)
def __getitem__(self, idx):
'''implement access indexing
Uses GEP.
'''
self._ensure_is_pointer()
if not isinstance(idx, CValue):
idx = self.parent.constant(types.int, idx)
bldr = self.parent.builder
ptr = bldr.gep(self.value, [idx.value])
return CVar(self.parent, ptr)
if self.is_pointer:
if type(idx) is slice:
# just handle case by case
# Case #1: A[idx:] get poointer offset by idx
if not idx.step and not idx.stop:
idx = _auto_coerce_index(self.parent, idx.start)
ptr = bldr.gep(self.value, [idx.value])
return CArray(self.parent, ptr)
else: # return an variable at idx
idx = _auto_coerce_index(self.parent, idx)
ptr = bldr.gep(self.value, [idx.value])
return CVar(self.parent, ptr)
elif self.is_vector:
idx = _auto_coerce_index(self.parent, idx)
val = bldr.extract_element(self.value, idx.value)
return CTemp(self.parent, val)
else:
raise TypeError("Must be a pointer or vector; got %s" % self.type)
def __setitem__(self, idx, val):
self._ensure_is_vector()
idx = _auto_coerce_index(self.parent, idx)
bldr = self.parent.builder
vec = bldr.insert_element(self.value, val.value, idx.value)
bldr.store(vec, self.ptr)
def load(self, volatile=False):
'''memory load for pointer types
@ -1181,6 +1222,7 @@ class CVar(CValue):
else:
return cstruct_class(self.parent, self.ptr)
class CArray(CValue):
'''wraps a array
@ -1201,6 +1243,26 @@ class CArray(CValue):
def type(self):
return self.base_ptr.type
def vector_load(self, count):
parent = self.parent
values = [self[i] for i in range(count)]
vec = parent.constant_null(types.vector(self.type.pointee, count)).value
for i, v in enumerate(values):
i = parent.constant(types.int, i)
vec = parent.builder.insert_element(vec, v.value, i.value)
return CTemp(parent, vec)
def vector_store(self, vec):
if vec.type.element != self.type.pointee:
raise TypeError("Type mismatch; expect %s but got %s" % \
(vec.type.element, self.type.pointee))
parent = self.parent
for i in range(vec.type.count):
i = parent.constant(types.int, i)
val = parent.builder.extract_element(vec.value, i.value)
self[i].assign(CTemp(parent, val))
return self
class CStruct(CValue):
'''Wraps a structure

View file

@ -61,7 +61,6 @@ class CExecutor(object):
else:
retty = typeinfo[0]
argtys = typeinfo[1:]
prototype = ct.CFUNCTYPE(retty, *argtys)
fnptr = self.engine.get_pointer_to_function(fn)
return prototype(fnptr)

View file

@ -28,3 +28,8 @@ pointer_size = _determine_pointer_size()
intp = {32: int32, 64: int64}[pointer_size]
# vector
def vector(ty, ct):
return Type.vector(ty, 4)