Compare commits
2 commits
master
...
improvefun
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca192850ee | ||
|
|
7a77be01cc |
7 changed files with 176 additions and 1 deletions
2
llvm_array/__init__.py
Normal file
2
llvm_array/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
from __future__ import absolute_imports
|
||||||
|
from .array.py import *
|
||||||
144
llvm_array/array.py
Normal file
144
llvm_array/array.py
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
# This should be moved to llvmpy
|
||||||
|
#
|
||||||
|
# There are different array kinds parameterized by eltype and nd
|
||||||
|
#
|
||||||
|
# Contiguous or Fortran
|
||||||
|
# struct {
|
||||||
|
# eltype *data;
|
||||||
|
# intp shape[nd];
|
||||||
|
# } contiguous_array(eltype, nd)
|
||||||
|
#
|
||||||
|
# struct {
|
||||||
|
# eltype *data;
|
||||||
|
# diminfo shape[nd];
|
||||||
|
# } strided_array(eltype, nd)
|
||||||
|
#
|
||||||
|
# struct {
|
||||||
|
# eltype *data;
|
||||||
|
# intp shape[nd];
|
||||||
|
# intp stride[nd];
|
||||||
|
# } strided_soa_array(eltype, nd)
|
||||||
|
#
|
||||||
|
# struct {
|
||||||
|
# intp dim;
|
||||||
|
# intp stride;
|
||||||
|
#} diminfo
|
||||||
|
#
|
||||||
|
|
||||||
|
import llvm.core as lc
|
||||||
|
from llvm.core import Type
|
||||||
|
import llvm_cbuilder.shortnames as C
|
||||||
|
|
||||||
|
CONTIGUOUS = 1 << 8
|
||||||
|
STRIDED = CONTIGUOUS + 1
|
||||||
|
STRIDED_SOA = CONTIGUOUS + 2
|
||||||
|
|
||||||
|
array_kinds = (CONTIGUOUS, STRIDED, STRIDED_SOA)
|
||||||
|
|
||||||
|
void_type = C.void
|
||||||
|
int_type = C.int
|
||||||
|
char_type = C.char
|
||||||
|
int16_type = C.int16
|
||||||
|
intp_type = C.intp
|
||||||
|
|
||||||
|
diminfo_type = Type.struct([intp_type, # shape
|
||||||
|
intp_type # stride
|
||||||
|
], name='diminfo')
|
||||||
|
|
||||||
|
# This is the way we define LLVM arrays.
|
||||||
|
def cont_array_type(nd, el_type=char_type, name=''):
|
||||||
|
terms = [Type.pointer(el_type), # data
|
||||||
|
Type.array(intp_type, nd) # shape
|
||||||
|
]
|
||||||
|
return Type.struct(terms, name=name)
|
||||||
|
|
||||||
|
def strided_array_type(nd, el_type=char_type, name=''):
|
||||||
|
terms = [Type.pointer(el_type), # data
|
||||||
|
Type.array(diminfo_type, nd) # diminfo
|
||||||
|
]
|
||||||
|
return Type.struct(terms, name=name)
|
||||||
|
|
||||||
|
def strided_soa_type(nd, el_type=char_type, name=''):
|
||||||
|
terms = [Type.pointer(el_type), # data
|
||||||
|
Type.array(intp_type, nd), # shape[nd]
|
||||||
|
Type.array(intp_type, nd) # strides[nd]
|
||||||
|
]
|
||||||
|
return Type.struct(terms, name=name)
|
||||||
|
|
||||||
|
def check_array(arrtyp):
|
||||||
|
if not isinstance(arrtyp, lc.StructType):
|
||||||
|
return None
|
||||||
|
if arrtyp.element_count not in [2, 3]:
|
||||||
|
return None
|
||||||
|
if not isinstance(arrtyp.elements[0], lc.PointerType) or \
|
||||||
|
not isinstance(arrtyp.elements[1], lc.ArrayType):
|
||||||
|
return None
|
||||||
|
|
||||||
|
data_type = arrtyp.elements[0].pointee
|
||||||
|
s1 = arrtyp.elements[1]
|
||||||
|
nd = s1.count
|
||||||
|
|
||||||
|
if arrtyp.element_count == 3:
|
||||||
|
if not isinstance(arrtyp.elements[2], lc.ArrayType):
|
||||||
|
return None
|
||||||
|
s2 = arrtyp.elements[2]
|
||||||
|
if s1.element != intp_type or s2.element != intp_type:
|
||||||
|
return None
|
||||||
|
if s1.count != s2.count:
|
||||||
|
return None
|
||||||
|
return STRIDED_SOA, nd, data_type
|
||||||
|
|
||||||
|
if s1.element == diminfo_type:
|
||||||
|
return STRIDED, nd, data_type
|
||||||
|
elif s1.element == intp_type:
|
||||||
|
return CONTIGUOUS, nd, data_type
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_cont_array(arrtyp):
|
||||||
|
if not isinstance(arrtyp, lc.StructType):
|
||||||
|
return False
|
||||||
|
if arrtyp.element_count != 2 or \
|
||||||
|
not isinstance(arrtyp.elements[0], lc.PointerType) or \
|
||||||
|
not isinstance(arrtyp.elements[1], lc.ArrayType):
|
||||||
|
return False
|
||||||
|
if arrtyp.elements[1].element != intp_type:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_strided_array(arrtyp, kind=diminfo_type):
|
||||||
|
if not isinstance(arrtyp, lc.StructType):
|
||||||
|
return False
|
||||||
|
if arrtyp.element_count != 2 or \
|
||||||
|
not isinstance(arrtyp.elements[0], lc.PointerType) or \
|
||||||
|
not isinstance(arrtyp.elements[1], lc.ArrayType):
|
||||||
|
return False
|
||||||
|
if arrtyp.elements[1].element != kind:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_strided_soa_array(arrtyp):
|
||||||
|
if not isinstance(arrtyp, lc.StructType):
|
||||||
|
return False
|
||||||
|
if arrtyp.element_count != 3 or \
|
||||||
|
not isinstance(arrtyp.elements[0], lc.PointerType) or \
|
||||||
|
not isinstance(arrtyp.elements[1], lc.ArrayType) or \
|
||||||
|
not isinstance(arrtyp.elements[2], lc.ArrayType):
|
||||||
|
return False
|
||||||
|
s1, s2 = arrtyp.elements[1:]
|
||||||
|
if s1.element != intp_type or s2.element != intp_type:
|
||||||
|
return False
|
||||||
|
if s1.count != s2.count:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def test():
|
||||||
|
arr = cont_array_type(5)
|
||||||
|
assert check_array(arr) == (CONTIGUOUS, 5, char_type)
|
||||||
|
arr = strided_array_type(4)
|
||||||
|
assert check_array(arr) == (STRIDED, 4, char_type)
|
||||||
|
arr = strided_soa_type(3)
|
||||||
|
assert check_array(arr) == (STRIDED_SOA, 3, char_type)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test()
|
||||||
|
|
@ -3,6 +3,15 @@ from collections import defaultdict
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def silent_logger():
|
||||||
|
'''
|
||||||
|
Silent logger for unless we have a error message.
|
||||||
|
'''
|
||||||
|
logger.setLevel(logging.ERROR)
|
||||||
|
|
||||||
|
# comment out the line below to re-enable logging at DEBUG level.
|
||||||
|
silent_logger()
|
||||||
|
|
||||||
def set_debug(enabled):
|
def set_debug(enabled):
|
||||||
'''
|
'''
|
||||||
Side-effect: configure logger with it is not configured.
|
Side-effect: configure logger with it is not configured.
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ from binding import *
|
||||||
from .namespace import llvm
|
from .namespace import llvm
|
||||||
from .Value import GlobalValue, Constant, Function, Argument, Value
|
from .Value import GlobalValue, Constant, Function, Argument, Value
|
||||||
from .BasicBlock import BasicBlock
|
from .BasicBlock import BasicBlock
|
||||||
|
from .ValueSymbolTable import ValueSymbolTable
|
||||||
from .Attributes import Attributes
|
from .Attributes import Attributes
|
||||||
from .Type import Type
|
from .Type import Type
|
||||||
from .DerivedTypes import FunctionType
|
from .DerivedTypes import FunctionType
|
||||||
|
|
@ -23,7 +24,7 @@ class Function:
|
||||||
getCallingConv = Method(CallingConv.ID)
|
getCallingConv = Method(CallingConv.ID)
|
||||||
setCallingConv = Method(Void, CallingConv.ID)
|
setCallingConv = Method(Void, CallingConv.ID)
|
||||||
|
|
||||||
hasGC = Method(cast(bool, Bool))
|
hasGC = Method(cast(Bool, bool))
|
||||||
getGC = Method(cast(ConstCharPtr, str))
|
getGC = Method(cast(ConstCharPtr, str))
|
||||||
setGC = Method(Void, cast(str, ConstCharPtr))
|
setGC = Method(Void, cast(str, ConstCharPtr))
|
||||||
|
|
||||||
|
|
@ -31,6 +32,7 @@ class Function:
|
||||||
getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr)
|
getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr)
|
||||||
getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr)
|
getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr)
|
||||||
getEntryBlock = Method(ref(BasicBlock))
|
getEntryBlock = Method(ref(BasicBlock))
|
||||||
|
getValueSymbolTable = Method(ref(ValueSymbolTable))
|
||||||
|
|
||||||
copyAttributesFrom = Method(Void, ptr(GlobalValue))
|
copyAttributesFrom = Method(Void, ptr(GlobalValue))
|
||||||
|
|
||||||
|
|
@ -49,6 +51,9 @@ class Function:
|
||||||
|
|
||||||
addFnAttr = Method(Void, Attributes.AttrVal)
|
addFnAttr = Method(Void, Attributes.AttrVal)
|
||||||
removeFnAttr = Method(Void, ref(Attributes))
|
removeFnAttr = Method(Void, ref(Attributes))
|
||||||
|
#hasFnAttribute = Method(cast(Bool, bool), Attributes.AttrVal)
|
||||||
|
|
||||||
|
Create = Method(ptr(Function))
|
||||||
|
|
||||||
eraseFromParent = Method()
|
eraseFromParent = Method()
|
||||||
eraseFromParent.disowning = True
|
eraseFromParent.disowning = True
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ MDNode = llvm.Class(Value)
|
||||||
MDString = llvm.Class(Value)
|
MDString = llvm.Class(Value)
|
||||||
User = llvm.Class(Value)
|
User = llvm.Class(Value)
|
||||||
BasicBlock = llvm.Class(Value)
|
BasicBlock = llvm.Class(Value)
|
||||||
|
ValueSymbolTable = llvm.Class()
|
||||||
Constant = llvm.Class(User)
|
Constant = llvm.Class(User)
|
||||||
GlobalValue = llvm.Class(Constant)
|
GlobalValue = llvm.Class(Constant)
|
||||||
Function = llvm.Class(GlobalValue)
|
Function = llvm.Class(GlobalValue)
|
||||||
|
|
|
||||||
13
llvmpy/src/ValueSymbolTable.py
Normal file
13
llvmpy/src/ValueSymbolTable.py
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
from binding import *
|
||||||
|
from .Value import ValueSymbolTable, Value
|
||||||
|
from .ADT.StringRef import StringRef
|
||||||
|
|
||||||
|
@ValueSymbolTable
|
||||||
|
class ValueSymbolTable:
|
||||||
|
new = Constructor()
|
||||||
|
delete = Destructor()
|
||||||
|
lookup = Method(ptr(Value), cast(str, StringRef))
|
||||||
|
empty = Method(cast(Bool, bool))
|
||||||
|
size = Method(cast(Unsigned, int))
|
||||||
|
dump = Method(Void)
|
||||||
|
|
||||||
1
setup.py
1
setup.py
|
|
@ -180,6 +180,7 @@ setup(
|
||||||
packages = ['llvm', 'llvm.workaround',
|
packages = ['llvm', 'llvm.workaround',
|
||||||
'llvm_cbuilder',
|
'llvm_cbuilder',
|
||||||
'llpython',
|
'llpython',
|
||||||
|
'llvm_array',
|
||||||
'llvmpy.api', 'llvmpy.api.llvm'],
|
'llvmpy.api', 'llvmpy.api.llvm'],
|
||||||
py_modules = ['llvmpy',
|
py_modules = ['llvmpy',
|
||||||
'llvmpy._capsule',
|
'llvmpy._capsule',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue