diff --git a/CHANGELOG b/CHANGELOG index 45d6a5f..5af6169 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,40 +1,3 @@ -2014-04-28 0.12.5: ---------------------- - * Fixes memory leaks (#92) - * Fixes tarball (#99) - -2014-03-20 0.12.4: ---------------------- - * Add dylib_import_library and friends - * Fix BasicBlock downcast - * Module hashing - * Fix test script - -2014-02-18 0.12.3: ---------------------- - * Fix deprecation message for py2.6 - * Fix llvm_cbuilder for using deprecated_alloca - * Merged PR #88 by cantora - * Merged PR #94 by cgohlke - -2014-02-04 0.12.2: ---------------------- - * enhance wrapper efficiency by moving some capsule code into C++ - * fix unclosed file handler in avx_support - * multiple-dimension insert_value, extract_value - * various minor fixes - -2013-11-11 0.12.1: ---------------------- - * various bug fixes - -2013-08-28 0.12.0: ---------------------- - * update to LLVM 3.3 and maintain compatibility with LLVM 3.2 - * add LLRT for minimal support for 64-bit divmod on 32-bit platform - * start to adopt MCJIT (not quite usable on win32) - * various bug fixes - 2013-03-05 0.11.1: -------------------- * fix test when cc is not available diff --git a/MANIFEST.in b/MANIFEST.in index 25a211d..295794c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,5 @@ -include CHANGELOG LICENSE README.rst setup.py MANIFEST.in versioneer.py +include CHANGELOG LICENSE README setup.py MANIFEST.in recursive-include llvm * -recursive-include llvmpy * recursive-include www * recursive-include test * recursive-include tools * diff --git a/README.rst b/README.rst index a1abf84..0fbcd24 100644 --- a/README.rst +++ b/README.rst @@ -30,13 +30,10 @@ Quickstart to separate your custom build from the default system package. Please replace ``LLVM_INSTALL_PATH`` with your own path. -3. Run ``REQUIRES_RTTI=1 make install`` to build and install. +3. Run ``REQUIRES_RTTI=1 make`` to build. **Note**: With LLVM 3.2, the default build configuration has C++ RTTI disabled. However, llvmpy requires RTTI. - - **Note**: Use ``make -j2 install`` to enable concurrent build. - Replace ``2`` with the actual number of processor you have. 4. Get llvm-py and install it:: diff --git a/buildscripts/condarecipe/meta.yaml b/buildscripts/condarecipe/meta.yaml index 4612840..b079986 100644 --- a/buildscripts/condarecipe/meta.yaml +++ b/buildscripts/condarecipe/meta.yaml @@ -1,6 +1,6 @@ package: name: llvmpy - version: 99.9.9 + version: master source: git_url: git@github.com:llvmpy/llvmpy.git @@ -10,7 +10,7 @@ requirements: build: - llvm - python - #- chrpath [linux] + - chrpath [linux] run: - llvm [unix] - python diff --git a/buildscripts/condarecipe/run_test.py b/buildscripts/condarecipe/run_test.py index 682b8d4..281a599 100644 --- a/buildscripts/condarecipe/run_test.py +++ b/buildscripts/condarecipe/run_test.py @@ -4,8 +4,6 @@ import llvm from llvm.core import Module from llvm.ee import EngineBuilder -from llvm.utils import check_intrinsics - m = Module.new('fjoidajfa') eb = EngineBuilder.new(m) target = eb.select_target() @@ -15,8 +13,7 @@ if sys.platform == 'darwin': s = {'64bit': 'x86_64', '32bit': 'x86'}[platform.architecture()[0]] assert target.triple.startswith(s + '-apple-darwin') -assert llvm.test(verbosity=2, run_isolated=False) == 0 -#check_intrinsics.main() +assert llvm.test(verbosity=2) == 0 print('llvm.__version__: %s' % llvm.__version__) #assert llvm.__version__ == '0.12.0' diff --git a/docs/source/index.rst b/docs/source/index.rst index fbf5c8b..7798b77 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -llvmpy -====== +Documentation for llvmpy +======================== Contents: @@ -22,7 +22,7 @@ Contents: Indices and tables ------------------- +================== * :ref:`genindex` * :ref:`modindex` diff --git a/example/vector_instr.py b/example/vector_instr.py deleted file mode 100644 index e49d06a..0000000 --- a/example/vector_instr.py +++ /dev/null @@ -1,152 +0,0 @@ -''' -This example shows: -1) how to use vector instructions -2) how to take advantage of LLVM loop vectorization to transform scalar - operations to vector operations -''' - -from __future__ import print_function -import llvm.core as lc -import llvm.ee as le -import llvm.passes as lp -from ctypes import CFUNCTYPE, POINTER, c_int, c_float - -def build_manual_vector(): - mod = lc.Module.new('manual.vector') - intty = lc.Type.int(32) - vecty = lc.Type.vector(lc.Type.float(), 4) - aryty = lc.Type.pointer(lc.Type.float()) - fnty = lc.Type.function(lc.Type.void(), [aryty, aryty, aryty, intty]) - fn = mod.add_function(fnty, name='vector_add') - bbentry = fn.append_basic_block('entry') - bbloopcond = fn.append_basic_block('loop.cond') - bbloopbody = fn.append_basic_block('loop.body') - bbexit = fn.append_basic_block('exit') - builder = lc.Builder.new(bbentry) - - # populate function body - in1, in2, out, size = fn.args - ZERO = lc.Constant.null(intty) - loopi_ptr = builder.alloca(intty) - builder.store(ZERO, loopi_ptr) - - builder.branch(bbloopcond) - builder.position_at_end(bbloopcond) - - loopi = builder.load(loopi_ptr) - loopcond = builder.icmp(lc.ICMP_ULT, loopi, size) - - builder.cbranch(loopcond, bbloopbody, bbexit) - builder.position_at_end(bbloopbody) - - vecaryty = lc.Type.pointer(vecty) - in1asvec = builder.bitcast(builder.gep(in1, [loopi]), vecaryty) - in2asvec = builder.bitcast(builder.gep(in2, [loopi]), vecaryty) - outasvec = builder.bitcast(builder.gep(out, [loopi]), vecaryty) - - vec1 = builder.load(in1asvec) - vec2 = builder.load(in2asvec) - - vecout = builder.fadd(vec1, vec2) - - builder.store(vecout, outasvec) - - next = builder.add(loopi, lc.Constant.int(intty, 4)) - builder.store(next, loopi_ptr) - - builder.branch(bbloopcond) - builder.position_at_end(bbexit) - - builder.ret_void() - - return mod, fn - - -def build_auto_vector(): - mod = lc.Module.new('auto.vector') - # Loop vectorize is sensitive to the size of the index size(!?) - intty = lc.Type.int(tuple.__itemsize__ * 8) - aryty = lc.Type.pointer(lc.Type.float()) - fnty = lc.Type.function(lc.Type.void(), [aryty, aryty, aryty, intty]) - fn = mod.add_function(fnty, name='vector_add') - bbentry = fn.append_basic_block('entry') - bbloopcond = fn.append_basic_block('loop.cond') - bbloopbody = fn.append_basic_block('loop.body') - bbexit = fn.append_basic_block('exit') - builder = lc.Builder.new(bbentry) - - # populate function body - in1, in2, out, size = fn.args - in1.add_attribute(lc.ATTR_NO_ALIAS) - in2.add_attribute(lc.ATTR_NO_ALIAS) - out.add_attribute(lc.ATTR_NO_ALIAS) - ZERO = lc.Constant.null(intty) - loopi_ptr = builder.alloca(intty) - builder.store(ZERO, loopi_ptr) - - builder.branch(bbloopcond) - builder.position_at_end(bbloopcond) - - loopi = builder.load(loopi_ptr) - loopcond = builder.icmp(lc.ICMP_ULT, loopi, size) - - builder.cbranch(loopcond, bbloopbody, bbexit) - builder.position_at_end(bbloopbody) - - in1elem = builder.load(builder.gep(in1, [loopi])) - in2elem = builder.load(builder.gep(in2, [loopi])) - - outelem = builder.fadd(in1elem, in2elem) - - builder.store(outelem, builder.gep(out, [loopi])) - - next = builder.add(loopi, lc.Constant.int(intty, 1)) - builder.store(next, loopi_ptr) - - builder.branch(bbloopcond) - builder.position_at_end(bbexit) - - builder.ret_void() - - return mod, fn - -def example(title, module_builder, opt): - print(title.center(80, '=')) - mod, fn = module_builder() - - eb = le.EngineBuilder.new(mod).opt(3) - if opt: - print('opt') - tm = eb.select_target() - pms = lp.build_pass_managers(mod=mod, tm=tm, opt=3, loop_vectorize=True, - fpm=False) - pms.pm.run(mod) - - print(mod) - print(mod.to_native_assembly()) - - engine = eb.create() - ptr = engine.get_pointer_to_function(fn) - - callable = CFUNCTYPE(None, POINTER(c_float), POINTER(c_float), - POINTER(c_float), c_int)(ptr) - - N = 20 - in1 = (c_float * N)(*range(N)) - in2 = (c_float * N)(*range(N)) - out = (c_float * N)() - - print('in1: ', list(in1)) - print('in1: ', list(in2)) - - callable(in1, in2, out, N) - - print('out', list(out)) - - -def main(): - example('manual vector function', build_manual_vector, False) - example('auto vector function', build_auto_vector, True) - -if __name__ == '__main__': - main() diff --git a/llpython/byte_control.py b/llpython/byte_control.py index 8ca407e..acd5a41 100644 --- a/llpython/byte_control.py +++ b/llpython/byte_control.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import import opcode diff --git a/llpython/byte_flow.py b/llpython/byte_flow.py index 197c839..2201791 100644 --- a/llpython/byte_flow.py +++ b/llpython/byte_flow.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import import dis diff --git a/llpython/byte_translator.py b/llpython/byte_translator.py index a6e5864..9b6d2de 100644 --- a/llpython/byte_translator.py +++ b/llpython/byte_translator.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ '''Defines a bytecode based LLVM translator for llpython code. ''' diff --git a/llpython/bytecode_visitor.py b/llpython/bytecode_visitor.py index 3fa3f48..009d1a0 100644 --- a/llpython/bytecode_visitor.py +++ b/llpython/bytecode_visitor.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import import itertools diff --git a/llpython/bytetype.py b/llpython/bytetype.py index 484d09e..211f3f8 100644 --- a/llpython/bytetype.py +++ b/llpython/bytetype.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import ctypes diff --git a/llpython/control_flow.py b/llpython/control_flow.py index 8026aba..5ea030a 100644 --- a/llpython/control_flow.py +++ b/llpython/control_flow.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import pprint diff --git a/llpython/gen_bytecode_visitor.py b/llpython/gen_bytecode_visitor.py index a60b345..b29bc56 100644 --- a/llpython/gen_bytecode_visitor.py +++ b/llpython/gen_bytecode_visitor.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import from . import opcode_util diff --git a/llpython/nobitey.py b/llpython/nobitey.py index 4236d29..68bde5f 100644 --- a/llpython/nobitey.py +++ b/llpython/nobitey.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import import sys diff --git a/llpython/opcode_util.py b/llpython/opcode_util.py index 7a1972b..efd0c5c 100644 --- a/llpython/opcode_util.py +++ b/llpython/opcode_util.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import dis diff --git a/llpython/phi_injector.py b/llpython/phi_injector.py index dfa1061..ee28ab5 100644 --- a/llpython/phi_injector.py +++ b/llpython/phi_injector.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from .bytecode_visitor import BytecodeFlowVisitor, BenignBytecodeVisitorMixin diff --git a/llpython/pyaddfunc.py b/llpython/pyaddfunc.py index d6a2945..8e09839 100644 --- a/llpython/pyaddfunc.py +++ b/llpython/pyaddfunc.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import ctypes diff --git a/llpython/tests/llfuncs.py b/llpython/tests/llfuncs.py index 8b5b1f3..2a8614f 100644 --- a/llpython/tests/llfuncs.py +++ b/llpython/tests/llfuncs.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ def doslice (in_string, lower, upper): diff --git a/llpython/tests/llfunctys.py b/llpython/tests/llfunctys.py index 8335044..b552cf4 100644 --- a/llpython/tests/llfunctys.py +++ b/llpython/tests/llfunctys.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import llvm.core as lc diff --git a/llvm-config-win32.py b/llvm-config-win32.py index 3f756ee..8c268cb 100644 --- a/llvm-config-win32.py +++ b/llvm-config-win32.py @@ -2,7 +2,6 @@ import re import sys from distutils.spawn import find_executable from os.path import abspath, dirname, isfile, join -from os import listdir from subprocess import Popen, PIPE @@ -40,17 +39,57 @@ def libs_options(): # NOTE: instead of actually looking at the components requested, # we just print out a bunch of libs for lib in """ +LLVMAnalysis +LLVMAsmParser +LLVMAsmPrinter +LLVMBitReader +LLVMBitWriter +LLVMCodeGen +LLVMCore +LLVMExecutionEngine +LLVMInstCombine +LLVMInstrumentation +LLVMInterpreter +LLVMipa +LLVMipo +LLVMJIT +LLVMMCJIT +LLVMLinker +LLVMMC +LLVMMCParser +LLVMObject +LLVMRuntimeDyld +LLVMScalarOpts +LLVMSelectionDAG +LLVMSupport +LLVMTarget +LLVMTransformUtils +LLVMVectorize +LLVMX86AsmParser +LLVMX86AsmPrinter +LLVMX86CodeGen +LLVMX86Desc +LLVMX86Disassembler +LLVMX86Info +LLVMX86Utils +LLVMDebugInfo Advapi32 Shell32 """.split(): print('-l%s' % lib) - bpath = join(find_llvm_prefix(), 'lib') - for filename in listdir(bpath): - filepath = join(bpath, filename) - if isfile(filepath) and filename.endswith('.lib') and filename.startswith('LLVM'): - name = filename.split('.', 1)[0] - print('-l%s' % name) + if isfile(join(find_llvm_prefix(), 'lib', 'LLVMPTXCodeGen.lib')): + print('-lLLVMPTXAsmPrinter') + print('-lLLVMPTXCodeGen') + print('-lLLVMPTXDesc') + print('-lLLVMPTXInfo') + + elif isfile(join(find_llvm_prefix(), 'lib', 'LLVMNVPTXCodeGen.lib')): + print('-lLLVMNVPTXAsmPrinter') + print('-lLLVMNVPTXCodeGen') + print('-lLLVMNVPTXDesc') + print('-lLLVMNVPTXInfo') + def main(): try: diff --git a/llvm/__init__.py b/llvm/__init__.py index 9b24112..8f71446 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -4,13 +4,10 @@ del get_versions from llvmpy import extra - version = extra.get_llvm_version() del extra class Wrapper(object): - __slots__ = '__ptr' - def __init__(self, ptr): assert ptr self.__ptr = ptr @@ -34,14 +31,14 @@ def _extract_ptrs(objs): class LLVMException(Exception): pass -def test(verbosity=3, run_isolated=True): +def test(verbosity=1): """test(verbosity=1) -> TextTestResult Run self-test, and return the number of failures + errors """ - from llvm.tests import run + from llvm.test_llvmpy import run - result = run(verbosity=verbosity, run_isolated=run_isolated) - errct = len(result.failures) + len(result.errors) + result = run(verbosity=verbosity) + + return len(result.failures) + len(result.errors) - return errct diff --git a/llvm/core.py b/llvm/core.py index 4db8135..c4fe560 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -41,7 +41,7 @@ import contextlib, weakref import llvm from llvm._intrinsic_ids import * -from llvm.deprecated import deprecated + from llvmpy import api #===----------------------------------------------------------------------=== @@ -211,17 +211,15 @@ class CCEnum(Enum): CC_X86_THISCALL = ID.X86_ThisCall CC_PTX_KERNEL = ID.PTX_Kernel CC_PTX_DEVICE = ID.PTX_Device - - if llvm.version <= (3, 3): - CC_MBLAZE_INTR = ID.MBLAZE_INTR - CC_MBLAZE_SVOL = ID.MBLAZE_SVOL + CC_MBLAZE_INTR = ID.MBLAZE_INTR + CC_MBLAZE_SVOL = ID.MBLAZE_SVOL CCEnum.declare() # int predicates class ICMPEnum(Enum): prefix = 'ICMP_' - + Predicate = api.llvm.CmpInst.Predicate ICMP_EQ = Predicate.ICMP_EQ @@ -379,7 +377,6 @@ class Module(llvm.Wrapper): module_obj = Module.new('my_module') """ - __slots__ = '__weakref__' __cache = weakref.WeakValueDictionary() def __new__(cls, ptr): @@ -452,12 +449,12 @@ class Module(llvm.Wrapper): """ return str(self._ptr) - def __hash__(self): - return id(self._ptr) - def __eq__(self, rhs): + assert isinstance(rhs, Module), type(rhs) if isinstance(rhs, Module): - return self._ptr == rhs._ptr + return str(self) == str(rhs) + else: + return False def __ne__(self, rhs): return not (self == rhs) @@ -689,7 +686,6 @@ class Type(llvm.Wrapper): Use one of the static methods to create an instance. Example: ty = Type.double() """ - __slots__ = '__name__' _type_ = api.llvm.Type def __init__(self, ptr): @@ -882,7 +878,6 @@ class Type(llvm.Wrapper): class IntegerType(Type): """Represents an integer type.""" - __slots__ = () _type_ = api.llvm.IntegerType @property @@ -892,7 +887,6 @@ class IntegerType(Type): class FunctionType(Type): """Represents a function type.""" - __slots__ = () _type_ = api.llvm.FunctionType @property @@ -922,7 +916,6 @@ class FunctionType(Type): class StructType(Type): """Represents a structure type.""" _type_ = api.llvm.StructType - __slots__ = () @property def element_count(self): @@ -958,7 +951,7 @@ class StructType(Type): def _get_name(self): if self._ptr.isLiteral(): return "" - else: + else: return self._ptr.getName() name = property(_get_name, _set_name) @@ -981,7 +974,6 @@ class StructType(Type): class ArrayType(Type): """Represents an array type.""" _type_ = api.llvm.ArrayType - __slots__ = () @property def element(self): @@ -993,7 +985,6 @@ class ArrayType(Type): class PointerType(Type): _type_ = api.llvm.PointerType - __slots__ = () @property def pointee(self): @@ -1005,7 +996,6 @@ class PointerType(Type): class VectorType(Type): _type_ = api.llvm.VectorType - __slots__ = () @property def element(self): @@ -1017,7 +1007,6 @@ class VectorType(Type): class Value(llvm.Wrapper): _type_ = api.llvm.Value - __slots__ = '__weakref__' def __init__(self, builder, ptr): assert builder is _ValueFactory @@ -1048,9 +1037,6 @@ class Value(llvm.Wrapper): def __str__(self): return str(self._ptr) - def __hash__(self): - return hash(self._ptr) - def __eq__(self, rhs): if isinstance(rhs, Value): return str(self) == str(rhs) @@ -1086,7 +1072,6 @@ class Value(llvm.Wrapper): class User(Value): _type_ = api.llvm.User - __slots__ = () @property def operand_count(self): @@ -1101,7 +1086,6 @@ class User(Value): class Constant(User): _type_ = api.llvm.Constant - __slots__ = () @staticmethod def null(ty): @@ -1287,7 +1271,6 @@ class Constant(User): class ConstantExpr(Constant): _type_ = api.llvm.ConstantExpr - __slots__ = () @property def opcode(self): @@ -1298,20 +1281,19 @@ class ConstantExpr(Constant): return self._ptr.getOpcodeName() class ConstantAggregateZero(Constant): - __slots__ = () + pass class ConstantDataArray(Constant): - __slots__ = () + pass class ConstantDataVector(Constant): - __slots__ = () + pass class ConstantInt(Constant): _type_ = api.llvm.ConstantInt - __slots__ = () @property def z_ext_value(self): @@ -1327,32 +1309,30 @@ class ConstantInt(Constant): class ConstantFP(Constant): - __slots__ = () + pass class ConstantArray(Constant): - __slots__ = () + pass class ConstantStruct(Constant): - __slots__ = () + pass class ConstantVector(Constant): - __slots__ = () + pass class ConstantPointerNull(Constant): - __slots__ = () + pass class UndefValue(Constant): - __slots__ = () - + pass class GlobalValue(Constant): _type_ = api.llvm.GlobalValue - __slots__ = () def _get_linkage(self): return self._ptr.getLinkage() @@ -1398,7 +1378,6 @@ class GlobalValue(Constant): class GlobalVariable(GlobalValue): _type_ = api.llvm.GlobalVariable - __slots__ = () @staticmethod def new(module, ty, name, addrspace=0): @@ -1459,7 +1438,6 @@ class GlobalVariable(GlobalValue): thread_local = property(_get_thread_local, _set_thread_local) class Argument(Value): - __slots__ = () _type_ = api.llvm.Argument _valid_attrs = frozenset([ATTR_BY_VAL, ATTR_NEST, ATTR_NO_ALIAS, ATTR_NO_CAPTURE, ATTR_STRUCT_RET]) @@ -1471,7 +1449,7 @@ class Argument(Value): attrbldr.addAttribute(attr) attrs = api.llvm.AttributeSet.get(context, 0, attrbldr) self._ptr.addAttr(attrs) - + if attr not in self: raise ValueError("Attribute %r is not valid for arg %s" % (attr, self)) @@ -1560,7 +1538,6 @@ class Argument(Value): return self._ptr.hasStructRetAttr() class Function(GlobalValue): - __slots__ = () _type_ = api.llvm.Function @staticmethod @@ -1670,10 +1647,7 @@ class Function(GlobalValue): context = api.llvm.getGlobalContext() attrbldr = api.llvm.AttrBuilder.new() attrbldr.addAttribute(attr) - if llvm.version >= (3, 3): - attrs = api.llvm.Attribute.get(context, attrbldr) - else: - attrs = api.llvm.Attributes.get(context, attrbldr) + attrs = api.llvm.Attributes.get(context, attrbldr) self._ptr.removeFnAttr(attrs) def viewCFGOnly(self): @@ -1699,7 +1673,6 @@ class Function(GlobalValue): #===----------------------------------------------------------------------=== class InlineAsm(Value): - __slots__ = () _type_ = api.llvm.InlineAsm @staticmethod @@ -1714,7 +1687,6 @@ class InlineAsm(Value): #===----------------------------------------------------------------------=== class MetaData(Value): - __slots__ = () _type_ = api.llvm.MDNode @staticmethod @@ -1771,7 +1743,6 @@ class MetaDataString(Value): class NamedMetaData(llvm.Wrapper): - __slots__ = () @staticmethod def get_or_insert(mod, name): @@ -1801,7 +1772,6 @@ class NamedMetaData(llvm.Wrapper): #===----------------------------------------------------------------------=== class Instruction(User): - __slots__ = () _type_ = api.llvm.Instruction @property @@ -1883,7 +1853,6 @@ class Instruction(User): class CallOrInvokeInstruction(Instruction): - __slots__ = () _type_ = api.llvm.CallInst, api.llvm.InvokeInst def _get_cc(self): @@ -1898,33 +1867,21 @@ class CallOrInvokeInstruction(Instruction): context = api.llvm.getGlobalContext() attrbldr = api.llvm.AttrBuilder.new() attrbldr.addAttribute(attr) - if llvm.version >= (3, 3): - attrs = api.llvm.Attribute.get(context, attrbldr) - else: - attrs = api.llvm.Attributes.get(context, attrbldr) - + attrs = api.llvm.Attributes.get(context, attrbldr) self._ptr.addAttribute(idx, attrs) def remove_parameter_attribute(self, idx, attr): context = api.llvm.getGlobalContext() attrbldr = api.llvm.AttrBuilder.new() attrbldr.addAttribute(attr) - if llvm.version >= (3, 3): - attrs = api.llvm.Attribute.get(context, attrbldr) - else: - attrs = api.llvm.Attributes.get(context, attrbldr) - + attrs = api.llvm.Attributes.get(context, attrbldr) self._ptr.removeAttribute(idx, attrs) def set_parameter_alignment(self, idx, align): context = api.llvm.getGlobalContext() attrbldr = api.llvm.AttrBuilder.new() attrbldr.addAlignmentAttr(align) - if llvm.version >= (3, 3): - attrs = api.llvm.Attribute.get(context, attrbldr) - else: - attrs = api.llvm.Attributes.get(context, attrbldr) - + attrs = api.llvm.Attributes.get(context, attrbldr) self._ptr.addAttribute(idx, attrs) def _get_called_function(self): @@ -1939,7 +1896,6 @@ class CallOrInvokeInstruction(Instruction): class PHINode(Instruction): - __slots__ = () _type_ = api.llvm.PHINode @property @@ -1957,7 +1913,6 @@ class PHINode(Instruction): class SwitchInstruction(Instruction): - __slots__ = () _type_ = api.llvm.SwitchInst def add_case(self, const, bblk): @@ -1965,7 +1920,6 @@ class SwitchInstruction(Instruction): class CompareInstruction(Instruction): - __slots__ = () _type_ = api.llvm.CmpInst @property @@ -1977,40 +1931,11 @@ class CompareInstruction(Instruction): return FCMPEnum.get(n) -class AllocaInstruction(Instruction): - __slots__ = () - _type_ = api.llvm.AllocaInst - - @property - def alignment(self): - return self._ptr.getAlignment() - - @alignment.setter - def alignment(self, n): - self._ptr.setAlignment(n) - - @property - def array_size(self): - return self._ptr.getArraySize() - - @array_size.setter - def array_size(self, value): - return self._ptr.setArraySize(value._ptr)._ptr - - @property - def is_array(self): - return self._ptr.isArrayAllocation() - - @property - def is_static(self): - return self._ptr.isStaticAlloca() - #===----------------------------------------------------------------------=== # Basic block #===----------------------------------------------------------------------=== class BasicBlock(Value): - __slots__ = () _type_ = api.llvm.BasicBlock def insert_before(self, name): @@ -2037,7 +1962,6 @@ class BasicBlock(Value): class _ValueFactory(object): - __slots__ = () cache = weakref.WeakValueDictionary() # value ID -> class map @@ -2066,8 +1990,7 @@ class _ValueFactory(object): VALUE_INSTRUCTION + OPCODE_INVOKE : CallOrInvokeInstruction, VALUE_INSTRUCTION + OPCODE_SWITCH : SwitchInstruction, VALUE_INSTRUCTION + OPCODE_ICMP : CompareInstruction, - VALUE_INSTRUCTION + OPCODE_FCMP : CompareInstruction, - VALUE_INSTRUCTION + OPCODE_ALLOCA : AllocaInstruction, + VALUE_INSTRUCTION + OPCODE_FCMP : CompareInstruction } @classmethod @@ -2114,7 +2037,6 @@ _atomic_orderings = { } class Builder(llvm.Wrapper): - __slots__ = () @staticmethod def new(basic_block): @@ -2276,6 +2198,7 @@ class Builder(llvm.Wrapper): # memory def malloc(self, ty, name=""): + context = api.llvm.getGlobalContext() allocsz = api.llvm.ConstantExpr.getSizeOf(ty._ptr) ity = allocsz.getType() malloc = api.llvm.CallInst.CreateMalloc(self.basic_block._ptr, @@ -2289,6 +2212,7 @@ class Builder(llvm.Wrapper): return _make_value(inst) def malloc_array(self, ty, size, name=""): + context = api.llvm.getGlobalContext() allocsz = api.llvm.ConstantExpr.getSizeOf(ty._ptr) ity = allocsz.getType() malloc = api.llvm.CallInst.CreateMalloc(self.basic_block._ptr, @@ -2301,13 +2225,12 @@ class Builder(llvm.Wrapper): inst = self._ptr.Insert(malloc, name) return _make_value(inst) - def alloca(self, ty, size=None, name=""): - sizeptr = size._ptr if size else None - return _make_value(self._ptr.CreateAlloca(ty._ptr, sizeptr, name)) + def alloca(self, ty, name=""): + intty = Type.int() + return _make_value(self._ptr.CreateAlloca(ty._ptr, None, name)) - @deprecated def alloca_array(self, ty, size, name=""): - return self.alloca(ty, size, name=name) + return _make_value(self._ptr.CreateAlloca(ty._ptr, size._ptr, name)) def free(self, ptr): free = api.llvm.CallInst.CreateFree(ptr._ptr, self.basic_block._ptr) @@ -2394,20 +2317,15 @@ class Builder(llvm.Wrapper): # misc def extract_value(self, retval, idx, name=""): - if not isinstance(idx, (tuple, list)): - idx = [idx] - return _make_value(self._ptr.CreateExtractValue(retval._ptr, idx, - name)) + return _make_value(self._ptr.CreateExtractValue(retval._ptr, [idx], name)) # obsolete synonym for extract_value getresult = extract_value def insert_value(self, retval, rhs, idx, name=""): - if not isinstance(idx, (tuple, list)): - idx = [idx] return _make_value(self._ptr.CreateInsertValue(retval._ptr, rhs._ptr, - idx, + [idx], name)) def phi(self, ty, name=""): diff --git a/llvm/deprecated.py b/llvm/deprecated.py deleted file mode 100644 index 6db5fe7..0000000 --- a/llvm/deprecated.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -Shameless borrowed from Smart_deprecation_warnings -https://wiki.python.org/moin/PythonDecoratorLibrary -""" - -import warnings -import functools - - -def deprecated(func): - """This is a decorator which can be used to mark functions - as deprecated. It will result in a warning being emitted - when the function is used.""" - - @functools.wraps(func) - def new_func(*args, **kwargs): - warnings.warn_explicit( - "Call to deprecated function %s." % (func.__name__,), - category=DeprecationWarning, - filename=func.func_code.co_filename, - lineno=func.func_code.co_firstlineno + 1 - ) - return func(*args, **kwargs) - - return new_func diff --git a/llvm/ee.py b/llvm/ee.py index f615b61..b91c4cb 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -31,22 +31,33 @@ "Execution Engine and related classes." import sys +from io import BytesIO +import contextlib import llvm from llvm import core from llvm.passes import TargetData, TargetTransformInfo from llvmpy import api, extra - #===----------------------------------------------------------------------=== -# import items which were moved to target module +# Enumerations #===----------------------------------------------------------------------=== -from llvm.target import (initialize_all, initialize_target, - print_registered_targets, get_host_cpu_name, get_default_triple, - TargetMachine, - BO_BIG_ENDIAN, BO_LITTLE_ENDIAN, - CM_DEFAULT, CM_JITDEFAULT, CM_SMALL, CM_KERNEL, CM_MEDIUM, CM_LARGE, - RELOC_DEFAULT, RELOC_STATIC, RELOC_PIC, RELOC_DYNAMIC_NO_PIC) +BO_BIG_ENDIAN = 0 +BO_LITTLE_ENDIAN = 1 + +# CodeModel +CM_DEFAULT = api.llvm.CodeModel.Model.Default +CM_JITDEFAULT = api.llvm.CodeModel.Model.JITDefault +CM_SMALL = api.llvm.CodeModel.Model.Small +CM_KERNEL = api.llvm.CodeModel.Model.Kernel +CM_MEDIUM = api.llvm.CodeModel.Model.Medium +CM_LARGE = api.llvm.CodeModel.Model.Large + +# Reloc +RELOC_DEFAULT = api.llvm.Reloc.Model.Default +RELOC_STATIC = api.llvm.Reloc.Model.Static +RELOC_PIC = api.llvm.Reloc.Model.PIC_ +RELOC_DYNAMIC_NO_PIC = api.llvm.Reloc.Model.DynamicNoPIC #===----------------------------------------------------------------------=== # Generic value @@ -228,6 +239,150 @@ class ExecutionEngine(llvm.Wrapper): ptr = self._ptr.getDataLayout() return TargetData(ptr) +#===----------------------------------------------------------------------=== +# Target machine +#===----------------------------------------------------------------------=== + +def initialize_target(target, noraise=False): + """Initialize target by name. + It is safe to initialize the same target multiple times. + """ + prefix = 'LLVMInitialize' + postfixes = ['Target', 'TargetInfo', 'TargetMC', 'AsmPrinter', 'AsmParser'] + try: + for postfix in postfixes: + getattr(api, '%s%s%s' % (prefix, target, postfix))() + except AttributeError: + if noraise: + return False + else: + raise + else: + return True + + +def print_registered_targets(): + ''' + Note: print directly to stdout + ''' + api.llvm.TargetRegistry.printRegisteredTargetsForVersion() + +def get_host_cpu_name(): + '''return the string name of the host CPU + ''' + return api.llvm.sys.getHostCPUName() + +def get_default_triple(): + '''return the target triple of the host in str-rep + ''' + return api.llvm.sys.getDefaultTargetTriple() + + +class TargetMachine(llvm.Wrapper): + + @staticmethod + def new(triple='', cpu='', features='', opt=2, cm=CM_DEFAULT, + reloc=RELOC_DEFAULT): + if not triple: + triple = get_default_triple() + if not cpu: + cpu = get_host_cpu_name() + with contextlib.closing(BytesIO()) as error: + target = api.llvm.TargetRegistry.lookupTarget(triple, error) + if not target: + raise llvm.LLVMException(error.getvalue()) + if not target.hasTargetMachine(): + raise llvm.LLVMException(target, "No target machine.") + target_options = api.llvm.TargetOptions.new() + tm = target.createTargetMachine(triple, cpu, features, + target_options, + reloc, cm, opt) + if not tm: + raise llvm.LLVMException("Cannot create target machine") + return TargetMachine(tm) + + @staticmethod + def lookup(arch, cpu='', features='', opt=2, cm=CM_DEFAULT, + reloc=RELOC_DEFAULT): + '''create a targetmachine given an architecture name + + For a list of architectures, + use: `llc -help` + + For a list of available CPUs, + use: `llvm-as < /dev/null | llc -march=xyz -mcpu=help` + + For a list of available attributes (features), + use: `llvm-as < /dev/null | llc -march=xyz -mattr=help` + ''' + triple = api.llvm.Triple.new() + with contextlib.closing(BytesIO()) as error: + target = api.llvm.TargetRegistry.lookupTarget(arch, triple, error) + if not target: + raise llvm.LLVMException(error.getvalue()) + if not target.hasTargetMachine(): + raise llvm.LLVMException(target, "No target machine.") + target_options = api.llvm.TargetOptions.new() + tm = target.createTargetMachine(str(triple), cpu, features, + target_options, + reloc, cm, opt) + if not tm: + raise llvm.LLVMException("Cannot create target machine") + return TargetMachine(tm) + + def _emit_file(self, module, cgft): + pm = api.llvm.PassManager.new() + os = extra.make_raw_ostream_for_printing() + pm.add(api.llvm.DataLayout.new(str(self.target_data))) + failed = self._ptr.addPassesToEmitFile(pm, os, cgft) + pm.run(module) + + + CGFT = api.llvm.TargetMachine.CodeGenFileType + if cgft == CGFT.CGFT_ObjectFile: + return os.bytes() + else: + return os.str() + + def emit_assembly(self, module): + '''returns byte string of the module as assembly code of the target machine + ''' + CGFT = api.llvm.TargetMachine.CodeGenFileType + return self._emit_file(module._ptr, CGFT.CGFT_AssemblyFile) + + def emit_object(self, module): + '''returns byte string of the module as native code of the target machine + ''' + CGFT = api.llvm.TargetMachine.CodeGenFileType + return self._emit_file(module._ptr, CGFT.CGFT_ObjectFile) + + @property + def target_data(self): + '''get target data of this machine + ''' + return TargetData(self._ptr.getDataLayout()) + + @property + def target_name(self): + return self._ptr.getTarget().getName() + + @property + def target_short_description(self): + return self._ptr.getTarget().getShortDescription() + + @property + def triple(self): + return self._ptr.getTargetTriple() + + @property + def cpu(self): + return self._ptr.getTargetCPU() + + @property + def feature_string(self): + return self._ptr.getTargetFeatureString() + + #===----------------------------------------------------------------------=== # Dynamic Library @@ -238,27 +393,3 @@ def dylib_add_symbol(name, ptr): def dylib_address_of_symbol(name): return api.llvm.sys.DynamicLibrary.SearchForAddressOfSymbol(name) - -def dylib_import_library(filename): - """Permanently import a dynamic library. - - Returns a DynamicLibrary object - - Raises RuntimeError - """ - return DynamicLibrary(filename) - - -class DynamicLibrary(object): - def __init__(self, filename): - """ - Raises RuntimeError - """ - self._ptr = api.llvm.sys.DynamicLibrary.getPermanentLibrary( - filename) - - def get_address_of_symbol(self, symbol): - """ - Get the address of `symbol` (str) as integer - """ - return self._ptr.getAddressOfSymbol(symbol) diff --git a/llvm/llrt.py b/llvm/llrt.py index c704a66..b80914e 100644 --- a/llvm/llrt.py +++ b/llvm/llrt.py @@ -38,11 +38,9 @@ def _replace_with(builder, inst, func): def load(arch): '''Load the LLRT module corresponding to the given architecture - Creates a new module and optimizes it using the information from + Creates a new module and optimizes it using the information from the host machine. ''' - if arch != 'x86_64': - arch = 'x86' path = os.path.join(os.path.dirname(__file__), 'llrt', 'llrt_%s.ll' % arch) with open(path) as fin: lib = lc.Module.from_assembly(fin) diff --git a/llvm/mc/__init__.py b/llvm/mc/__init__.py deleted file mode 100644 index 69dd12f..0000000 --- a/llvm/mc/__init__.py +++ /dev/null @@ -1,242 +0,0 @@ -import sys - -import llvm -if llvm.version < (3, 4): - raise Exception("mc is not supported for llvm version less than 3.4") - -from io import BytesIO -import contextlib - -from llvmpy import api, extra -from llvmpy.api.llvm import MCDisassembler - -class Operand(object): - - def __init__(self, mcoperand, target_machine): - ''' - @mcoperand: an MCOperand object - @target_machine: an llvm.target.TargetMachine object - ''' - - self.op = mcoperand - if not self.op: - raise llvm.LLVMException("null MCOperand argument") - - self.tm = target_machine - - def __str__(self): - s = "invalid" - if self.is_reg(): - s = "reg(%s)" % (self.reg_name()) - elif self.is_imm(): - s = "imm(0x%02x)" % (self.op.getImm()) - elif self.is_fp_imm(): - s = "imm(%r)" % (self.op.getFPImm()) - elif self.is_expr(): - s = "expr(%r)" % (self.op.getExpr().getKind()) - elif self.is_inst(): - s = repr(Instr(self.op.getInst())) - - return s - - def __repr__(self): - return str(self) - - def reg_name(self): - if self.is_reg(): - s = self.tm.reg_info.getName(self.op.getReg()) - if s.strip() == "": - return "?" - else: - return s - else: - return "" - - def is_reg(self): - return self.op.isReg() - - def is_imm(self): - return self.op.isImm() - - def is_fp_imm(self): - return self.op.isFPImm() - - def is_expr(self): - return self.op.isExpr() - - def is_inst(self): - return self.op.isInst() - - def get_imm(self): - if self.is_imm(): - return self.op.getImm() - else: - return None - - def get_fp_imm(self): - if self.is_fp_imm(): - return self.op.getFPImm() - else: - return None - - def get_inst(self): - if self.is_inst(): - return Instr(self.op.getInst()) - else: - return None - -class Instr(object): - - def __init__(self, mcinst, target_machine): - ''' - @mcinst: an MCInst object - @target_machine: an llvm.target.TargetMachine object - ''' - - self.mcinst = mcinst - if not self.mcinst: - raise llvm.LLVMException("null MCInst argument") - - self.tm = target_machine - - def __str__(self): - os = extra.make_raw_ostream_for_printing() - self.tm.inst_printer.printInst(self.mcinst, os, "") - return str(os.str()) - - def __repr__(self): - return str(self) - - def __len__(self): - ''' the number of operands ''' - return int(self.mcinst.size()) - - def operands(self): - amt = self.mcinst.getNumOperands() - if amt < 1: - return [] - - l = [] - for i in range(0, amt): - l.append(Operand(self.mcinst.getOperand(i), self.tm)) - - return l - - @property - def instr_desc(self): - return self.tm.instr_info.get(self.opcode) - - @property - def flags(self): - return self.instr_desc.getFlags() - - @property - def ts_flags(self): - return self.instr_desc.TSFlags - - @property - def opcode(self): - return self.mcinst.getOpcode() - - def is_branch(self): - return self.instr_desc.isBranch() - - def is_cond_branch(self): - return self.instr_desc.isConditionalBranch() - - def is_uncond_branch(self): - return self.instr_desc.isUnconditionalBranch() - - def is_indirect_branch(self): - return self.instr_desc.isIndirectBranch() - - def is_call(self): - return self.instr_desc.isCall() - - def is_return(self): - return self.instr_desc.isReturn() - - def is_terminator(self): - return self.instr_desc.isTerminator() - - def is_barrier(self): - return self.instr_desc.isBarrier() - -class BadInstr(Instr): - pass - -class Disassembler(object): - - def __init__(self, target_machine): - self.tm = target_machine - - @property - def mdasm(self): - return self.tm.disassembler - - @property - def mai(self): - return self.tm.asm_info - - def instr(self, mcinst): - return Instr(mcinst, self.tm) - - def bad_instr(self, mcinst): - return BadInstr(mcinst, self.tm) - - def decode(self, bs, base_addr, align=None): - ''' - decodes the bytes in @bs into instructions and yields - each instruction as it is decoded. @base_addr is the base address - where the instruction bytes are from (not an offset into - @bs). yields instructions in the form of (addr, data, inst) where - addr is an integer, data is a tuple of integers and inst is an instance of - llvm.mc.Instr. @align specifies the byte alignment of instructions and - is only used if an un-decodable instruction is encountered, in which - case the disassembler will skip the following bytes until the next - aligned address. if @align is unspecified, the default alignment - for the architecture will be used, however this may not be ideal - for disassembly. for example, the default alignment for ARM is 1, but you - probably want it to be 4 for the purposes of disassembling ARM - instructions. - ''' - - if isinstance(bs, str) and sys.version_info.major >= 3: - bs = bytes(map(lambda c: ord(c), bs)) - elif not isinstance(bs, bytes): - raise TypeError("expected bs to be either 'str' or 'bytes' but got %s" % type(bs)) - - code = api.llvm.StringRefMemoryObject.new(bs, base_addr) - idx = 0 - if not isinstance(align, int) or align < 1: - align = self.mai.getMinInstAlignment() - - while(idx < code.getExtent()): - inst = api.llvm.MCInst.new() - addr = code.getBase() + idx - status, size = self.mdasm.getInstruction(inst, code, addr) - - if size < 1: - size = (align - (idx % align)) - - amt_left = code.getExtent() - idx - if amt_left >= size: - data = code.readBytes(addr, size) - elif amt_left < 1: - break - else: - data = code.readBytes(addr, amt_left) - - if sys.version_info.major < 3: - data = tuple(map(lambda b: ord(b), data)) - else: - data = tuple(data) - - if status == MCDisassembler.DecodeStatus.Fail: - yield (addr, data, None) - elif status == MCDisassembler.DecodeStatus.SoftFail: - yield (addr, data, self.bad_instr(inst)) - else: - yield (addr, data, self.instr(inst)) - - idx += size diff --git a/llvm/passes.py b/llvm/passes.py index e5ed085..b13fa84 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -80,15 +80,6 @@ class PassManagerBuilder(llvm.Wrapper): self._ptr.BBVectorize = enable vectorize = bbvectorize - - @property - def slpvectorize(self): - return self._ptr.SLPVectorize - - @slpvectorize.setter - def slpvectorize(self, enable): - self._ptr.SLPVectorize = enable - else: @property def vectorize(self): @@ -129,14 +120,13 @@ class PassManagerBuilder(llvm.Wrapper): def disable_unroll_loops(self, disable): self._ptr.DisableUnrollLoops = disable - if llvm.version <= (3, 3): - @property - def disable_simplify_lib_calls(self): - return self._ptr.DisableSimplifyLibCalls + @property + def disable_simplify_lib_calls(self): + return self._ptr.DisableSimplifyLibCalls - @disable_simplify_lib_calls.setter - def disable_simplify_lib_calls(self, disable): - self._ptr.DisableSimplifyLibCalls = disable + @disable_simplify_lib_calls.setter + def disable_simplify_lib_calls(self, disable): + self._ptr.DisableSimplifyLibCalls = disable def use_inliner_with_threshold(self, threshold): self._ptr.Inliner = api.llvm.createFunctionInliningPass(threshold) @@ -320,15 +310,13 @@ class TargetTransformInfo(Pass): # Helpers #===----------------------------------------------------------------------=== -def build_pass_managers(tm, opt=2, size=0, loop_vectorize=False, - slp_vectorize=False, vectorize=False, - inline_threshold=None, pm=True, fpm=True, mod=None): +def build_pass_managers(tm, opt=2, loop_vectorize=False, vectorize=False, + inline_threshold=2000, pm=True, fpm=True, mod=None): ''' tm --- The TargetMachine for which the passes are optimizing for. The TargetMachine must stay alive until the pass managers are removed. opt --- [0-3] Optimization level. Default to 2. - size --- [0-2] Optimize for size. Default to 0. loop_vectorize --- [boolean] Whether to use loop-vectorizer. vectorize --- [boolean] Whether to use basic-block vectorizer. inline_threshold --- [int] Threshold for the inliner. @@ -337,18 +325,6 @@ def build_pass_managers(tm, opt=2, size=0, loop_vectorize=False, fpm --- [boolean] Whether to build a function-level pass-manager. mod --- [Module] The module object for the FunctionPassManager. ''' - if inline_threshold is None: - if 0 < opt < 3: - inline_threshold = 225 - - if size == 1: - inline_threshold = 75 - elif size == 2: - inline_threshold = 25 - - if opt >= 3: - inline_threshold = 275 - if pm: pm = PassManager.new() if fpm: @@ -361,27 +337,22 @@ def build_pass_managers(tm, opt=2, size=0, loop_vectorize=False, pmb.opt_level = opt pmb.vectorize = vectorize pmb.loop_vectorize = loop_vectorize - if llvm.version >= (3, 3): - pmb.slp_vectorize = slp_vectorize if inline_threshold: pmb.use_inliner_with_threshold(inline_threshold) if pm: pm.add(tm.target_data.clone()) pm.add(TargetLibraryInfo.new(tm.triple)) - if llvm.version <= (3, 2): + if llvm.version >= (3, 2): pm.add(TargetTransformInfo.new(tm)) - else: - tm.add_analysis_passes(pm) pmb.populate(pm) if fpm: fpm.add(tm.target_data.clone()) fpm.add(TargetLibraryInfo.new(tm.triple)) - if llvm.version <= (3, 2): + if llvm.version >= (3, 2): fpm.add(TargetTransformInfo.new(tm)) - else: - tm.add_analysis_passes(fpm) pmb.populate(fpm) + fpm.initialize() from collections import namedtuple return namedtuple('passmanagers', ['pm', 'fpm'])(pm=pm, fpm=fpm) diff --git a/llvm/target.py b/llvm/target.py deleted file mode 100644 index f68b023..0000000 --- a/llvm/target.py +++ /dev/null @@ -1,266 +0,0 @@ -import llvm -from llvmpy import api, extra -from io import BytesIO -import contextlib -from llvm.passes import TargetData - -#===----------------------------------------------------------------------=== -# Enumerations -#===----------------------------------------------------------------------=== - -BO_BIG_ENDIAN = 0 -BO_LITTLE_ENDIAN = 1 - -# CodeModel -CM_DEFAULT = api.llvm.CodeModel.Model.Default -CM_JITDEFAULT = api.llvm.CodeModel.Model.JITDefault -CM_SMALL = api.llvm.CodeModel.Model.Small -CM_KERNEL = api.llvm.CodeModel.Model.Kernel -CM_MEDIUM = api.llvm.CodeModel.Model.Medium -CM_LARGE = api.llvm.CodeModel.Model.Large - -# Reloc -RELOC_DEFAULT = api.llvm.Reloc.Model.Default -RELOC_STATIC = api.llvm.Reloc.Model.Static -RELOC_PIC = api.llvm.Reloc.Model.PIC_ -RELOC_DYNAMIC_NO_PIC = api.llvm.Reloc.Model.DynamicNoPIC - -def initialize_all(): - api.llvm.InitializeAllTargets() - api.llvm.InitializeAllTargetInfos() - api.llvm.InitializeAllTargetMCs() - api.llvm.InitializeAllAsmPrinters() - api.llvm.InitializeAllDisassemblers() - api.llvm.InitializeAllAsmParsers() - -def initialize_target(target, noraise=False): - """Initialize target by name. - It is safe to initialize the same target multiple times. - """ - prefix = 'LLVMInitialize' - postfixes = ['Target', 'TargetInfo', 'TargetMC', 'AsmPrinter', 'AsmParser'] - try: - for postfix in postfixes: - getattr(api, '%s%s%s' % (prefix, target, postfix))() - except AttributeError: - if noraise: - return False - else: - raise - else: - return True - - -def print_registered_targets(): - ''' - Note: print directly to stdout - ''' - api.llvm.TargetRegistry.printRegisteredTargetsForVersion() - -def get_host_cpu_name(): - '''return the string name of the host CPU - ''' - return api.llvm.sys.getHostCPUName() - -def get_default_triple(): - '''return the target triple of the host in str-rep - ''' - return api.llvm.sys.getDefaultTargetTriple() - -class TargetMachine(llvm.Wrapper): - - @staticmethod - def new(triple='', cpu='', features='', opt=2, cm=CM_DEFAULT, - reloc=RELOC_DEFAULT): - if not triple: - triple = get_default_triple() - if not cpu: - cpu = get_host_cpu_name() - with contextlib.closing(BytesIO()) as error: - target = api.llvm.TargetRegistry.lookupTarget(triple, error) - if not target: - raise llvm.LLVMException(error.getvalue()) - if not target.hasTargetMachine(): - raise llvm.LLVMException(target, "No target machine.") - target_options = api.llvm.TargetOptions.new() - tm = target.createTargetMachine(triple, cpu, features, - target_options, - reloc, cm, opt) - if not tm: - raise llvm.LLVMException("Cannot create target machine") - return TargetMachine(tm) - - @staticmethod - def lookup(arch, cpu='', features='', opt=2, cm=CM_DEFAULT, - reloc=RELOC_DEFAULT): - '''create a targetmachine given an architecture name - - For a list of architectures, - use: `llc -help` - - For a list of available CPUs, - use: `llvm-as < /dev/null | llc -march=xyz -mcpu=help` - - For a list of available attributes (features), - use: `llvm-as < /dev/null | llc -march=xyz -mattr=help` - ''' - triple = api.llvm.Triple.new() - with contextlib.closing(BytesIO()) as error: - target = api.llvm.TargetRegistry.lookupTarget(arch, triple, error) - if not target: - raise llvm.LLVMException(error.getvalue()) - if not target.hasTargetMachine(): - raise llvm.LLVMException(target, "No target machine.") - target_options = api.llvm.TargetOptions.new() - tm = target.createTargetMachine(str(triple), cpu, features, - target_options, - reloc, cm, opt) - if not tm: - raise llvm.LLVMException("Cannot create target machine") - return TargetMachine(tm) - - @staticmethod - def x86(): - return TargetMachine.lookup('x86') - - @staticmethod - def x86_64(): - return TargetMachine.lookup('x86-64') - - @staticmethod - def arm(): - return TargetMachine.lookup('arm') - - @staticmethod - def thumb(): - return TargetMachine.lookup('thumb') - - def _emit_file(self, module, cgft): - pm = api.llvm.PassManager.new() - os = extra.make_raw_ostream_for_printing() - pm.add(api.llvm.DataLayout.new(str(self.target_data))) - failed = self._ptr.addPassesToEmitFile(pm, os, cgft) - pm.run(module) - - - CGFT = api.llvm.TargetMachine.CodeGenFileType - if cgft == CGFT.CGFT_ObjectFile: - return os.bytes() - else: - return os.str() - - def emit_assembly(self, module): - '''returns byte string of the module as assembly code of the target machine - ''' - CGFT = api.llvm.TargetMachine.CodeGenFileType - return self._emit_file(module._ptr, CGFT.CGFT_AssemblyFile) - - def emit_object(self, module): - '''returns byte string of the module as native code of the target machine - ''' - CGFT = api.llvm.TargetMachine.CodeGenFileType - return self._emit_file(module._ptr, CGFT.CGFT_ObjectFile) - - @property - def target_data(self): - '''get target data of this machine - ''' - return TargetData(self._ptr.getDataLayout()) - - @property - def target_name(self): - return self._ptr.getTarget().getName() - - @property - def target_short_description(self): - return self._ptr.getTarget().getShortDescription() - - @property - def triple(self): - return self._ptr.getTargetTriple() - - @property - def cpu(self): - return self._ptr.getTargetCPU() - - @property - def feature_string(self): - return self._ptr.getTargetFeatureString() - - @property - def target(self): - return self._ptr.getTarget() - - if llvm.version >= (3, 3): - def add_analysis_passes(self, pm): - self._ptr.addAnalysisPasses(pm._ptr) - - if llvm.version >= (3, 4): - @property - def reg_info(self): - mri = self._ptr.getRegisterInfo() - if not mri: - raise llvm.LLVMException("no reg info for this machine") - - return mri - - @property - def subtarget_info(self): - sti = self._ptr.getSubtargetImpl() - if not sti: - raise llvm.LLVMException("no subtarget info for this machine") - - return sti - - @property - def asm_info(self): - ai = self._ptr.getMCAsmInfo() - if not ai: - raise llvm.LLVMException("no asm info for this machine") - - return ai - - @property - def instr_info(self): - ii = self._ptr.getInstrInfo() - if not ii: - raise llvm.LLVMException("no instr info for this machine") - - return ii - - @property - def instr_analysis(self): - if not getattr(self, '_mia', False): - self._mia = self.target.createMCInstrAnalysis(self.instr_info) - if not self._mia: - raise llvm.LLVMException("no instr analysis for this machine") - - return self._mia - - @property - def disassembler(self): - if not getattr(self, '_dasm', False): - self._dasm = self.target.createMCDisassembler(self.subtarget_info) - if not self._dasm: - raise llvm.LLVMException("no disassembler for this machine") - - return self._dasm - - @property - def inst_printer(self): - if not getattr(self, '_mip', False): - self._mip = self.target.createMCInstPrinter( - self.asm_info.getAssemblerDialect(), - self.asm_info, - self.instr_info, - self.reg_info, - self.subtarget_info - ) - if not self._mip: - raise llvm.LLVMException("no instr printer for this machine") - - return self._mip - - def is_little_endian(self): - return self.asm_info.isLittleEndian() - diff --git a/llvm/test_llvmpy.py b/llvm/test_llvmpy.py new file mode 100644 index 0000000..3b8aebf --- /dev/null +++ b/llvm/test_llvmpy.py @@ -0,0 +1,1602 @@ +""" +LLVM tests +""" +import os +import sys +import math +import shutil +import unittest +import subprocess +import tempfile +import contextlib +from distutils.spawn import find_executable + +is_py3k = sys.version_info[0] >= 3 +BITS = tuple.__itemsize__ * 8 + +try: + from StringIO import StringIO +except ImportError: + from io import StringIO + + +import llvm +from llvm.core import (Module, Type, GlobalVariable, Function, Builder, + Constant, MetaData, MetaDataString, inline_function) +from llvm.ee import EngineBuilder +import llvm.core as lc +import llvm.passes as lp +import llvm.ee as le +import llvmpy + + +tests = [] + +# --------------------------------------------------------------------------- + +if sys.version_info[:2] <= (2, 6): + # create custom TestCase + class TestCase(unittest.TestCase): + def assertIn(self, item, container): + self.assertTrue(item in container) + + def assertNotIn(self, item, container): + self.assertFalse(item in container) + + def assertLess(self, a, b): + self.assertTrue(a < b) + + def assertIs(self, a, b): + self.assertTrue(a is b) + + @contextlib.contextmanager + def assertRaises(self, exc): + try: + yield + except exc: + pass + else: + raise self.failureException("Did not raise %s" % exc) + +else: + TestCase = unittest.TestCase + + +# --------------------------------------------------------------------------- + +class TestAsm(TestCase): + def setUp(self): + self.tmpdir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.tmpdir) + + def test_asm(self): + # create a module + m = Module.new('module1') + m.add_global_variable(Type.int(), 'i') + + # write it's assembly representation to a file + asm = str(m) + + testasm_ll = os.path.join(self.tmpdir, 'testasm.ll') + with open(testasm_ll, "w") as fout: + fout.write(asm) + + # read it back into a module + with open(testasm_ll) as fin: + m2 = Module.from_assembly(fin) + # The default `m.id` is ''. + m2.id = m.id # Copy the name from `m` + + self.assertEqual(str(m2).strip(), asm.strip()) + + def test_bitcode(self): + # create a module + m = Module.new('module1') + m.add_global_variable(Type.int(), 'i') + + # write it's assembly representation to a file + asm = str(m) + + testasm_bc = os.path.join(self.tmpdir, 'testasm.bc') + with open(testasm_bc, "wb") as fout: + m.to_bitcode(fout) + + # read it back into a module + with open(testasm_bc, "rb") as fin: + m2 = Module.from_bitcode(fin) + # The default `m.id` is ''. + m2.id = m.id # Copy the name from `m` + + self.assertEqual(str(m2).strip(), asm.strip()) + +tests.append(TestAsm) + +# --------------------------------------------------------------------------- + +class TestAttr(TestCase): + def make_module(self): + test_module = """ + define void @sum(i32*, i32*) { + entry: + ret void + } + """ + buf = StringIO(test_module) + return Module.from_assembly(buf) + + def test_align(self): + m = self.make_module() + f = m.get_function_named('sum') + f.args[0].alignment = 16 + self.assert_("align 16" in str(f)) + self.assertEqual(f.args[0].alignment, 16) + +tests.append(TestAttr) + +# --------------------------------------------------------------------------- + +class TestAtomic(TestCase): + orderings = ['unordered', 'monotonic', 'acquire', + 'release', 'acq_rel', 'seq_cst'] + + atomic_op = ['xchg', 'add', 'sub', 'and', 'nand', 'or', 'xor', + 'max', 'min', 'umax', 'umin'] + + def test_atomic_cmpxchg(self): + mod = Module.new('mod') + functype = Type.function(Type.void(), []) + func = mod.add_function(functype, name='foo') + bb = func.append_basic_block('entry') + bldr = Builder.new(bb) + ptr = bldr.alloca(Type.int()) + + old = bldr.load(ptr) + new = Constant.int(Type.int(), 1234) + + for ordering in self.orderings: + inst = bldr.atomic_cmpxchg(ptr, old, new, ordering) + self.assertEqual(ordering, str(inst).strip().split(' ')[-1]) + + inst = bldr.atomic_cmpxchg(ptr, old, new, ordering, crossthread=False) + self.assertEqual('singlethread', str(inst).strip().split(' ')[-2]) + + def test_atomic_rmw(self): + mod = Module.new('mod') + functype = Type.function(Type.void(), []) + func = mod.add_function(functype, name='foo') + bb = func.append_basic_block('entry') + bldr = Builder.new(bb) + ptr = bldr.alloca(Type.int()) + + old = bldr.load(ptr) + val = Constant.int(Type.int(), 1234) + + for ordering in self.orderings: + inst = bldr.atomic_rmw('xchg', ptr, val, ordering) + self.assertEqual(ordering, str(inst).split(' ')[-1]) + + for op in self.atomic_op: + inst = bldr.atomic_rmw(op, ptr, val, ordering) + self.assertEqual(op, str(inst).strip().split(' ')[3]) + + inst = bldr.atomic_rmw('xchg', ptr, val, ordering, crossthread=False) + self.assertEqual('singlethread', str(inst).strip().split(' ')[-2]) + + for op in self.atomic_op: + atomic_op = getattr(bldr, 'atomic_%s' % op) + inst = atomic_op(ptr, val, ordering) + self.assertEqual(op, str(inst).strip().split(' ')[3]) + + def test_atomic_ldst(self): + mod = Module.new('mod') + functype = Type.function(Type.void(), []) + func = mod.add_function(functype, name='foo') + bb = func.append_basic_block('entry') + bldr = Builder.new(bb) + ptr = bldr.alloca(Type.int()) + + val = Constant.int(Type.int(), 1234) + + for ordering in self.orderings: + loaded = bldr.atomic_load(ptr, ordering) + self.assert_('load atomic' in str(loaded)) + self.assertEqual(ordering, + str(loaded).strip().split(' ')[-3].rstrip(',')) + self.assert_('align 1' in str(loaded)) + + stored = bldr.atomic_store(loaded, ptr, ordering) + self.assert_('store atomic' in str(stored)) + self.assertEqual(ordering, + str(stored).strip().split(' ')[-3].rstrip(',')) + self.assert_('align 1' in str(stored)) + + fenced = bldr.fence(ordering) + self.assertEqual(['fence', ordering], + str(fenced).strip().split(' ')) + +tests.append(TestAtomic) + +# --------------------------------------------------------------------------- + +class TestConstExpr(TestCase): + + def test_constexpr_opcode(self): + mod = Module.new('test_constexpr_opcode') + func = mod.add_function(Type.function(Type.void(), []), name="foo") + builder = Builder.new(func.append_basic_block('entry')) + a = builder.inttoptr(Constant.int(Type.int(), 123), + Type.pointer(Type.int())) + self.assertTrue(isinstance(a, lc.ConstantExpr)) + self.assertEqual(a.opcode, lc.OPCODE_INTTOPTR) + self.assertEqual(a.opcode_name, "inttoptr") + +tests.append(TestConstExpr) + +# --------------------------------------------------------------------------- + +class TestOperands(TestCase): + # implement a test function + test_module = """ +define i32 @prod(i32, i32) { +entry: + %2 = mul i32 %0, %1 + ret i32 %2 +} + +define i32 @test_func(i32, i32, i32) { +entry: + %tmp1 = call i32 @prod(i32 %0, i32 %1) + %tmp2 = add i32 %tmp1, %2 + %tmp3 = add i32 %tmp2, 1 + %tmp4 = add i32 %tmp3, -1 + %tmp5 = add i64 -81985529216486895, 12297829382473034410 + ret i32 %tmp4 +} +""" + def test_operands(self): + m = Module.from_assembly(StringIO(self.test_module)) + + test_func = m.get_function_named("test_func") + prod = m.get_function_named("prod") + + # test operands + i1 = test_func.basic_blocks[0].instructions[0] + i2 = test_func.basic_blocks[0].instructions[1] + i3 = test_func.basic_blocks[0].instructions[2] + i4 = test_func.basic_blocks[0].instructions[3] + i5 = test_func.basic_blocks[0].instructions[4] + + self.assertEqual(i1.operand_count, 3) + self.assertEqual(i2.operand_count, 2) + + self.assertEqual(i3.operands[1].z_ext_value, 1) + self.assertEqual(i3.operands[1].s_ext_value, 1) + self.assertEqual(i4.operands[1].z_ext_value, 0xffffffff) + self.assertEqual(i4.operands[1].s_ext_value, -1) + self.assertEqual(i5.operands[0].s_ext_value, -81985529216486895) + self.assertEqual(i5.operands[1].z_ext_value, 12297829382473034410) + + self.assert_(i1.operands[-1] is prod) + self.assert_(i1.operands[0] is test_func.args[0]) + self.assert_(i1.operands[1] is test_func.args[1]) + self.assert_(i2.operands[0] is i1) + self.assert_(i2.operands[1] is test_func.args[2]) + self.assertEqual(len(i1.operands), 3) + self.assertEqual(len(i2.operands), 2) + + self.assert_(i1.called_function is prod) + +tests.append(TestOperands) + +# --------------------------------------------------------------------------- + +class TestPasses(TestCase): + # Create a module. + asm = """ + +define i32 @test() nounwind { + ret i32 42 +} + +define i32 @test1() nounwind { +entry: + %tmp = alloca i32 + store i32 42, i32* %tmp, align 4 + %tmp1 = load i32* %tmp, align 4 + %tmp2 = call i32 @test() + %tmp3 = load i32* %tmp, align 4 + %tmp4 = load i32* %tmp, align 4 + ret i32 %tmp1 +} + +define i32 @test2() nounwind { +entry: + %tmp = call i32 @test() + ret i32 %tmp +} +""" + def test_passes(self): + m = Module.from_assembly(StringIO(self.asm)) + + fn_test1 = m.get_function_named('test1') + fn_test2 = m.get_function_named('test2') + + original_test1 = str(fn_test1) + original_test2 = str(fn_test2) + + # Let's run a module-level inlining pass. First, create a pass manager. + pm = lp.PassManager.new() + + # Add the target data as the first "pass". This is mandatory. + pm.add(le.TargetData.new('')) + + # Add the inlining pass. + pm.add(lp.PASS_INLINE) + + # Run it! + pm.run(m) + + # Done with the pass manager. + del pm + + # Make sure test2 is inlined + self.assertNotEqual(str(fn_test2).strip(), original_test2.strip()) + + bb_entry = fn_test2.basic_blocks[0] + + self.assertEqual(len(bb_entry.instructions), 1) + self.assertEqual(bb_entry.instructions[0].opcode_name, 'ret') + + # Let's run a DCE pass on the the function 'test1' now. First create a + # function pass manager. + fpm = lp.FunctionPassManager.new(m) + + # Add the target data as first "pass". This is mandatory. + fpm.add(le.TargetData.new('')) + + # Add a DCE pass + fpm.add(lp.PASS_ADCE) + + # Run the pass on the function 'test1' + fpm.run(m.get_function_named('test1')) + + # Make sure test1 is modified + self.assertNotEqual(str(fn_test1).strip(), original_test1.strip()) + + def test_passes_with_pmb(self): + m = Module.from_assembly(StringIO(self.asm)) + + fn_test1 = m.get_function_named('test1') + fn_test2 = m.get_function_named('test2') + + original_test1 = str(fn_test1) + original_test2 = str(fn_test2) + + # Try out the PassManagerBuilder + + pmb = lp.PassManagerBuilder.new() + + self.assertEqual(pmb.opt_level, 2) # ensure default is level 2 + pmb.opt_level = 3 + self.assertEqual(pmb.opt_level, 3) # make sure it works + + self.assertEqual(pmb.size_level, 0) # ensure default is level 0 + pmb.size_level = 2 + self.assertEqual(pmb.size_level, 2) # make sure it works + + self.assertFalse(pmb.vectorize) # ensure default is False + pmb.vectorize = True + self.assertTrue(pmb.vectorize) # make sure it works + + # make sure the default is False + self.assertFalse(pmb.disable_unit_at_a_time) + self.assertFalse(pmb.disable_unroll_loops) + self.assertFalse(pmb.disable_simplify_lib_calls) + + pmb.disable_unit_at_a_time = True + self.assertTrue(pmb.disable_unit_at_a_time) + + # Do function pass + fpm = lp.FunctionPassManager.new(m) + pmb.populate(fpm) + fpm.run(fn_test1) + + # Make sure test1 has changed + self.assertNotEqual(str(fn_test1).strip(), original_test1.strip()) + + # Do module pass + pm = lp.PassManager.new() + pmb.populate(pm) + pm.run(m) + + # Make sure test2 has changed + self.assertNotEqual(str(fn_test2).strip(), original_test2.strip()) + + def test_dump_passes(self): + self.assertTrue(len(lp.PASSES)>0, msg="Cannot have no passes") + +tests.append(TestPasses) + +# --------------------------------------------------------------------------- + +class TestEngineBuilder(TestCase): + + def make_test_module(self): + module = Module.new("testmodule") + fnty = Type.function(Type.int(), []) + function = module.add_function(fnty, 'foo') + bb_entry = function.append_basic_block('entry') + builder = Builder.new(bb_entry) + builder.ret(Constant.int(Type.int(), 0xcafe)) + module.verify() + return module + + def run_foo(self, ee, module): + function = module.get_function_named('foo') + retval = ee.run_function(function, []) + self.assertEqual(retval.as_int(), 0xcafe) + + + def test_enginebuilder_basic(self): + module = self.make_test_module() + self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr)) + ee = EngineBuilder.new(module).create() + self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr)) + self.run_foo(ee, module) + + + def test_enginebuilder_with_tm(self): + tm = le.TargetMachine.new() + module = self.make_test_module() + self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr)) + ee = EngineBuilder.new(module).create(tm) + self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr)) + self.run_foo(ee, module) + + def test_enginebuilder_force_jit(self): + module = self.make_test_module() + ee = EngineBuilder.new(module).force_jit().create() + + self.run_foo(ee, module) +# +# def test_enginebuilder_force_interpreter(self): +# module = self.make_test_module() +# ee = EngineBuilder.new(module).force_interpreter().create() +# +# self.run_foo(ee, module) + + def test_enginebuilder_opt(self): + module = self.make_test_module() + ee = EngineBuilder.new(module).opt(3).create() + + self.run_foo(ee, module) + +tests.append(TestEngineBuilder) + +# --------------------------------------------------------------------------- + +class TestExecutionEngine(TestCase): + def test_get_pointer_to_global(self): + module = lc.Module.new(str(self)) + gvar = module.add_global_variable(Type.int(), 'hello') + X = 1234 + gvar.initializer = lc.Constant.int(Type.int(), X) + + ee = le.ExecutionEngine.new(module) + ptr = ee.get_pointer_to_global(gvar) + from ctypes import c_void_p, cast, c_int, POINTER + casted = cast(c_void_p(ptr), POINTER(c_int)) + self.assertEqual(X, casted[0]) + + def test_add_global_mapping(self): + module = lc.Module.new(str(self)) + gvar = module.add_global_variable(Type.int(), 'hello') + + fnty = lc.Type.function(Type.int(), []) + foo = module.add_function(fnty, name='foo') + bldr = lc.Builder.new(foo.append_basic_block('entry')) + bldr.ret(bldr.load(gvar)) + + ee = le.ExecutionEngine.new(module) + from ctypes import c_int, addressof, CFUNCTYPE + value = 0xABCD + value_ctype = c_int(value) + value_pointer = addressof(value_ctype) + + ee.add_global_mapping(gvar, value_pointer) + + foo_addr = ee.get_pointer_to_function(foo) + prototype = CFUNCTYPE(c_int) + foo_callable = prototype(foo_addr) + self.assertEqual(foo_callable(), value) + + + +tests.append(TestExecutionEngine) +# --------------------------------------------------------------------------- + +class TestObjCache(TestCase): + + def test_objcache(self): + # Testing module aliasing + m1 = Module.new('a') + t = Type.int() + ft = Type.function(t, [t]) + f1 = m1.add_function(ft, "func") + m2 = f1.module + self.assert_(m1 is m2) + + # Testing global vairable aliasing 1 + gv1 = GlobalVariable.new(m1, t, "gv") + gv2 = GlobalVariable.get(m1, "gv") + self.assert_(gv1 is gv2) + + # Testing global vairable aliasing 2 + gv3 = m1.global_variables[0] + self.assert_(gv1 is gv3) + + # Testing global vairable aliasing 3 + gv2 = None + gv3 = None + + gv1.delete() + + gv4 = GlobalVariable.new(m1, t, "gv") + + self.assert_(gv1 is not gv4) + + # Testing function aliasing 1 + b1 = f1.append_basic_block('entry') + f2 = b1.function + self.assert_(f1 is f2) + + # Testing function aliasing 2 + f3 = m1.get_function_named("func") + self.assert_(f1 is f3) + + # Testing function aliasing 3 + f4 = Function.get_or_insert(m1, ft, "func") + self.assert_(f1 is f4) + + # Testing function aliasing 4 + f5 = Function.get(m1, "func") + self.assert_(f1 is f5) + + # Testing function aliasing 5 + f6 = m1.get_or_insert_function(ft, "func") + self.assert_(f1 is f6) + + # Testing function aliasing 6 + f7 = m1.functions[0] + self.assert_(f1 is f7) + + # Testing argument aliasing + a1 = f1.args[0] + a2 = f1.args[0] + self.assert_(a1 is a2) + + # Testing basic block aliasing 1 + b2 = f1.basic_blocks[0] + self.assert_(b1 is b2) + + # Testing basic block aliasing 2 + b3 = f1.entry_basic_block + self.assert_(b1 is b3) + + # Testing basic block aliasing 3 + b31 = f1.entry_basic_block + self.assert_(b1 is b31) + + # Testing basic block aliasing 4 + bldr = Builder.new(b1) + b4 = bldr.basic_block + self.assert_(b1 is b4) + + # Testing basic block aliasing 5 + i1 = bldr.ret_void() + b5 = i1.basic_block + self.assert_(b1 is b5) + + # Testing instruction aliasing 1 + i2 = b5.instructions[0] + self.assert_(i1 is i2) + + # phi node + phi = bldr.phi(t) + phi.add_incoming(f1.args[0], b1) + v2 = phi.get_incoming_value(0) + b6 = phi.get_incoming_block(0) + + # Testing PHI / basic block aliasing 5 + self.assert_(b1 is b6) + + # Testing PHI / value aliasing + self.assert_(f1.args[0] is v2) + +tests.append(TestObjCache) + +# --------------------------------------------------------------------------- + +class TestTargetMachines(TestCase): + '''Exercise target machines + + Require PTX backend + ''' + def test_native(self): + m, _ = self._build_module() + tm = le.EngineBuilder.new(m).select_target() + + self.assertTrue(tm.target_name) + self.assertTrue(tm.target_data) + self.assertTrue(tm.target_short_description) + self.assertTrue(tm.triple) + self.assertIn('foo', tm.emit_assembly(m)) + self.assertTrue(le.get_host_cpu_name()) + + def test_ptx(self): + if le.initialize_target('PTX', noraise=True): + arch = 'ptx64' + elif le.initialize_target('NVPTX', noraise=True): + arch = 'nvptx64' + else: + return # skip this test + + print(arch) + m, func = self._build_module() + func.calling_convention = lc.CC_PTX_KERNEL # set calling conv + ptxtm = le.TargetMachine.lookup(arch=arch, cpu='sm_20') + self.assertTrue(ptxtm.triple) + self.assertTrue(ptxtm.cpu) + ptxasm = ptxtm.emit_assembly(m) + self.assertIn('foo', ptxasm) + if arch == 'nvptx64': + self.assertIn('.address_size 64', ptxasm) + self.assertIn('sm_20', ptxasm) + + def _build_module(self): + m = Module.new('TestTargetMachines') + + fnty = Type.function(Type.void(), []) + func = m.add_function(fnty, name='foo') + + bldr = Builder.new(func.append_basic_block('entry')) + bldr.ret_void() + m.verify() + return m, func + + def _build_bad_archname(self): + with self.assertRaises(RuntimeError): + tm = TargetMachine.lookup("ain't no arch name") + +tests.append(TestTargetMachines) + +# --------------------------------------------------------------------------- + +class TestNative(TestCase): + + def setUp(self): + self.tmpdir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.tmpdir) + + + def _make_module(self): + m = Module.new('module1') + m.add_global_variable(Type.int(), 'i') + + fty = Type.function(Type.int(), []) + f = m.add_function(fty, name='main') + + bldr = Builder.new(f.append_basic_block('entry')) + bldr.ret(Constant.int(Type.int(), 0xab)) + + return m + + def _compile(self, src): + cc = find_executable('cc') + if not cc: + return + + dst = os.path.join(self.tmpdir, 'llvmobj.out') + s = subprocess.call([cc, '-o', dst, src]) + if s != 0: + raise Exception("Cannot compile") + + s = subprocess.call([dst]) + self.assertEqual(s, 0xab) + + def test_assembly(self): + if sys.platform == 'darwin': + # skip this test on MacOSX for now + return + + m = self._make_module() + output = m.to_native_assembly() + + src = os.path.join(self.tmpdir, 'llvmasm.s') + with open(src, 'wb') as fout: + if is_py3k: + fout.write(output.encode('utf-8')) + else: + fout.write(output) + + self._compile(src) + + def test_object(self): + if sys.platform == 'darwin': + # skip this test on MacOSX for now + return + + m = self._make_module() + output = m.to_native_object() + + src = os.path.join(self.tmpdir, 'llvmobj.o') + with open(src, 'wb') as fout: + fout.write(output) + + self._compile(src) + +if sys.platform != 'win32': + tests.append(TestNative) + +# --------------------------------------------------------------------------- + +class TestNativeAsm(TestCase): + + def test_asm(self): + m = Module.new('module1') + + foo = m.add_function(Type.function(Type.int(), + [Type.int(), Type.int()]), + name="foo") + bldr = Builder.new(foo.append_basic_block('entry')) + x = bldr.add(foo.args[0], foo.args[1]) + bldr.ret(x) + + att_syntax = m.to_native_assembly() + os.environ["LLVMPY_OPTIONS"] = "-x86-asm-syntax=intel" + lc.parse_environment_options(sys.argv[0], "LLVMPY_OPTIONS") + intel_syntax = m.to_native_assembly() + + self.assertNotEqual(att_syntax, intel_syntax) + +tests.append(TestNativeAsm) + +# --------------------------------------------------------------------------- + +class TestUses(TestCase): + + def test_uses(self): + m = Module.new('a') + t = Type.int() + ft = Type.function(t, [t, t, t]) + f = m.add_function(ft, "func") + b = f.append_basic_block('entry') + bld = Builder.new(b) + tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1") + tmp2 = bld.add(tmp1, f.args[1], "tmp2") + tmp3 = bld.add(tmp1, f.args[2], "tmp3") + bld.ret(tmp3) + + # Testing use count + self.assertEqual(f.args[0].use_count, 1) + self.assertEqual(f.args[1].use_count, 1) + self.assertEqual(f.args[2].use_count, 1) + self.assertEqual(tmp1.use_count, 2) + self.assertEqual(tmp2.use_count, 0) + self.assertEqual(tmp3.use_count, 1) + + # Testing uses + self.assert_(f.args[0].uses[0] is tmp1) + self.assertEqual(len(f.args[0].uses), 1) + self.assert_(f.args[1].uses[0] is tmp2) + self.assertEqual(len(f.args[1].uses), 1) + self.assert_(f.args[2].uses[0] is tmp3) + self.assertEqual(len(f.args[2].uses), 1) + self.assertEqual(len(tmp1.uses), 2) + self.assertEqual(len(tmp2.uses), 0) + self.assertEqual(len(tmp3.uses), 1) + +tests.append(TestUses) + +# --------------------------------------------------------------------------- + +class TestMetaData(TestCase): + # test module metadata + def test_metadata(self): + m = Module.new('a') + t = Type.int() + metadata = MetaData.get(m, [Constant.int(t, 100), + MetaDataString.get(m, 'abcdef'), + None]) + MetaData.add_named_operand(m, 'foo', metadata) + self.assertEqual(MetaData.get_named_operands(m, 'foo'), [metadata]) + self.assertEqual(MetaData.get_named_operands(m, 'bar'), []) + self.assertEqual(len(metadata.operands), 3) + self.assertEqual(metadata.operands[0].z_ext_value, 100) + self.assertEqual(metadata.operands[1].string, 'abcdef') + self.assertTrue(metadata.operands[2] is None) + +tests.append(TestMetaData) + +# --------------------------------------------------------------------------- + +class TestInlining(TestCase): + def test_inline_call(self): + mod = Module.new(__name__) + callee = mod.add_function(Type.function(Type.int(), [Type.int()]), + name='bar') + + builder = Builder.new(callee.append_basic_block('entry')) + builder.ret(builder.add(callee.args[0], callee.args[0])) + + caller = mod.add_function(Type.function(Type.int(), []), + name='foo') + + builder = Builder.new(caller.append_basic_block('entry')) + callinst = builder.call(callee, [Constant.int(Type.int(), 1234)]) + builder.ret(callinst) + + pre_inlining = str(caller) + self.assertIn('call', pre_inlining) + + self.assertTrue(inline_function(callinst)) + + post_inlining = str(caller) + self.assertNotIn('call', post_inlining) + self.assertIn('2468', post_inlining) + +tests.append(TestInlining) + +# --------------------------------------------------------------------------- + +class TestIssue10(TestCase): + def test_issue10(self): + m = Module.new('a') + ti = Type.int() + tf = Type.function(ti, [ti, ti]) + + f = m.add_function(tf, "func1") + + bb = f.append_basic_block('entry') + + b = Builder.new(bb) + + # There are no instructions in bb. Positioning of the + # builder at beginning (or end) should succeed (trivially). + b.position_at_end(bb) + b.position_at_beginning(bb) + +tests.append(TestIssue10) + +# --------------------------------------------------------------------------- + +class TestOpaque(TestCase): + + def test_opaque(self): + # Create an opaque type + ts = Type.opaque('mystruct') + self.assertTrue('type opaque' in str(ts)) + self.assertTrue(ts.is_opaque) + self.assertTrue(ts.is_identified) + self.assertFalse(ts.is_literal) + #print(ts) + + # Create a recursive type + ts.set_body([Type.int(), Type.pointer(ts)]) + + self.assertEqual(ts.elements[0], Type.int()) + self.assertEqual(ts.elements[1], Type.pointer(ts)) + self.assertEqual(ts.elements[1].pointee, ts) + self.assertFalse(ts.is_opaque) # is not longer a opaque type + #print(ts) + + with self.assertRaises(llvm.LLVMException): + # Cannot redefine + ts.set_body([]) + + def test_opaque_with_no_name(self): + with self.assertRaises(llvm.LLVMException): + Type.opaque('') + +tests.append(TestOpaque) + +# --------------------------------------------------------------------------- +class TestCPUSupport(TestCase): + + def _build_test_module(self): + mod = Module.new('test') + + float = Type.double() + mysinty = Type.function( float, [float] ) + mysin = mod.add_function(mysinty, "mysin") + block = mysin.append_basic_block("entry") + b = Builder.new(block) + + sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) + pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) + cos = Function.intrinsic(mod, lc.INTR_COS, [float]) + + mysin.args[0].name = "x" + x = mysin.args[0] + one = Constant.real(float, "1") + cosx = b.call(cos, [x], "cosx") + cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") + onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub + sin = b.call(sqrt, [onemc2], "sin") + b.ret(sin) + return mod, mysin + + def _template(self, mattrs): + mod, func = self._build_test_module() + ee = self._build_engine(mod, mattrs=mattrs) + arg = le.GenericValue.real(Type.double(), 1.234) + retval = ee.run_function(func, [arg]) + + golden = math.sin(1.234) + answer = retval.as_real(Type.double()) + self.assertTrue(abs(answer-golden)/golden < 1e-5) + + + def _build_engine(self, mod, mattrs): + if mattrs: + return EngineBuilder.new(mod).mattrs(mattrs).create() + else: + return EngineBuilder.new(mod).create() + + def test_cpu_support2(self): + features = 'sse3', 'sse41', 'sse42', 'avx' + mattrs = ','.join(map(lambda s: '-%s' % s, features)) + print('disable mattrs', mattrs) + self._template(mattrs) + + def test_cpu_support3(self): + features = 'sse41', 'sse42', 'avx' + mattrs = ','.join(map(lambda s: '-%s' % s, features)) + print('disable mattrs', mattrs) + self._template(mattrs) + + def test_cpu_support4(self): + features = 'sse42', 'avx' + mattrs = ','.join(map(lambda s: '-%s' % s, features)) + print('disable mattrs', mattrs) + self._template(mattrs) + + def test_cpu_support5(self): + features = 'avx', + mattrs = ','.join(map(lambda s: '-%s' % s, features)) + print('disable mattrs', mattrs) + self._template(mattrs) + + def test_cpu_support6(self): + features = [] + from llvm.workaround.avx_support import detect_avx_support + if not detect_avx_support(): + print('Skipping: no AVX') + else: + mattrs = ','.join(map(lambda s: '-%s' % s, features)) + print('disable mattrs', mattrs) + self._template(mattrs) + +tests.append(TestCPUSupport) + +# --------------------------------------------------------------------------- +class TestIntrinsicBasic(TestCase): + + def _build_module(self, float): + mod = Module.new('test') + functy = Type.function(float, [float]) + func = mod.add_function(functy, "mytest%s" % float) + block = func.append_basic_block("entry") + b = Builder.new(block) + return mod, func, b + + def _template(self, mod, func, pyfunc): + float = func.type.pointee.return_type + + from llvm.workaround.avx_support import detect_avx_support + if not detect_avx_support(): + ee = le.EngineBuilder.new(mod).mattrs("-avx").create() + else: + ee = le.EngineBuilder.new(mod).create() + arg = le.GenericValue.real(float, 1.234) + retval = ee.run_function(func, [arg]) + golden = pyfunc(1.234) + answer = retval.as_real(float) + self.assertTrue(abs(answer - golden) / golden < 1e-7) + + def test_sqrt_f32(self): + float = Type.float() + mod, func, b = self._build_module(float) + intr = Function.intrinsic(mod, lc.INTR_SQRT, [float]) + b.ret(b.call(intr, func.args)) + self._template(mod, func, math.sqrt) + + def test_sqrt_f64(self): + float = Type.double() + mod, func, b = self._build_module(float) + intr = Function.intrinsic(mod, lc.INTR_SQRT, [float]) + b.ret(b.call(intr, func.args)) + self._template(mod, func, math.sqrt) + + def test_cos_f32(self): + if sys.platform == 'win32' and BITS == 32: + # float32 support is known to fail on 32-bit Windows + return + float = Type.float() + mod, func, b = self._build_module(float) + intr = Function.intrinsic(mod, lc.INTR_COS, [float]) + b.ret(b.call(intr, func.args)) + self._template(mod, func, math.cos) + + def test_cos_f64(self): + float = Type.double() + mod, func, b = self._build_module(float) + intr = Function.intrinsic(mod, lc.INTR_COS, [float]) + b.ret(b.call(intr, func.args)) + self._template(mod, func, math.cos) + + def test_sin_f32(self): + if sys.platform == 'win32' and BITS == 32: + # float32 support is known to fail on 32-bit Windows + return + float = Type.float() + mod, func, b = self._build_module(float) + intr = Function.intrinsic(mod, lc.INTR_SIN, [float]) + b.ret(b.call(intr, func.args)) + self._template(mod, func, math.sin) + + def test_sin_f64(self): + float = Type.double() + mod, func, b = self._build_module(float) + intr = Function.intrinsic(mod, lc.INTR_SIN, [float]) + b.ret(b.call(intr, func.args)) + self._template(mod, func, math.sin) + + def test_powi_f32(self): + float = Type.float() + mod, func, b = self._build_module(float) + intr = Function.intrinsic(mod, lc.INTR_POWI, [float]) + b.ret(b.call(intr, [func.args[0], lc.Constant.int(Type.int(), 2)])) + self._template(mod, func, lambda x: x**2) + + def test_powi_f64(self): + float = Type.double() + mod, func, b = self._build_module(float) + intr = Function.intrinsic(mod, lc.INTR_POWI, [float]) + b.ret(b.call(intr, [func.args[0], lc.Constant.int(Type.int(), 2)])) + self._template(mod, func, lambda x: x**2) + + + +tests.append(TestIntrinsicBasic) + +# --------------------------------------------------------------------------- + +class TestIntrinsic(TestCase): + def test_bswap(self): + # setup a function and a builder + mod = Module.new('test') + functy = Type.function(Type.int(), []) + func = mod.add_function(functy, "showme") + block = func.append_basic_block("entry") + b = Builder.new(block) + + # let's do bswap on a 32-bit integer using llvm.bswap + val = Constant.int(Type.int(), 0x42) + bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()]) + + bswap_res = b.call(bswap, [val]) + b.ret(bswap_res) + + # logging.debug(mod) + + # the output is: + # + # ; ModuleID = 'test' + # + # define void @showme() { + # entry: + # %0 = call i32 @llvm.bswap.i32(i32 42) + # ret i32 %0 + # } + + # let's run the function + ee = le.ExecutionEngine.new(mod) + retval = ee.run_function(func, []) + self.assertEqual(retval.as_int(), 0x42000000) + + def test_mysin(self): + if sys.platform == 'win32' and BITS == 32: + # float32 support is known to fail on 32-bit Windows + return + + # mysin(x) = sqrt(1.0 - pow(cos(x), 2)) + mod = Module.new('test') + + float = Type.float() + mysinty = Type.function( float, [float] ) + mysin = mod.add_function(mysinty, "mysin") + block = mysin.append_basic_block("entry") + b = Builder.new(block) + + sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) + pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) + cos = Function.intrinsic(mod, lc.INTR_COS, [float]) + + mysin.args[0].name = "x" + x = mysin.args[0] + one = Constant.real(float, "1") + cosx = b.call(cos, [x], "cosx") + cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") + onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub + sin = b.call(sqrt, [onemc2], "sin") + b.ret(sin) + #logging.debug(mod) + +# ; ModuleID = 'test' +# +# define void @showme() { +# entry: +# call i32 @llvm.bswap.i32( i32 42 ) ; :0 [#uses +# } +# +# declare i32 @llvm.bswap.i32(i32) nounwind readnone +# +# define float @mysin(float %x) { +# entry: +# %cosx = call float @llvm.cos.f32( float %x ) ; [#uses +# %sin = call float @llvm.sqrt.f32( float %onemc2 ) +# ret float %sin +# } +# +# declare float @llvm.sqrt.f32(float) nounwind readnone +# +# declare float @llvm.powi.f32(float, i32) nounwind readnone +# +# declare float @llvm.cos.f32(float) nounwind readnone + + # let's run the function + + from llvm.workaround.avx_support import detect_avx_support + if not detect_avx_support(): + ee = le.EngineBuilder.new(mod).mattrs("-avx").create() + else: + ee = le.EngineBuilder.new(mod).create() + + arg = le.GenericValue.real(Type.float(), 1.234) + retval = ee.run_function(mysin, [arg]) + + golden = math.sin(1.234) + answer = retval.as_real(Type.float()) + self.assertTrue(abs(answer-golden)/golden < 1e-5) + +tests.append(TestIntrinsic) + +# --------------------------------------------------------------------------- + +class TestVolatile(TestCase): + + def test_volatile(self): + mod = Module.new('mod') + functype = Type.function(Type.void(), []) + func = mod.add_function(functype, name='foo') + bb = func.append_basic_block('entry') + bldr = Builder.new(bb) + ptr = bldr.alloca(Type.int()) + + # test load inst + val = bldr.load(ptr) + self.assertFalse(val.is_volatile, "default must be non-volatile") + val.set_volatile(True) + self.assertTrue(val.is_volatile, "fail to set volatile") + val.set_volatile(False) + self.assertFalse(val.is_volatile, "fail to unset volatile") + + # test store inst + store_inst = bldr.store(val, ptr) + self.assertFalse(store_inst.is_volatile, "default must be non-volatile") + store_inst.set_volatile(True) + self.assertTrue(store_inst.is_volatile, "fail to set volatile") + store_inst.set_volatile(False) + self.assertFalse(store_inst.is_volatile, "fail to unset volatile") + + def test_volatile_another(self): + mod = Module.new('mod') + functype = Type.function(Type.void(), []) + func = mod.add_function(functype, name='foo') + bb = func.append_basic_block('entry') + bldr = Builder.new(bb) + ptr = bldr.alloca(Type.int()) + + # test load inst + val = bldr.load(ptr, volatile=True) + self.assertTrue(val.is_volatile, "volatile kwarg does not work") + val.set_volatile(False) + self.assertFalse(val.is_volatile, "fail to unset volatile") + val.set_volatile(True) + self.assertTrue(val.is_volatile, "fail to set volatile") + + # test store inst + store_inst = bldr.store(val, ptr, volatile=True) + self.assertTrue(store_inst.is_volatile, "volatile kwarg does not work") + store_inst.set_volatile(False) + self.assertFalse(store_inst.is_volatile, "fail to unset volatile") + store_inst.set_volatile(True) + self.assertTrue(store_inst.is_volatile, "fail to set volatile") + +tests.append(TestVolatile) + +# --------------------------------------------------------------------------- + +class TestNamedMetaData(TestCase): + def test_named_md(self): + m = Module.new('test_named_md') + nmd = m.get_or_insert_named_metadata('something') + md = MetaData.get(m, [Constant.int(Type.int(), 0xbeef)]) + nmd.add(md) + self.assertTrue(str(nmd).startswith('!something')) + ir = str(m) + self.assertTrue('!something' in ir) + +tests.append(TestNamedMetaData) + + +# --------------------------------------------------------------------------- + +class TestStruct(TestCase): + def test_struct_identical(self): + m = Module.new('test_struct_identical') + ta = Type.struct([Type.int(32), Type.float()], name='ta') + tb = Type.struct([Type.int(32), Type.float()]) + self.assertTrue(ta.is_layout_identical(tb)) + +tests.append(TestStruct) + +# --------------------------------------------------------------------------- + +class TestTypeHash(TestCase): + def test_scalar_type(self): + i32a = Type.int(32) + i32b = Type.int(32) + i64a = Type.int(64) + i64b = Type.int(64) + ts = set([i32a, i32b, i64a, i64b]) + self.assertTrue(len(ts)) + self.assertTrue(i32a in ts) + self.assertTrue(i64b in ts) + + def test_struct_type(self): + ta = Type.struct([Type.int(32), Type.float()]) + tb = Type.struct([Type.int(32), Type.float()]) + tc = Type.struct([Type.int(32), Type.int(32), Type.float()]) + ts = set([ta, tb, tc]) + self.assertTrue(len(ts) == 2) + self.assertTrue(ta in ts) + self.assertTrue(tb in ts) + self.assertTrue(tc in ts) + +tests.append(TestTypeHash) + +# --------------------------------------------------------------------------- + +class TestArgAttr(TestCase): + def test_arg_attr(self): + m = Module.new('oifjda') + vptr = Type.pointer(Type.float()) + sptr = Type.pointer(Type.struct([])) + fnty = Type.function(Type.void(), [vptr] * 5) + func = m.add_function(fnty, 'foo') + attrs = [lc.ATTR_STRUCT_RET, lc.ATTR_BY_VAL, lc.ATTR_NEST, + lc.ATTR_NO_ALIAS, lc.ATTR_NO_CAPTURE] + for i, attr in enumerate(attrs): + arg = func.args[i] + self.assertEqual(i, arg.arg_no) + arg.add_attribute(attr) + self.assertTrue(attr in func.args[i]) + +tests.append(TestArgAttr) + +# --------------------------------------------------------------------------- + +class TestSwitch(TestCase): + def test_arg_attr(self): + m = Module.new('oifjda') + fnty = Type.function(Type.void(), [Type.int()]) + func = m.add_function(fnty, 'foo') + bb = func.append_basic_block('') + bbdef = func.append_basic_block('') + bbsw1 = func.append_basic_block('') + bbsw2 = func.append_basic_block('') + bldr = Builder.new(bb) + + swt = bldr.switch(func.args[0], bbdef, n=2) + swt.add_case(Constant.int(Type.int(), 0), bbsw1) + swt.add_case(Constant.int(Type.int(), 1), bbsw2) + + bldr.position_at_end(bbsw1) + bldr.ret_void() + + bldr.position_at_end(bbsw2) + bldr.ret_void() + + bldr.position_at_end(bbdef) + bldr.ret_void() + + func.verify() + +tests.append(TestSwitch) + +# --------------------------------------------------------------------------- + +class TestCmp(TestCase): + def test_arg_attr(self): + m = Module.new('oifjda') + fnty = Type.function(Type.void(), [Type.int()]) + func = m.add_function(fnty, 'foo') + bb = func.append_basic_block('') + bldr = Builder.new(bb) + + cmpinst = bldr.icmp(lc.ICMP_ULE, func.args[0], + Constant.int(Type.int(), 123)) + self.assertTrue(repr(cmpinst.predicate).startswith('ICMP_ULE')) + self.assertEqual(cmpinst.predicate, lc.ICMP_ULE) + bldr.ret_void() + + func.verify() + +tests.append(TestCmp) + + +# --------------------------------------------------------------------------- + +class TestMCJIT(TestCase): + def test_mcjit(self): + m = Module.new('oidfjs') + fnty = Type.function(Type.int(), [Type.int(), Type.int()]) + func = m.add_function(fnty, 'foo') + bb = func.append_basic_block('') + bldr = Builder.new(bb) + bldr.ret(bldr.add(*func.args)) + + func.verify() + + engine = EngineBuilder.new(m).mcjit(True).create() + ptr = engine.get_pointer_to_function(func) + + from ctypes import c_int, CFUNCTYPE + callee = CFUNCTYPE(c_int, c_int, c_int)(ptr) + self.assertEqual(321 + 123, callee(321, 123)) + + def test_multi_module_linking(self): + # generate external library module + m = Module.new('external-library-module') + fnty = Type.function(Type.int(), [Type.int(), Type.int()]) + libfname = 'myadd' + func = m.add_function(fnty, libfname) + bb = func.append_basic_block('') + bldr = Builder.new(bb) + bldr.ret(bldr.add(*func.args)) + func.verify() + + # JIT the lib module and bind dynamic symbol + libengine = EngineBuilder.new(m).mcjit(True).create() + myadd_ptr = libengine.get_pointer_to_function(func) + le.dylib_add_symbol(libfname, myadd_ptr) + + # reference external library + m = Module.new('user') + fnty = Type.function(Type.int(), [Type.int(), Type.int()]) + func = m.add_function(fnty, 'foo') + bb = func.append_basic_block('') + bldr = Builder.new(bb) + extadd = m.get_or_insert_function(fnty, name=libfname) + bldr.ret(bldr.call(extadd, func.args)) + func.verify() + + # JIT the user module + engine = EngineBuilder.new(m).mcjit(True).create() + ptr = engine.get_pointer_to_function(func) + self.assertEqual(myadd_ptr, + engine.get_pointer_to_named_function(libfname)) + + from ctypes import c_int, CFUNCTYPE + callee = CFUNCTYPE(c_int, c_int, c_int)(ptr) + self.assertEqual(321 + 123, callee(321, 123)) + + +if llvm.version >= (3, 3): + # MCJIT broken in 3.2 + # The test will segfault in OSX? + tests.append(TestMCJIT) + + +class TestLLRT(TestCase): + def test_llrt_divmod(self): + from llvm import llrt + m = lc.Module.new('testllrt') + longlong = lc.Type.int(64) + lfunc = m.add_function(lc.Type.function(longlong, [longlong, longlong]), 'foo') + bldr = lc.Builder.new(lfunc.append_basic_block('')) + bldr.ret(bldr.udiv(*lfunc.args)) + + llrt.replace_divmod64(lfunc) + + rt = llrt.LLRT() + rt.install_symbols() + + engine = le.EngineBuilder.new(m).create() + pointer = engine.get_pointer_to_function(lfunc) + + from ctypes import CFUNCTYPE, c_uint64, c_int64 + func = CFUNCTYPE(c_uint64, c_uint64, c_uint64)(pointer) + a, b = 98342, 2231 + self.assertEqual(func(98342, 2231), 98342 // 2231) + + rt.uninstall_symbols() + +tests.append(TestLLRT) + +class TestArith(TestCase): + ''' + Test basic arithmetic support with LLVM MCJIT + ''' + def func_template(self, ty, op): + m = Module.new('dofjaa') + fnty = Type.function(ty, [ty, ty]) + fn = m.add_function(fnty, 'foo') + bldr = Builder.new(fn.append_basic_block('')) + bldr.ret(getattr(bldr, op)(*fn.args)) + + engine = EngineBuilder.new(m).mcjit(True).create() + ptr = engine.get_pointer_to_function(fn) + + from ctypes import c_uint32, c_uint64, c_float, c_double, CFUNCTYPE + + maptypes = { + Type.int(32): c_uint32, + Type.int(64): c_uint64, + Type.float(): c_float, + Type.double(): c_double, + } + cty = maptypes[ty] + prototype = CFUNCTYPE(*[cty] * 3) + callee = prototype(ptr) + callee(12, 23) + + def template(self, iop, fop): + inttys = [Type.int(32), Type.int(64)] + flttys = [Type.float(), Type.double()] + + if iop: + for ty in inttys: + self.func_template(ty, iop) + if fop: + for ty in flttys: + self.func_template(ty, fop) + + def test_add(self): + self.template('add', 'fadd') + + def test_sub(self): + self.template('sub', 'fsub') + + def test_mul(self): + self.template('mul', 'fmul') + + def test_div(self): + if BITS == 32: + print('skipped test for div') + print('known failure due to unresolved external symbol __udivdi3') + return + self.template('udiv', None) # 'fdiv') + + def test_rem(self): + if BITS == 32: + print('skipped test for rem') + print('known failure due to unresolved external symbol __umoddi3') + return + self.template('urem', None) # 'frem') + +if llvm.version >= (3, 3): + # MCJIT is broken in 3.2 + tests.append(TestArith) + +class TestNUWNSW(TestCase): + def make_module(self): + mod = Module.new('asdfa') + fnty = Type.function(Type.void(), [Type.int()] * 2) + func = mod.add_function(fnty, 'foo') + bldr = Builder.new(func.append_basic_block('')) + return mod, func, bldr + + def has_nsw(self, inst, op): + self.assertTrue(('%s nsw' % op) in str(inst), "NSW flag does not work") + + def has_nuw(self, inst, op): + self.assertTrue(('%s nuw' % op) in str(inst), "NUW flag does not work") + + def _test_template(self, opf, opname): + mod, func, bldr = self.make_module() + a, b = func.args + self.has_nsw(opf(bldr, a, b, nsw=True), opname) + self.has_nuw(opf(bldr, a, b, nuw=True), opname) + + def test_add_nuw_nsw(self): + self._test_template(Builder.add, 'add') + + def test_sub_nuw_nsw(self): + self._test_template(Builder.sub, 'sub') + + def test_mul_nuw_nsw(self): + self._test_template(Builder.mul, 'mul') + + def test_shl_nuw_nsw(self): + self._test_template(Builder.shl, 'shl') + + def test_neg_nuw_nsw(self): + mod, func, bldr = self.make_module() + a, b = func.args + self.has_nsw(bldr.neg(a, nsw=True), 'sub') + self.has_nuw(bldr.neg(a, nuw=True), 'sub') + + +tests.append(TestNUWNSW) + + +class TestExact(TestCase): + def make_module(self): + mod = Module.new('asdfa') + fnty = Type.function(Type.void(), [Type.int()] * 2) + func = mod.add_function(fnty, 'foo') + bldr = Builder.new(func.append_basic_block('')) + return mod, func, bldr + + def has_exact(self, inst, op): + self.assertTrue(('%s exact' % op) in str(inst), "exact flag does not work") + + def _test_template(self, opf, opname): + mod, func, bldr = self.make_module() + a, b = func.args + self.has_exact(opf(bldr, a, b, exact=True), opname) + + def test_udiv_exact(self): + self._test_template(Builder.udiv, 'udiv') + + def test_sdiv_exact(self): + self._test_template(Builder.sdiv, 'sdiv') + + def test_lshr_exact(self): + self._test_template(Builder.lshr, 'lshr') + + def test_ashr_exact(self): + self._test_template(Builder.ashr, 'ashr') + +tests.append(TestExact) + + + +# --------------------------------------------------------------------------- + +def run(verbosity=1): + print('llvmpy is installed in: ' + os.path.dirname(__file__)) + print('llvmpy version: ' + llvm.__version__) + print(sys.version) + + suite = unittest.TestSuite() + for cls in tests: + suite.addTest(unittest.makeSuite(cls)) + + # The default stream fails in IPython qtconsole on Windows, + # so just using sys.stdout + runner = unittest.TextTestRunner(verbosity=verbosity, stream=sys.stdout) + return runner.run(suite) + + +if __name__ == '__main__': + unittest.main() diff --git a/llvm/tests/__init__.py b/llvm/tests/__init__.py deleted file mode 100644 index 0bc4223..0000000 --- a/llvm/tests/__init__.py +++ /dev/null @@ -1,72 +0,0 @@ -from __future__ import print_function -import sys -import os -import unittest -import subprocess -import llvm - -tests = [] # stores unittest.TestCase objects - -# Isolated tests -# Tests that affect process-wide settings -isolated_tests = [] # stores modue name - - -def run(verbosity=1, run_isolated=True): - print('llvmpy is installed in: ' + os.path.dirname(__file__)) - print('llvmpy version: ' + llvm.__version__) - print(sys.version) - - files = filter(lambda s: s.startswith('test_') and s.endswith('.py'), - os.listdir(os.path.dirname(__file__))) - - for f in files: - fname = f.split('.', 1)[0] - __import__('.'.join([__name__, fname])) - - suite = unittest.TestSuite() - for cls in tests: - if cls: - suite.addTest(unittest.makeSuite(cls)) - - # The default stream fails in IPython qtconsole on Windows, - # so just using sys.stdout - - kwargs = dict(verbosity=verbosity, stream=sys.stdout) - - if sys.version_info[:2] > (2, 6): - kwargs['buffer'] = True - runner = unittest.TextTestRunner(**kwargs) - - try: - from guppy import hpy - except ImportError: - testresult = runner.run(suite) - else: - hp = hpy() - hp.setref() - testresult = runner.run(suite) - print(hp.heap()) - - if testresult and run_isolated: - # Run isolated tests - print("run isolated tests".center(80, '-')) - - for test in isolated_tests: - print(('testing %s' % test).center(80)) - - cmd = [sys.executable, '-m', test] - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - for line in p.stdout: - print(line.decode('utf8'), end='') - p.wait() - if p.returncode: - raise Exception("%s returned: %d" % (test, p.returncode)) - - return testresult - - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/support.py b/llvm/tests/support.py deleted file mode 100644 index 03c4c3c..0000000 --- a/llvm/tests/support.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import print_function, division -import sys -import platform -import unittest -import contextlib -import types -from llvm.tests import tests, isolated_tests # re-expose symbol - -IS_PY3K = sys.version_info[0] >= 3 -BITS = tuple.__itemsize__ * 8 -OS = sys.platform -MACHINE = platform.machine() -INTEL_CPUS = 'i386', 'x86_64' - -if sys.version_info[:2] <= (2, 6): - # create custom TestCase - class _TestCase(unittest.TestCase): - def assertIn(self, item, container): - self.assertTrue(item in container) - - def assertNotIn(self, item, container): - self.assertFalse(item in container) - - def assertLess(self, a, b): - self.assertTrue(a < b) - - def assertIs(self, a, b): - self.assertTrue(a is b) - - @contextlib.contextmanager - def assertRaises(self, exc): - try: - yield - except exc: - pass - else: - raise self.failureException("Did not raise %s" % exc) - -else: - _TestCase = unittest.TestCase - -class TestCase(_TestCase): - def assertClose(self, got, expect): - rel = abs(got - expect) / expect - self.assertTrue(rel < 1e-6, 'relative error = %f' % rel) - -#------------------------------------------------------------------------------- -# Tests decorators - -def _skipped(name, msg): - def _test(self): - if hasattr(unittest, 'SkipTest'): - raise unittest.SkipTest(msg) - else: - print('skipped %s' % name, msg) - return _test - -def skip_if(cond, msg=''): - def skipper(test): - if not isinstance(test, types.FunctionType): - repl = None - else: - repl = _skipped(test, msg) - return repl if cond else test - return skipper - -skip_if_not_64bits = skip_if(BITS != 64, msg='skipped not 64-bit') - -skip_if_not_32bits = skip_if(BITS != 32, msg='skipped not 32-bits') - -skip_if_win32 = skip_if(OS.startswith('win32'), msg='skipped win32') - -skip_if_not_win32 = skip_if(not OS.startswith('win32'), - msg='skipped not win32') -skip_if_not_intel_cpu = skip_if(MACHINE not in INTEL_CPUS, - msg='skipped not Intel CPU') - - diff --git a/llvm/tests/test_alloca.py b/llvm/tests/test_alloca.py deleted file mode 100644 index 60e3cf5..0000000 --- a/llvm/tests/test_alloca.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest -from llvm.core import Type, Module, Builder, Constant -from .support import TestCase, tests - -class TestAlloca(TestCase): - def test_alloca_alignment(self): - m = Module.new('') - f = m.add_function(Type.function(Type.void(), []), "foo") - b = Builder.new(f.append_basic_block('')) - inst = b.alloca(Type.int(32)) - inst.alignment = 4 - b.ret_void() - m.verify() - - self.assertTrue(inst.is_static) - self.assertFalse(inst.is_array) - self.assertEqual(inst.alignment, 4) - self.assertEqual(str(inst.array_size), 'i32 1') - -tests.append(TestAlloca) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_arg_attr.py b/llvm/tests/test_arg_attr.py deleted file mode 100644 index c388bd4..0000000 --- a/llvm/tests/test_arg_attr.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest -from llvm.core import Module, Type -import llvm.core as lc -from .support import TestCase, tests - -class TestArgAttr(TestCase): - def test_arg_attr(self): - m = Module.new('oifjda') - vptr = Type.pointer(Type.float()) - fnty = Type.function(Type.void(), [vptr] * 5) - func = m.add_function(fnty, 'foo') - attrs = [lc.ATTR_STRUCT_RET, lc.ATTR_BY_VAL, lc.ATTR_NEST, - lc.ATTR_NO_ALIAS, lc.ATTR_NO_CAPTURE] - for i, attr in enumerate(attrs): - arg = func.args[i] - self.assertEqual(i, arg.arg_no) - arg.add_attribute(attr) - self.assertTrue(attr in func.args[i]) - -tests.append(TestArgAttr) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_arith.py b/llvm/tests/test_arith.py deleted file mode 100644 index 5c50aeb..0000000 --- a/llvm/tests/test_arith.py +++ /dev/null @@ -1,73 +0,0 @@ -import unittest -import llvm -from llvm.core import (Module, Type, Builder) -from llvm.ee import EngineBuilder -from .support import TestCase, tests, skip_if, skip_if_not_64bits - -@skip_if(llvm.version < (3, 3)) -class TestArith(TestCase): - ''' - Test basic arithmetic support with LLVM MCJIT - ''' - def func_template(self, ty, op): - m = Module.new('dofjaa') - fnty = Type.function(ty, [ty, ty]) - fn = m.add_function(fnty, 'foo') - bldr = Builder.new(fn.append_basic_block('')) - bldr.ret(getattr(bldr, op)(*fn.args)) - - engine = EngineBuilder.new(m).mcjit(True).create() - ptr = engine.get_pointer_to_function(fn) - - from ctypes import c_uint32, c_uint64, c_float, c_double, CFUNCTYPE - - maptypes = { - Type.int(32): c_uint32, - Type.int(64): c_uint64, - Type.float(): c_float, - Type.double(): c_double, - } - cty = maptypes[ty] - prototype = CFUNCTYPE(*[cty] * 3) - callee = prototype(ptr) - callee(12, 23) - - def template(self, iop, fop): - inttys = [Type.int(32), Type.int(64)] - flttys = [Type.float(), Type.double()] - - if iop: - for ty in inttys: - self.func_template(ty, iop) - if fop: - for ty in flttys: - self.func_template(ty, fop) - - def test_add(self): - self.template('add', 'fadd') - - def test_sub(self): - self.template('sub', 'fsub') - - def test_mul(self): - self.template('mul', 'fmul') - - @skip_if_not_64bits - def test_div(self): - ''' - known failure due to unresolved external symbol __udivdi3 - ''' - self.template('udiv', None) # 'fdiv') - - @skip_if_not_64bits - def test_rem(self): - ''' - known failure due to unresolved external symbol __umoddi3 - ''' - self.template('urem', None) # 'frem') - -tests.append(TestArith) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_asm.py b/llvm/tests/test_asm.py deleted file mode 100644 index d4e02fb..0000000 --- a/llvm/tests/test_asm.py +++ /dev/null @@ -1,58 +0,0 @@ -import os -import unittest -import tempfile -import shutil -from llvm.core import Module, Type -from .support import TestCase, tests - -class TestAsm(TestCase): - def setUp(self): - self.tmpdir = tempfile.mkdtemp() - - def tearDown(self): - shutil.rmtree(self.tmpdir) - - def test_asm(self): - # create a module - m = Module.new('module1') - m.add_global_variable(Type.int(), 'i') - - # write it's assembly representation to a file - asm = str(m) - - testasm_ll = os.path.join(self.tmpdir, 'testasm.ll') - with open(testasm_ll, "w") as fout: - fout.write(asm) - - # read it back into a module - with open(testasm_ll) as fin: - m2 = Module.from_assembly(fin) - # The default `m.id` is ''. - m2.id = m.id # Copy the name from `m` - - self.assertEqual(str(m2).strip(), asm.strip()) - - def test_bitcode(self): - # create a module - m = Module.new('module1') - m.add_global_variable(Type.int(), 'i') - - # write it's assembly representation to a file - asm = str(m) - - testasm_bc = os.path.join(self.tmpdir, 'testasm.bc') - with open(testasm_bc, "wb") as fout: - m.to_bitcode(fout) - - # read it back into a module - with open(testasm_bc, "rb") as fin: - m2 = Module.from_bitcode(fin) - # The default `m.id` is ''. - m2.id = m.id # Copy the name from `m` - - self.assertEqual(str(m2).strip(), asm.strip()) - -tests.append(TestAsm) - -if __name__ == '__main__': - unittest.main() diff --git a/llvm/tests/test_atomic.py b/llvm/tests/test_atomic.py deleted file mode 100644 index 2a2f402..0000000 --- a/llvm/tests/test_atomic.py +++ /dev/null @@ -1,85 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Builder, Constant) -from .support import TestCase, tests - -class TestAtomic(TestCase): - orderings = ['unordered', 'monotonic', 'acquire', - 'release', 'acq_rel', 'seq_cst'] - - atomic_op = ['xchg', 'add', 'sub', 'and', 'nand', 'or', 'xor', - 'max', 'min', 'umax', 'umin'] - - def test_atomic_cmpxchg(self): - mod = Module.new('mod') - functype = Type.function(Type.void(), []) - func = mod.add_function(functype, name='foo') - bb = func.append_basic_block('entry') - bldr = Builder.new(bb) - ptr = bldr.alloca(Type.int()) - - old = bldr.load(ptr) - new = Constant.int(Type.int(), 1234) - - for ordering in self.orderings: - inst = bldr.atomic_cmpxchg(ptr, old, new, ordering) - self.assertEqual(ordering, str(inst).strip().split(' ')[-1]) - - inst = bldr.atomic_cmpxchg(ptr, old, new, ordering, crossthread=False) - self.assertEqual('singlethread', str(inst).strip().split(' ')[-2]) - - def test_atomic_rmw(self): - mod = Module.new('mod') - functype = Type.function(Type.void(), []) - func = mod.add_function(functype, name='foo') - bb = func.append_basic_block('entry') - bldr = Builder.new(bb) - ptr = bldr.alloca(Type.int()) - - val = Constant.int(Type.int(), 1234) - - for ordering in self.orderings: - inst = bldr.atomic_rmw('xchg', ptr, val, ordering) - self.assertEqual(ordering, str(inst).split(' ')[-1]) - - for op in self.atomic_op: - inst = bldr.atomic_rmw(op, ptr, val, ordering) - self.assertEqual(op, str(inst).strip().split(' ')[3]) - - inst = bldr.atomic_rmw('xchg', ptr, val, ordering, crossthread=False) - self.assertEqual('singlethread', str(inst).strip().split(' ')[-2]) - - for op in self.atomic_op: - atomic_op = getattr(bldr, 'atomic_%s' % op) - inst = atomic_op(ptr, val, ordering) - self.assertEqual(op, str(inst).strip().split(' ')[3]) - - def test_atomic_ldst(self): - mod = Module.new('mod') - functype = Type.function(Type.void(), []) - func = mod.add_function(functype, name='foo') - bb = func.append_basic_block('entry') - bldr = Builder.new(bb) - ptr = bldr.alloca(Type.int()) - - for ordering in self.orderings: - loaded = bldr.atomic_load(ptr, ordering) - self.assert_('load atomic' in str(loaded)) - self.assertEqual(ordering, - str(loaded).strip().split(' ')[-3].rstrip(',')) - self.assert_('align 1' in str(loaded)) - - stored = bldr.atomic_store(loaded, ptr, ordering) - self.assert_('store atomic' in str(stored)) - self.assertEqual(ordering, - str(stored).strip().split(' ')[-3].rstrip(',')) - self.assert_('align 1' in str(stored)) - - fenced = bldr.fence(ordering) - self.assertEqual(['fence', ordering], - str(fenced).strip().split(' ')) - -tests.append(TestAtomic) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_attr.py b/llvm/tests/test_attr.py deleted file mode 100644 index d1df700..0000000 --- a/llvm/tests/test_attr.py +++ /dev/null @@ -1,33 +0,0 @@ -import unittest -try: - from StringIO import StringIO -except ImportError: - from io import StringIO - -from llvm.core import Module -from .support import TestCase, tests - -class TestAttr(TestCase): - def make_module(self): - test_module = """ - define void @sum(i32*, i32*) { - entry: - ret void - } - """ - buf = StringIO(test_module) - return Module.from_assembly(buf) - - def test_align(self): - m = self.make_module() - f = m.get_function_named('sum') - f.args[0].alignment = 16 - self.assert_("align 16" in str(f)) - self.assertEqual(f.args[0].alignment, 16) - -tests.append(TestAttr) - - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_cmp.py b/llvm/tests/test_cmp.py deleted file mode 100644 index 85cf1f0..0000000 --- a/llvm/tests/test_cmp.py +++ /dev/null @@ -1,26 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Builder, Constant) -import llvm.core as lc -from .support import TestCase, tests - -class TestCmp(TestCase): - def test_arg_attr(self): - m = Module.new('oifjda') - fnty = Type.function(Type.void(), [Type.int()]) - func = m.add_function(fnty, 'foo') - bb = func.append_basic_block('') - bldr = Builder.new(bb) - - cmpinst = bldr.icmp(lc.ICMP_ULE, func.args[0], - Constant.int(Type.int(), 123)) - self.assertTrue(repr(cmpinst.predicate).startswith('ICMP_ULE')) - self.assertEqual(cmpinst.predicate, lc.ICMP_ULE) - bldr.ret_void() - - func.verify() - -tests.append(TestCmp) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_const_expr.py b/llvm/tests/test_const_expr.py deleted file mode 100644 index c398573..0000000 --- a/llvm/tests/test_const_expr.py +++ /dev/null @@ -1,23 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Builder, Constant) -import llvm.core as lc - -from .support import TestCase, tests - -class TestConstExpr(TestCase): - - def test_constexpr_opcode(self): - mod = Module.new('test_constexpr_opcode') - func = mod.add_function(Type.function(Type.void(), []), name="foo") - builder = Builder.new(func.append_basic_block('entry')) - a = builder.inttoptr(Constant.int(Type.int(), 123), - Type.pointer(Type.int())) - self.assertTrue(isinstance(a, lc.ConstantExpr)) - self.assertEqual(a.opcode, lc.OPCODE_INTTOPTR) - self.assertEqual(a.opcode_name, "inttoptr") - -tests.append(TestConstExpr) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_cpu_support.py b/llvm/tests/test_cpu_support.py deleted file mode 100644 index 7874706..0000000 --- a/llvm/tests/test_cpu_support.py +++ /dev/null @@ -1,89 +0,0 @@ -import unittest -import math -from llvm.core import (Module, Type, Function, Builder, - Constant) -from llvm.ee import EngineBuilder -import llvm.core as lc -import llvm.ee as le -from llvm.workaround.avx_support import detect_avx_support -from .support import TestCase, tests, skip_if_not_intel_cpu, skip_if - -@skip_if_not_intel_cpu -class TestCPUSupport(TestCase): - - def _build_test_module(self): - mod = Module.new('test') - - float = Type.double() - mysinty = Type.function( float, [float] ) - mysin = mod.add_function(mysinty, "mysin") - block = mysin.append_basic_block("entry") - b = Builder.new(block) - - sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) - pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) - cos = Function.intrinsic(mod, lc.INTR_COS, [float]) - - mysin.args[0].name = "x" - x = mysin.args[0] - one = Constant.real(float, "1") - cosx = b.call(cos, [x], "cosx") - cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") - onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub - sin = b.call(sqrt, [onemc2], "sin") - b.ret(sin) - return mod, mysin - - def _template(self, mattrs): - mod, func = self._build_test_module() - ee = self._build_engine(mod, mattrs=mattrs) - arg = le.GenericValue.real(Type.double(), 1.234) - retval = ee.run_function(func, [arg]) - - golden = math.sin(1.234) - answer = retval.as_real(Type.double()) - self.assertTrue(abs(answer-golden)/golden < 1e-5) - - - def _build_engine(self, mod, mattrs): - if mattrs: - return EngineBuilder.new(mod).mattrs(mattrs).create() - else: - return EngineBuilder.new(mod).create() - - def test_cpu_support2(self): - features = 'sse3', 'sse41', 'sse42', 'avx' - mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print('disable mattrs', mattrs) - self._template(mattrs) - - def test_cpu_support3(self): - features = 'sse41', 'sse42', 'avx' - mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print('disable mattrs', mattrs) - self._template(mattrs) - - def test_cpu_support4(self): - features = 'sse42', 'avx' - mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print('disable mattrs', mattrs) - self._template(mattrs) - - def test_cpu_support5(self): - features = 'avx', - mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print('disable mattrs', mattrs) - self._template(mattrs) - - @skip_if(not detect_avx_support(), msg="no AVX support") - def test_cpu_support6(self): - features = [] - mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print('disable mattrs', mattrs) - self._template(mattrs) - -tests.append(TestCPUSupport) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_engine_builder.py b/llvm/tests/test_engine_builder.py deleted file mode 100644 index 24037d6..0000000 --- a/llvm/tests/test_engine_builder.py +++ /dev/null @@ -1,65 +0,0 @@ -import unittest -from llvm.core import Module, Type, Builder, Constant -from llvm.ee import EngineBuilder -import llvm.ee as le -import llvmpy - -from .support import TestCase, tests - -class TestEngineBuilder(TestCase): - - def make_test_module(self): - module = Module.new("testmodule") - fnty = Type.function(Type.int(), []) - function = module.add_function(fnty, 'foo') - bb_entry = function.append_basic_block('entry') - builder = Builder.new(bb_entry) - builder.ret(Constant.int(Type.int(), 0xcafe)) - module.verify() - return module - - def run_foo(self, ee, module): - function = module.get_function_named('foo') - retval = ee.run_function(function, []) - self.assertEqual(retval.as_int(), 0xcafe) - - - def test_enginebuilder_basic(self): - module = self.make_test_module() - self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr)) - ee = EngineBuilder.new(module).create() - self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr)) - self.run_foo(ee, module) - - - def test_enginebuilder_with_tm(self): - tm = le.TargetMachine.new() - module = self.make_test_module() - self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr)) - ee = EngineBuilder.new(module).create(tm) - self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr)) - self.run_foo(ee, module) - - def test_enginebuilder_force_jit(self): - module = self.make_test_module() - ee = EngineBuilder.new(module).force_jit().create() - - self.run_foo(ee, module) -# -# def test_enginebuilder_force_interpreter(self): -# module = self.make_test_module() -# ee = EngineBuilder.new(module).force_interpreter().create() -# -# self.run_foo(ee, module) - - def test_enginebuilder_opt(self): - module = self.make_test_module() - ee = EngineBuilder.new(module).opt(3).create() - - self.run_foo(ee, module) - -tests.append(TestEngineBuilder) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_exact.py b/llvm/tests/test_exact.py deleted file mode 100644 index db711a5..0000000 --- a/llvm/tests/test_exact.py +++ /dev/null @@ -1,37 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Builder) -from .support import TestCase, tests - -class TestExact(TestCase): - def make_module(self): - mod = Module.new('asdfa') - fnty = Type.function(Type.void(), [Type.int()] * 2) - func = mod.add_function(fnty, 'foo') - bldr = Builder.new(func.append_basic_block('')) - return mod, func, bldr - - def has_exact(self, inst, op): - self.assertTrue(('%s exact' % op) in str(inst), "exact flag does not work") - - def _test_template(self, opf, opname): - mod, func, bldr = self.make_module() - a, b = func.args - self.has_exact(opf(bldr, a, b, exact=True), opname) - - def test_udiv_exact(self): - self._test_template(Builder.udiv, 'udiv') - - def test_sdiv_exact(self): - self._test_template(Builder.sdiv, 'sdiv') - - def test_lshr_exact(self): - self._test_template(Builder.lshr, 'lshr') - - def test_ashr_exact(self): - self._test_template(Builder.ashr, 'ashr') - -tests.append(TestExact) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_execution_engine.py b/llvm/tests/test_execution_engine.py deleted file mode 100644 index 446b25f..0000000 --- a/llvm/tests/test_execution_engine.py +++ /dev/null @@ -1,47 +0,0 @@ -import unittest -from llvm.core import Type -import llvm.core as lc -import llvm.ee as le - -from .support import TestCase, tests - -class TestExecutionEngine(TestCase): - def test_get_pointer_to_global(self): - module = lc.Module.new(str(self)) - gvar = module.add_global_variable(Type.int(), 'hello') - X = 1234 - gvar.initializer = lc.Constant.int(Type.int(), X) - - ee = le.ExecutionEngine.new(module) - ptr = ee.get_pointer_to_global(gvar) - from ctypes import c_void_p, cast, c_int, POINTER - casted = cast(c_void_p(ptr), POINTER(c_int)) - self.assertEqual(X, casted[0]) - - def test_add_global_mapping(self): - module = lc.Module.new(str(self)) - gvar = module.add_global_variable(Type.int(), 'hello') - - fnty = lc.Type.function(Type.int(), []) - foo = module.add_function(fnty, name='foo') - bldr = lc.Builder.new(foo.append_basic_block('entry')) - bldr.ret(bldr.load(gvar)) - - ee = le.ExecutionEngine.new(module) - from ctypes import c_int, addressof, CFUNCTYPE - value = 0xABCD - value_ctype = c_int(value) - value_pointer = addressof(value_ctype) - - ee.add_global_mapping(gvar, value_pointer) - - foo_addr = ee.get_pointer_to_function(foo) - prototype = CFUNCTYPE(c_int) - foo_callable = prototype(foo_addr) - self.assertEqual(foo_callable(), value) - -tests.append(TestExecutionEngine) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_inlining.py b/llvm/tests/test_inlining.py deleted file mode 100644 index 3104da8..0000000 --- a/llvm/tests/test_inlining.py +++ /dev/null @@ -1,34 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Builder, Constant, inline_function) -from .support import TestCase, tests - -class TestInlining(TestCase): - def test_inline_call(self): - mod = Module.new(__name__) - callee = mod.add_function(Type.function(Type.int(), [Type.int()]), - name='bar') - - builder = Builder.new(callee.append_basic_block('entry')) - builder.ret(builder.add(callee.args[0], callee.args[0])) - - caller = mod.add_function(Type.function(Type.int(), []), - name='foo') - - builder = Builder.new(caller.append_basic_block('entry')) - callinst = builder.call(callee, [Constant.int(Type.int(), 1234)]) - builder.ret(callinst) - - pre_inlining = str(caller) - self.assertIn('call', pre_inlining) - - self.assertTrue(inline_function(callinst)) - - post_inlining = str(caller) - self.assertNotIn('call', post_inlining) - self.assertIn('2468', post_inlining) - -tests.append(TestInlining) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_intel_native_asm.py b/llvm/tests/test_intel_native_asm.py deleted file mode 100644 index 088413a..0000000 --- a/llvm/tests/test_intel_native_asm.py +++ /dev/null @@ -1,31 +0,0 @@ -import sys -import os -import unittest -from llvm.core import Builder, Module, Type -import llvm.core as lc -from .support import TestCase, skip_if_not_intel_cpu, isolated_tests - -@skip_if_not_intel_cpu -class TestNativeAsm(TestCase): - - def test_asm(self): - m = Module.new('module1') - - foo = m.add_function(Type.function(Type.int(), - [Type.int(), Type.int()]), - name="foo") - bldr = Builder.new(foo.append_basic_block('entry')) - x = bldr.add(foo.args[0], foo.args[1]) - bldr.ret(x) - - att_syntax = m.to_native_assembly() - os.environ["LLVMPY_OPTIONS"] = "-x86-asm-syntax=intel" - lc.parse_environment_options(sys.argv[0], "LLVMPY_OPTIONS") - intel_syntax = m.to_native_assembly() - - self.assertNotEqual(att_syntax, intel_syntax) - -isolated_tests.append(__name__) - -if __name__ == '__main__': - unittest.main() diff --git a/llvm/tests/test_intrinsic.py b/llvm/tests/test_intrinsic.py deleted file mode 100644 index e30bd49..0000000 --- a/llvm/tests/test_intrinsic.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest -import sys -import math -from llvm.core import (Module, Type, Function, Builder, Constant) -import llvm.core as lc -import llvm.ee as le -from .support import TestCase, tests, BITS - -class TestIntrinsic(TestCase): - def test_bswap(self): - # setup a function and a builder - mod = Module.new('test') - functy = Type.function(Type.int(), []) - func = mod.add_function(functy, "showme") - block = func.append_basic_block("entry") - b = Builder.new(block) - - # let's do bswap on a 32-bit integer using llvm.bswap - val = Constant.int(Type.int(), 0x42) - bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()]) - - bswap_res = b.call(bswap, [val]) - b.ret(bswap_res) - - # logging.debug(mod) - - # the output is: - # - # ; ModuleID = 'test' - # - # define void @showme() { - # entry: - # %0 = call i32 @llvm.bswap.i32(i32 42) - # ret i32 %0 - # } - - # let's run the function - ee = le.ExecutionEngine.new(mod) - retval = ee.run_function(func, []) - self.assertEqual(retval.as_int(), 0x42000000) - - def test_mysin(self): - if sys.platform == 'win32' and BITS == 32: - # float32 support is known to fail on 32-bit Windows - return - - # mysin(x) = sqrt(1.0 - pow(cos(x), 2)) - mod = Module.new('test') - - float = Type.float() - mysinty = Type.function( float, [float] ) - mysin = mod.add_function(mysinty, "mysin") - block = mysin.append_basic_block("entry") - b = Builder.new(block) - - sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) - pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) - cos = Function.intrinsic(mod, lc.INTR_COS, [float]) - - mysin.args[0].name = "x" - x = mysin.args[0] - one = Constant.real(float, "1") - cosx = b.call(cos, [x], "cosx") - cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") - onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub - sin = b.call(sqrt, [onemc2], "sin") - b.ret(sin) - #logging.debug(mod) - -# ; ModuleID = 'test' -# -# define void @showme() { -# entry: -# call i32 @llvm.bswap.i32( i32 42 ) ; :0 [#uses -# } -# -# declare i32 @llvm.bswap.i32(i32) nounwind readnone -# -# define float @mysin(float %x) { -# entry: -# %cosx = call float @llvm.cos.f32( float %x ) ; [#uses -# %sin = call float @llvm.sqrt.f32( float %onemc2 ) -# ret float %sin -# } -# -# declare float @llvm.sqrt.f32(float) nounwind readnone -# -# declare float @llvm.powi.f32(float, i32) nounwind readnone -# -# declare float @llvm.cos.f32(float) nounwind readnone - - # let's run the function - - from llvm.workaround.avx_support import detect_avx_support - if not detect_avx_support(): - ee = le.EngineBuilder.new(mod).mattrs("-avx").create() - else: - ee = le.EngineBuilder.new(mod).create() - - arg = le.GenericValue.real(Type.float(), 1.234) - retval = ee.run_function(mysin, [arg]) - - golden = math.sin(1.234) - answer = retval.as_real(Type.float()) - self.assertTrue(abs(answer-golden)/golden < 1e-5) - -tests.append(TestIntrinsic) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_intrinsic_basic.py b/llvm/tests/test_intrinsic_basic.py deleted file mode 100644 index d89106a..0000000 --- a/llvm/tests/test_intrinsic_basic.py +++ /dev/null @@ -1,99 +0,0 @@ -import unittest -import sys -import math -from llvm.core import (Module, Type, Function, Builder) -import llvm.core as lc -import llvm.ee as le -from .support import TestCase, BITS, tests - -class TestIntrinsicBasic(TestCase): - - def _build_module(self, float): - mod = Module.new('test') - functy = Type.function(float, [float]) - func = mod.add_function(functy, "mytest%s" % float) - block = func.append_basic_block("entry") - b = Builder.new(block) - return mod, func, b - - def _template(self, mod, func, pyfunc): - float = func.type.pointee.return_type - - from llvm.workaround.avx_support import detect_avx_support - if not detect_avx_support(): - ee = le.EngineBuilder.new(mod).mattrs("-avx").create() - else: - ee = le.EngineBuilder.new(mod).create() - arg = le.GenericValue.real(float, 1.234) - retval = ee.run_function(func, [arg]) - golden = pyfunc(1.234) - answer = retval.as_real(float) - self.assertTrue(abs(answer - golden) / golden < 1e-7) - - def test_sqrt_f32(self): - float = Type.float() - mod, func, b = self._build_module(float) - intr = Function.intrinsic(mod, lc.INTR_SQRT, [float]) - b.ret(b.call(intr, func.args)) - self._template(mod, func, math.sqrt) - - def test_sqrt_f64(self): - float = Type.double() - mod, func, b = self._build_module(float) - intr = Function.intrinsic(mod, lc.INTR_SQRT, [float]) - b.ret(b.call(intr, func.args)) - self._template(mod, func, math.sqrt) - - def test_cos_f32(self): - if sys.platform == 'win32' and BITS == 32: - # float32 support is known to fail on 32-bit Windows - return - float = Type.float() - mod, func, b = self._build_module(float) - intr = Function.intrinsic(mod, lc.INTR_COS, [float]) - b.ret(b.call(intr, func.args)) - self._template(mod, func, math.cos) - - def test_cos_f64(self): - float = Type.double() - mod, func, b = self._build_module(float) - intr = Function.intrinsic(mod, lc.INTR_COS, [float]) - b.ret(b.call(intr, func.args)) - self._template(mod, func, math.cos) - - def test_sin_f32(self): - if sys.platform == 'win32' and BITS == 32: - # float32 support is known to fail on 32-bit Windows - return - float = Type.float() - mod, func, b = self._build_module(float) - intr = Function.intrinsic(mod, lc.INTR_SIN, [float]) - b.ret(b.call(intr, func.args)) - self._template(mod, func, math.sin) - - def test_sin_f64(self): - float = Type.double() - mod, func, b = self._build_module(float) - intr = Function.intrinsic(mod, lc.INTR_SIN, [float]) - b.ret(b.call(intr, func.args)) - self._template(mod, func, math.sin) - - def test_powi_f32(self): - float = Type.float() - mod, func, b = self._build_module(float) - intr = Function.intrinsic(mod, lc.INTR_POWI, [float]) - b.ret(b.call(intr, [func.args[0], lc.Constant.int(Type.int(), 2)])) - self._template(mod, func, lambda x: x**2) - - def test_powi_f64(self): - float = Type.double() - mod, func, b = self._build_module(float) - intr = Function.intrinsic(mod, lc.INTR_POWI, [float]) - b.ret(b.call(intr, [func.args[0], lc.Constant.int(Type.int(), 2)])) - self._template(mod, func, lambda x: x**2) - -tests.append(TestIntrinsicBasic) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_issue_10.py b/llvm/tests/test_issue_10.py deleted file mode 100644 index 61b390d..0000000 --- a/llvm/tests/test_issue_10.py +++ /dev/null @@ -1,26 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Builder) -from .support import TestCase, tests - -class TestIssue10(TestCase): - def test_issue10(self): - m = Module.new('a') - ti = Type.int() - tf = Type.function(ti, [ti, ti]) - - f = m.add_function(tf, "func1") - - bb = f.append_basic_block('entry') - - b = Builder.new(bb) - - # There are no instructions in bb. Positioning of the - # builder at beginning (or end) should succeed (trivially). - b.position_at_end(bb) - b.position_at_beginning(bb) - -tests.append(TestIssue10) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_llrt.py b/llvm/tests/test_llrt.py deleted file mode 100644 index 2b220f5..0000000 --- a/llvm/tests/test_llrt.py +++ /dev/null @@ -1,34 +0,0 @@ -import unittest -import llvm.core as lc -import llvm.ee as le -from .support import TestCase, tests - -class TestLLRT(TestCase): - def test_llrt_divmod(self): - from llvm import llrt - m = lc.Module.new('testllrt') - longlong = lc.Type.int(64) - lfunc = m.add_function(lc.Type.function(longlong, [longlong, longlong]), 'foo') - bldr = lc.Builder.new(lfunc.append_basic_block('')) - bldr.ret(bldr.udiv(*lfunc.args)) - - llrt.replace_divmod64(lfunc) - - rt = llrt.LLRT() - rt.install_symbols() - - engine = le.EngineBuilder.new(m).create() - pointer = engine.get_pointer_to_function(lfunc) - - from ctypes import CFUNCTYPE, c_uint64 - func = CFUNCTYPE(c_uint64, c_uint64, c_uint64)(pointer) - a, b = 98342, 2231 - self.assertEqual(func(98342, 2231), 98342 // 2231) - - rt.uninstall_symbols() - -tests.append(TestLLRT) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_mcjit.py b/llvm/tests/test_mcjit.py deleted file mode 100644 index 8d00ac5..0000000 --- a/llvm/tests/test_mcjit.py +++ /dev/null @@ -1,73 +0,0 @@ -import unittest -import sys -import llvm -from llvm.core import (Module, Type, Builder) -from llvm.ee import EngineBuilder - -import llvm.ee as le -from .support import TestCase, tests, BITS - -class TestMCJIT(TestCase): - def test_mcjit(self): - m = Module.new('oidfjs') - fnty = Type.function(Type.int(), [Type.int(), Type.int()]) - func = m.add_function(fnty, 'foo') - bb = func.append_basic_block('') - bldr = Builder.new(bb) - bldr.ret(bldr.add(*func.args)) - - func.verify() - - engine = EngineBuilder.new(m).mcjit(True).create() - ptr = engine.get_pointer_to_function(func) - - from ctypes import c_int, CFUNCTYPE - callee = CFUNCTYPE(c_int, c_int, c_int)(ptr) - self.assertEqual(321 + 123, callee(321, 123)) - - def test_multi_module_linking(self): - # generate external library module - m = Module.new('external-library-module') - fnty = Type.function(Type.int(), [Type.int(), Type.int()]) - libfname = 'myadd' - func = m.add_function(fnty, libfname) - bb = func.append_basic_block('') - bldr = Builder.new(bb) - bldr.ret(bldr.add(*func.args)) - func.verify() - - # JIT the lib module and bind dynamic symbol - libengine = EngineBuilder.new(m).mcjit(True).create() - myadd_ptr = libengine.get_pointer_to_function(func) - le.dylib_add_symbol(libfname, myadd_ptr) - - # reference external library - m = Module.new('user') - fnty = Type.function(Type.int(), [Type.int(), Type.int()]) - func = m.add_function(fnty, 'foo') - bb = func.append_basic_block('') - bldr = Builder.new(bb) - extadd = m.get_or_insert_function(fnty, name=libfname) - bldr.ret(bldr.call(extadd, func.args)) - func.verify() - - # JIT the user module - engine = EngineBuilder.new(m).mcjit(True).create() - ptr = engine.get_pointer_to_function(func) - self.assertEqual(myadd_ptr, - engine.get_pointer_to_named_function(libfname)) - - from ctypes import c_int, CFUNCTYPE - callee = CFUNCTYPE(c_int, c_int, c_int)(ptr) - self.assertEqual(321 + 123, callee(321, 123)) - - -if (llvm.version >= (3, 3) and - not (sys.platform.startswith('win32') and BITS == 64)): - # MCJIT broken in 3.2, the test will segfault in OSX? - # Compatbility problem on windows 7 64-bit? - tests.append(TestMCJIT) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_metadata.py b/llvm/tests/test_metadata.py deleted file mode 100644 index 139a1da..0000000 --- a/llvm/tests/test_metadata.py +++ /dev/null @@ -1,25 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Constant, MetaData, MetaDataString) -from .support import TestCase, tests - -class TestMetaData(TestCase): - # test module metadata - def test_metadata(self): - m = Module.new('a') - t = Type.int() - metadata = MetaData.get(m, [Constant.int(t, 100), - MetaDataString.get(m, 'abcdef'), - None]) - MetaData.add_named_operand(m, 'foo', metadata) - self.assertEqual(MetaData.get_named_operands(m, 'foo'), [metadata]) - self.assertEqual(MetaData.get_named_operands(m, 'bar'), []) - self.assertEqual(len(metadata.operands), 3) - self.assertEqual(metadata.operands[0].z_ext_value, 100) - self.assertEqual(metadata.operands[1].string, 'abcdef') - self.assertTrue(metadata.operands[2] is None) - -tests.append(TestMetaData) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_named_metadata.py b/llvm/tests/test_named_metadata.py deleted file mode 100644 index 0c75da3..0000000 --- a/llvm/tests/test_named_metadata.py +++ /dev/null @@ -1,20 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Constant, MetaData) -from .support import TestCase, tests - - -class TestNamedMetaData(TestCase): - def test_named_md(self): - m = Module.new('test_named_md') - nmd = m.get_or_insert_named_metadata('something') - md = MetaData.get(m, [Constant.int(Type.int(), 0xbeef)]) - nmd.add(md) - self.assertTrue(str(nmd).startswith('!something')) - ir = str(m) - self.assertTrue('!something' in ir) - -tests.append(TestNamedMetaData) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_native.py b/llvm/tests/test_native.py deleted file mode 100644 index 04dde76..0000000 --- a/llvm/tests/test_native.py +++ /dev/null @@ -1,81 +0,0 @@ -import unittest -import os -import sys -import shutil -import subprocess -import tempfile -from distutils.spawn import find_executable -from llvm.core import (Module, Type, Builder, Constant) -from .support import TestCase, IS_PY3K, tests, skip_if - -@skip_if(sys.platform in ('win32', 'darwin')) -class TestNative(TestCase): - - def setUp(self): - self.tmpdir = tempfile.mkdtemp() - - def tearDown(self): - shutil.rmtree(self.tmpdir) - - - def _make_module(self): - m = Module.new('module1') - m.add_global_variable(Type.int(), 'i') - - fty = Type.function(Type.int(), []) - f = m.add_function(fty, name='main') - - bldr = Builder.new(f.append_basic_block('entry')) - bldr.ret(Constant.int(Type.int(), 0xab)) - - return m - - def _compile(self, src): - cc = find_executable('cc') - if not cc: - return - - dst = os.path.join(self.tmpdir, 'llvmobj.out') - s = subprocess.call([cc, '-o', dst, src]) - if s != 0: - raise Exception("Cannot compile") - - s = subprocess.call([dst]) - self.assertEqual(s, 0xab) - - def test_assembly(self): - # if sys.platform == 'darwin': - # # skip this test on MacOSX for now - # return - - m = self._make_module() - output = m.to_native_assembly() - - src = os.path.join(self.tmpdir, 'llvmasm.s') - with open(src, 'wb') as fout: - if IS_PY3K: - fout.write(output.encode('utf-8')) - else: - fout.write(output) - - self._compile(src) - - def test_object(self): - ''' - Note: Older Darwin with GCC will report missing _main symbol when - compile the object file to an executable. - ''' - m = self._make_module() - output = m.to_native_object() - - src = os.path.join(self.tmpdir, 'llvmobj.o') - with open(src, 'wb') as fout: - fout.write(output) - - self._compile(src) - -tests.append(TestNative) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_nuw_nsw.py b/llvm/tests/test_nuw_nsw.py deleted file mode 100644 index 70babb9..0000000 --- a/llvm/tests/test_nuw_nsw.py +++ /dev/null @@ -1,48 +0,0 @@ -import unittest -from llvm.core import Module, Type, Builder -from .support import TestCase, tests - -class TestNUWNSW(TestCase): - def make_module(self): - mod = Module.new('asdfa') - fnty = Type.function(Type.void(), [Type.int()] * 2) - func = mod.add_function(fnty, 'foo') - bldr = Builder.new(func.append_basic_block('')) - return mod, func, bldr - - def has_nsw(self, inst, op): - self.assertTrue(('%s nsw' % op) in str(inst), "NSW flag does not work") - - def has_nuw(self, inst, op): - self.assertTrue(('%s nuw' % op) in str(inst), "NUW flag does not work") - - def _test_template(self, opf, opname): - mod, func, bldr = self.make_module() - a, b = func.args - self.has_nsw(opf(bldr, a, b, nsw=True), opname) - self.has_nuw(opf(bldr, a, b, nuw=True), opname) - - def test_add_nuw_nsw(self): - self._test_template(Builder.add, 'add') - - def test_sub_nuw_nsw(self): - self._test_template(Builder.sub, 'sub') - - def test_mul_nuw_nsw(self): - self._test_template(Builder.mul, 'mul') - - def test_shl_nuw_nsw(self): - self._test_template(Builder.shl, 'shl') - - def test_neg_nuw_nsw(self): - mod, func, bldr = self.make_module() - a, b = func.args - self.has_nsw(bldr.neg(a, nsw=True), 'sub') - self.has_nuw(bldr.neg(a, nuw=True), 'sub') - - -tests.append(TestNUWNSW) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_obj_cache.py b/llvm/tests/test_obj_cache.py deleted file mode 100644 index 49cec6e..0000000 --- a/llvm/tests/test_obj_cache.py +++ /dev/null @@ -1,107 +0,0 @@ -import unittest -from llvm.core import Module, Type, GlobalVariable, Function, Builder -from .support import TestCase, tests - -class TestObjCache(TestCase): - - def test_objcache(self): - # Testing module aliasing - m1 = Module.new('a') - t = Type.int() - ft = Type.function(t, [t]) - f1 = m1.add_function(ft, "func") - m2 = f1.module - self.assert_(m1 is m2) - - # Testing global vairable aliasing 1 - gv1 = GlobalVariable.new(m1, t, "gv") - gv2 = GlobalVariable.get(m1, "gv") - self.assert_(gv1 is gv2) - - # Testing global vairable aliasing 2 - gv3 = m1.global_variables[0] - self.assert_(gv1 is gv3) - - # Testing global vairable aliasing 3 - gv2 = None - gv3 = None - - gv1.delete() - - gv4 = GlobalVariable.new(m1, t, "gv") - - self.assert_(gv1 is not gv4) - - # Testing function aliasing 1 - b1 = f1.append_basic_block('entry') - f2 = b1.function - self.assert_(f1 is f2) - - # Testing function aliasing 2 - f3 = m1.get_function_named("func") - self.assert_(f1 is f3) - - # Testing function aliasing 3 - f4 = Function.get_or_insert(m1, ft, "func") - self.assert_(f1 is f4) - - # Testing function aliasing 4 - f5 = Function.get(m1, "func") - self.assert_(f1 is f5) - - # Testing function aliasing 5 - f6 = m1.get_or_insert_function(ft, "func") - self.assert_(f1 is f6) - - # Testing function aliasing 6 - f7 = m1.functions[0] - self.assert_(f1 is f7) - - # Testing argument aliasing - a1 = f1.args[0] - a2 = f1.args[0] - self.assert_(a1 is a2) - - # Testing basic block aliasing 1 - b2 = f1.basic_blocks[0] - self.assert_(b1 is b2) - - # Testing basic block aliasing 2 - b3 = f1.entry_basic_block - self.assert_(b1 is b3) - - # Testing basic block aliasing 3 - b31 = f1.entry_basic_block - self.assert_(b1 is b31) - - # Testing basic block aliasing 4 - bldr = Builder.new(b1) - b4 = bldr.basic_block - self.assert_(b1 is b4) - - # Testing basic block aliasing 5 - i1 = bldr.ret_void() - b5 = i1.basic_block - self.assert_(b1 is b5) - - # Testing instruction aliasing 1 - i2 = b5.instructions[0] - self.assert_(i1 is i2) - - # phi node - phi = bldr.phi(t) - phi.add_incoming(f1.args[0], b1) - v2 = phi.get_incoming_value(0) - b6 = phi.get_incoming_block(0) - - # Testing PHI / basic block aliasing 5 - self.assert_(b1 is b6) - - # Testing PHI / value aliasing - self.assert_(f1.args[0] is v2) - -tests.append(TestObjCache) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_opaque.py b/llvm/tests/test_opaque.py deleted file mode 100644 index 7bce43e..0000000 --- a/llvm/tests/test_opaque.py +++ /dev/null @@ -1,38 +0,0 @@ -import unittest -import llvm -from llvm.core import Type -from .support import TestCase, tests - -class TestOpaque(TestCase): - - def test_opaque(self): - # Create an opaque type - ts = Type.opaque('mystruct') - self.assertTrue('type opaque' in str(ts)) - self.assertTrue(ts.is_opaque) - self.assertTrue(ts.is_identified) - self.assertFalse(ts.is_literal) - #print(ts) - - # Create a recursive type - ts.set_body([Type.int(), Type.pointer(ts)]) - - self.assertEqual(ts.elements[0], Type.int()) - self.assertEqual(ts.elements[1], Type.pointer(ts)) - self.assertEqual(ts.elements[1].pointee, ts) - self.assertFalse(ts.is_opaque) # is not longer a opaque type - #print(ts) - - with self.assertRaises(llvm.LLVMException): - # Cannot redefine - ts.set_body([]) - - def test_opaque_with_no_name(self): - with self.assertRaises(llvm.LLVMException): - Type.opaque('') - -tests.append(TestOpaque) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_operands.py b/llvm/tests/test_operands.py deleted file mode 100644 index ef68b9e..0000000 --- a/llvm/tests/test_operands.py +++ /dev/null @@ -1,66 +0,0 @@ -import unittest -try: - from StringIO import StringIO -except ImportError: - from io import StringIO - -from llvm.core import Module -from .support import TestCase, tests - -class TestOperands(TestCase): - # implement a test function - test_module = """ -define i32 @prod(i32, i32) { -entry: - %2 = mul i32 %0, %1 - ret i32 %2 -} - -define i32 @test_func(i32, i32, i32) { -entry: - %tmp1 = call i32 @prod(i32 %0, i32 %1) - %tmp2 = add i32 %tmp1, %2 - %tmp3 = add i32 %tmp2, 1 - %tmp4 = add i32 %tmp3, -1 - %tmp5 = add i64 -81985529216486895, 12297829382473034410 - ret i32 %tmp4 -} -""" - def test_operands(self): - m = Module.from_assembly(StringIO(self.test_module)) - - test_func = m.get_function_named("test_func") - prod = m.get_function_named("prod") - - # test operands - i1 = test_func.basic_blocks[0].instructions[0] - i2 = test_func.basic_blocks[0].instructions[1] - i3 = test_func.basic_blocks[0].instructions[2] - i4 = test_func.basic_blocks[0].instructions[3] - i5 = test_func.basic_blocks[0].instructions[4] - - self.assertEqual(i1.operand_count, 3) - self.assertEqual(i2.operand_count, 2) - - self.assertEqual(i3.operands[1].z_ext_value, 1) - self.assertEqual(i3.operands[1].s_ext_value, 1) - self.assertEqual(i4.operands[1].z_ext_value, 0xffffffff) - self.assertEqual(i4.operands[1].s_ext_value, -1) - self.assertEqual(i5.operands[0].s_ext_value, -81985529216486895) - self.assertEqual(i5.operands[1].z_ext_value, 12297829382473034410) - - self.assert_(i1.operands[-1] is prod) - self.assert_(i1.operands[0] is test_func.args[0]) - self.assert_(i1.operands[1] is test_func.args[1]) - self.assert_(i2.operands[0] is i1) - self.assert_(i2.operands[1] is test_func.args[2]) - self.assertEqual(len(i1.operands), 3) - self.assertEqual(len(i2.operands), 2) - - self.assert_(i1.called_function is prod) - -tests.append(TestOperands) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_passes.py b/llvm/tests/test_passes.py deleted file mode 100644 index f4b957e..0000000 --- a/llvm/tests/test_passes.py +++ /dev/null @@ -1,143 +0,0 @@ -import unittest -try: - from StringIO import StringIO -except ImportError: - from io import StringIO -import llvm -from llvm.core import Module -import llvm.passes as lp -import llvm.ee as le -from .support import TestCase, tests - - -class TestPasses(TestCase): - # Create a module. - asm = """ - -define i32 @test() nounwind { - ret i32 42 -} - -define i32 @test1() nounwind { -entry: - %tmp = alloca i32 - store i32 42, i32* %tmp, align 4 - %tmp1 = load i32* %tmp, align 4 - %tmp2 = call i32 @test() - %tmp3 = load i32* %tmp, align 4 - %tmp4 = load i32* %tmp, align 4 - ret i32 %tmp1 -} - -define i32 @test2() nounwind { -entry: - %tmp = call i32 @test() - ret i32 %tmp -} -""" - def test_passes(self): - m = Module.from_assembly(StringIO(self.asm)) - - fn_test1 = m.get_function_named('test1') - fn_test2 = m.get_function_named('test2') - - original_test1 = str(fn_test1) - original_test2 = str(fn_test2) - - # Let's run a module-level inlining pass. First, create a pass manager. - pm = lp.PassManager.new() - - # Add the target data as the first "pass". This is mandatory. - pm.add(le.TargetData.new('')) - - # Add the inlining pass. - pm.add(lp.PASS_INLINE) - - # Run it! - pm.run(m) - - # Done with the pass manager. - del pm - - # Make sure test2 is inlined - self.assertNotEqual(str(fn_test2).strip(), original_test2.strip()) - - bb_entry = fn_test2.basic_blocks[0] - - self.assertEqual(len(bb_entry.instructions), 1) - self.assertEqual(bb_entry.instructions[0].opcode_name, 'ret') - - # Let's run a DCE pass on the the function 'test1' now. First create a - # function pass manager. - fpm = lp.FunctionPassManager.new(m) - - # Add the target data as first "pass". This is mandatory. - fpm.add(le.TargetData.new('')) - - # Add a DCE pass - fpm.add(lp.PASS_ADCE) - - # Run the pass on the function 'test1' - fpm.run(m.get_function_named('test1')) - - # Make sure test1 is modified - self.assertNotEqual(str(fn_test1).strip(), original_test1.strip()) - - def test_passes_with_pmb(self): - m = Module.from_assembly(StringIO(self.asm)) - - fn_test1 = m.get_function_named('test1') - fn_test2 = m.get_function_named('test2') - - original_test1 = str(fn_test1) - original_test2 = str(fn_test2) - - # Try out the PassManagerBuilder - - pmb = lp.PassManagerBuilder.new() - - self.assertEqual(pmb.opt_level, 2) # ensure default is level 2 - pmb.opt_level = 3 - self.assertEqual(pmb.opt_level, 3) # make sure it works - - self.assertEqual(pmb.size_level, 0) # ensure default is level 0 - pmb.size_level = 2 - self.assertEqual(pmb.size_level, 2) # make sure it works - - self.assertFalse(pmb.vectorize) # ensure default is False - pmb.vectorize = True - self.assertTrue(pmb.vectorize) # make sure it works - - # make sure the default is False - self.assertFalse(pmb.disable_unit_at_a_time) - self.assertFalse(pmb.disable_unroll_loops) - if llvm.version <= (3, 3): - self.assertFalse(pmb.disable_simplify_lib_calls) - - pmb.disable_unit_at_a_time = True - self.assertTrue(pmb.disable_unit_at_a_time) - - # Do function pass - fpm = lp.FunctionPassManager.new(m) - pmb.populate(fpm) - fpm.run(fn_test1) - - # Make sure test1 has changed - self.assertNotEqual(str(fn_test1).strip(), original_test1.strip()) - - # Do module pass - pm = lp.PassManager.new() - pmb.populate(pm) - pm.run(m) - - # Make sure test2 has changed - self.assertNotEqual(str(fn_test2).strip(), original_test2.strip()) - - def test_dump_passes(self): - self.assertTrue(len(lp.PASSES)>0, msg="Cannot have no passes") - -tests.append(TestPasses) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_struct.py b/llvm/tests/test_struct.py deleted file mode 100644 index 8d61111..0000000 --- a/llvm/tests/test_struct.py +++ /dev/null @@ -1,28 +0,0 @@ -import unittest -from llvm.core import Type, Module, Builder, Constant -from .support import TestCase, tests - -class TestStruct(TestCase): - def test_struct_identical(self): - ta = Type.struct([Type.int(32), Type.float()], name='ta') - tb = Type.struct([Type.int(32), Type.float()]) - self.assertTrue(ta.is_layout_identical(tb)) - - def test_struct_extract_value_2d(self): - ta = Type.struct([Type.int(32), Type.float()]) - tb = Type.struct([ta, Type.float()]) - m = Module.new('') - f = m.add_function(Type.function(Type.void(), []), "foo") - b = Builder.new(f.append_basic_block('')) - v = Constant.undef(tb) - ins = b.insert_value(v, Constant.real(Type.float(), 1.234), [0, 1]) - ext = b.extract_value(ins, [0, 1]) - b.ret_void() - m.verify() - self.assertEqual(str(ext), 'float 0x3FF3BE76C0000000') - -tests.append(TestStruct) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_struct_args.py b/llvm/tests/test_struct_args.py deleted file mode 100644 index 5e48ea8..0000000 --- a/llvm/tests/test_struct_args.py +++ /dev/null @@ -1,685 +0,0 @@ -from __future__ import print_function -from . import tests -import sys -import unittest -from ctypes import Structure, c_float, c_double, c_uint8, CFUNCTYPE -from llvm import core as lc -from llvm import ee as le - -from .support import (skip_if_win32, skip_if_not_win32, skip_if_not_32bits, - skip_if_not_64bits, skip_if_not_intel_cpu, TestCase) - -class TwoDoubleOneByte(Structure): - _fields_ = ('x', c_double), ('y', c_double), ('z', c_uint8) - - def __repr__(self): - return '' % (self.x, self.y, self.z) - -class TwoDouble(Structure): - _fields_ = ('x', c_double), ('y', c_double) - - def __repr__(self): - return '' % (self.x, self.y) - -class TwoFloat(Structure): - _fields_ = ('x', c_float), ('y', c_float) - - def __repr__(self): - return '' % (self.x, self.y) - -class OneByte(Structure): - _fields_ = [('x', c_uint8)] - - def __repr__(self): - return '' % (self.x,) - -@skip_if_not_intel_cpu -@skip_if_win32 -class TestStructSystemVABI(TestCase): - ''' - Non microsoft convention - ''' - - #---------------------------------------------------------------------- - # 64 bits - - @skip_if_not_64bits - def test_bigger_than_two_words_64(self): - m = lc.Module.new('test_struct_arg') - - double_type = lc.Type.double() - uint8_type = lc.Type.int(8) - struct_type = lc.Type.struct([double_type, double_type, uint8_type]) - struct_ptr_type = lc.Type.pointer(struct_type) - func_type = lc.Type.function(lc.Type.void(), - [struct_ptr_type, struct_ptr_type]) - func = m.add_function(func_type, name='foo') - - # return value pointer - func.args[0].add_attribute(lc.ATTR_STRUCT_RET) - - # pass structure by value - func.args[1].add_attribute(lc.ATTR_BY_VAL) - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = builder.load(func.args[1]) - e1, e2, e3 = [builder.extract_value(arg, i) for i in range(3)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - ret = builder.insert_value(ret, e3, 2) - builder.store(ret, func.args[0]) - builder.ret_void() - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoDoubleOneByte, TwoDoubleOneByte) - cfunc = cfunctype(ptr) - - arg = TwoDoubleOneByte(x=1.321321, y=6.54352, z=128) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - self.assertEqual(arg.z, ret.z) - - @skip_if_not_64bits - def test_just_two_words_64(self): - m = lc.Module.new('test_struct_arg') - - double_type = lc.Type.double() - struct_type = lc.Type.struct([double_type, double_type]) - func_type = lc.Type.function(struct_type, [struct_type]) - func = m.add_function(func_type, name='foo') - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = func.args[0] - e1, e2 = [builder.extract_value(arg, i) for i in range(2)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - builder.ret(ret) - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoDouble, TwoDouble) - cfunc = cfunctype(ptr) - - arg = TwoDouble(x=1.321321, y=6.54352) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - - @skip_if_not_64bits - def test_two_halfwords(self): - '''Arguments smaller or equal to a word is packed into a word. - - Passing as struct { float, float } occupies two XMM registers instead - of one. - The output must be in XMM. - ''' - m = lc.Module.new('test_struct_arg') - - float_type = lc.Type.float() - struct_type = lc.Type.vector(float_type, 2) - func_type = lc.Type.function(struct_type, [struct_type]) - func = m.add_function(func_type, name='foo') - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = func.args[0] - constint = lambda x: lc.Constant.int(lc.Type.int(), x) - e1, e2 = [builder.extract_element(arg, constint(i)) - for i in range(2)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_element(lc.Constant.undef(struct_type), se1, - constint(0)) - ret = builder.insert_element(ret, se2, constint(1)) - builder.ret(ret) - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoFloat, TwoFloat) - cfunc = cfunctype(ptr) - - arg = TwoFloat(x=1.321321, y=6.54352) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - - #---------------------------------------------------------------------- - # 32 bits - - @skip_if_not_32bits - def test_structure_abi_32_1(self): - '''x86 is simple. Always pass structure as memory. - ''' - m = lc.Module.new('test_struct_arg') - - double_type = lc.Type.double() - uint8_type = lc.Type.int(8) - struct_type = lc.Type.struct([double_type, double_type, uint8_type]) - struct_ptr_type = lc.Type.pointer(struct_type) - func_type = lc.Type.function(lc.Type.void(), - [struct_ptr_type, struct_ptr_type]) - func = m.add_function(func_type, name='foo') - - # return value pointer - func.args[0].add_attribute(lc.ATTR_STRUCT_RET) - - # pass structure by value - func.args[1].add_attribute(lc.ATTR_BY_VAL) - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = builder.load(func.args[1]) - e1, e2, e3 = [builder.extract_value(arg, i) for i in range(3)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - ret = builder.insert_value(ret, e3, 2) - builder.store(ret, func.args[0]) - builder.ret_void() - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoDoubleOneByte, TwoDoubleOneByte) - cfunc = cfunctype(ptr) - - arg = TwoDoubleOneByte(x=1.321321, y=6.54352, z=128) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - self.assertEqual(arg.z, ret.z) - - - @skip_if_not_32bits - def test_structure_abi_32_2(self): - '''x86 is simple. Always pass structure as memory. - ''' - m = lc.Module.new('test_struct_arg') - - float_type = lc.Type.float() - struct_type = lc.Type.struct([float_type, float_type]) - struct_ptr_type = lc.Type.pointer(struct_type) - func_type = lc.Type.function(lc.Type.void(), - [struct_ptr_type, struct_ptr_type]) - func = m.add_function(func_type, name='foo') - - # return value pointer - func.args[0].add_attribute(lc.ATTR_STRUCT_RET) - - # pass structure by value - func.args[1].add_attribute(lc.ATTR_BY_VAL) - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = builder.load(func.args[1]) - e1, e2 = [builder.extract_value(arg, i) for i in range(2)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - builder.store(ret, func.args[0]) - builder.ret_void() - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoFloat, TwoFloat) - cfunc = cfunctype(ptr) - - arg = TwoFloat(x=1.321321, y=6.54352) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - - - @skip_if_not_32bits - def test_structure_abi_32_3(self): - '''x86 is simple. Always pass structure as memory. - ''' - m = lc.Module.new('test_struct_arg') - - uint8_type = lc.Type.int(8) - struct_type = lc.Type.struct([uint8_type]) - struct_ptr_type = lc.Type.pointer(struct_type) - func_type = lc.Type.function(lc.Type.void(), - [struct_ptr_type, struct_ptr_type]) - func = m.add_function(func_type, name='foo') - - # return value pointer - func.args[0].add_attribute(lc.ATTR_STRUCT_RET) - - # pass structure by value - func.args[1].add_attribute(lc.ATTR_BY_VAL) - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = builder.load(func.args[1]) - e1 = builder.extract_value(arg, 0) - se1 = builder.mul(e1, e1) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - builder.store(ret, func.args[0]) - builder.ret_void() - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(OneByte, OneByte) - cfunc = cfunctype(ptr) - - arg = OneByte(x=8) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertEqual(arg.x * arg.x, ret.x) - -tests.append(TestStructSystemVABI) - -@skip_if_not_intel_cpu -@skip_if_not_win32 -class TestStructMicrosoftABI(TestCase): - ''' - Microsoft convention - ''' - - #---------------------------------------------------------------------- - # 64 bits - - @skip_if_not_64bits - def test_bigger_than_two_words_64(self): - m = lc.Module.new('test_struct_arg') - - double_type = lc.Type.double() - uint8_type = lc.Type.int(8) - struct_type = lc.Type.struct([double_type, double_type, uint8_type]) - struct_ptr_type = lc.Type.pointer(struct_type) - func_type = lc.Type.function(lc.Type.void(), - [struct_ptr_type, struct_ptr_type]) - func = m.add_function(func_type, name='foo') - - # return value pointer - func.args[0].add_attribute(lc.ATTR_STRUCT_RET) - - # pass structure by value - func.args[1].add_attribute(lc.ATTR_BY_VAL) - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = builder.load(func.args[1]) - e1, e2, e3 = [builder.extract_value(arg, i) for i in range(3)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - ret = builder.insert_value(ret, e3, 2) - builder.store(ret, func.args[0]) - builder.ret_void() - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoDoubleOneByte, TwoDoubleOneByte) - cfunc = cfunctype(ptr) - - arg = TwoDoubleOneByte(x=1.321321, y=6.54352, z=128) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - self.assertEqual(arg.z, ret.z) - - @skip_if_not_64bits - def test_just_two_words_64(self): - m = lc.Module.new('test_struct_arg') - - double_type = lc.Type.double() - struct_type = lc.Type.struct([double_type, double_type]) - struct_ptr_type = lc.Type.pointer(struct_type) - func_type = lc.Type.function(lc.Type.void(), - [struct_ptr_type, struct_ptr_type]) - func = m.add_function(func_type, name='foo') - - # return value pointer - func.args[0].add_attribute(lc.ATTR_STRUCT_RET) - - # pass structure by value - func.args[1].add_attribute(lc.ATTR_BY_VAL) - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = builder.load(func.args[1]) - e1, e2 = [builder.extract_value(arg, i) for i in range(2)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - builder.store(ret, func.args[0]) - builder.ret_void() - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoDouble, TwoDouble) - cfunc = cfunctype(ptr) - - arg = TwoDouble(x=1.321321, y=6.54352) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - - @skip_if_not_64bits - def test_two_halfwords(self): - '''Arguments smaller or equal to a word is packed into a word. - - Floats structure are not passed on the XMM. - Treat it as a i64. - ''' - m = lc.Module.new('test_struct_arg') - - float_type = lc.Type.float() - struct_type = lc.Type.struct([float_type, float_type]) - abi_type = lc.Type.int(64) - - func_type = lc.Type.function(abi_type, [abi_type]) - func = m.add_function(func_type, name='foo') - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = func.args[0] - - struct_ptr = builder.alloca(struct_type) - struct_int_ptr = builder.bitcast(struct_ptr, lc.Type.pointer(abi_type)) - builder.store(arg, struct_int_ptr) - - arg = builder.load(struct_ptr) - - e1, e2 = [builder.extract_value(arg, i) for i in range(2)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - - builder.store(ret, struct_ptr) - ret = builder.load(struct_int_ptr) - - builder.ret(ret) - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoFloat, TwoFloat) - cfunc = cfunctype(ptr) - - arg = TwoFloat(x=1.321321, y=6.54352) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - - #---------------------------------------------------------------------- - # 32 bits - - @skip_if_not_32bits - def test_one_word_register(self): - '''Argument is passed by memory. - Return value is passed by register. - ''' - m = lc.Module.new('test_struct_arg') - - uint8_type = lc.Type.int(8) - struct_type = lc.Type.struct([uint8_type]) - struct_ptr_type = lc.Type.pointer(struct_type) - func_type = lc.Type.function(struct_type, [struct_ptr_type]) - func = m.add_function(func_type, name='foo') - - # pass structure by value - func.args[0].add_attribute(lc.ATTR_BY_VAL) - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = builder.load(func.args[0]) - e1 = builder.extract_value(arg, 0) - se1 = builder.mul(e1, e1) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - - builder.ret(ret) - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(OneByte, OneByte) - cfunc = cfunctype(ptr) - - arg = OneByte(x=8) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertEqual(arg.x * arg.x, ret.x) - - - @skip_if_not_32bits - def test_two_floats(self): - '''Argument is passed by register. - Return in 2 registers - ''' - m = lc.Module.new('test_struct_arg') - - float_type = lc.Type.float() - struct_type = lc.Type.struct([float_type, float_type]) - - abi_type = lc.Type.int(64) - func_type = lc.Type.function(abi_type, [struct_type]) - func = m.add_function(func_type, name='foo') - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - out_ptr = builder.alloca(struct_type) - - arg = func.args[0] - e1, e2 = [builder.extract_value(arg, i) for i in range(2)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - builder.store(ret, out_ptr) - - out_int_ptr = builder.bitcast(out_ptr, lc.Type.pointer(abi_type)) - - builder.ret(builder.load(out_int_ptr)) - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoFloat, TwoFloat) - cfunc = cfunctype(ptr) - - arg = TwoFloat(x=1.321321, y=6.54352) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - - @skip_if_not_32bits - def test_bigger_than_two_words(self): - '''Pass in memory. - ''' - m = lc.Module.new('test_struct_arg') - - double_type = lc.Type.double() - uint8_type = lc.Type.int(8) - struct_type = lc.Type.struct([double_type, double_type, uint8_type]) - struct_ptr_type = lc.Type.pointer(struct_type) - func_type = lc.Type.function(lc.Type.void(), - [struct_ptr_type, struct_ptr_type]) - func = m.add_function(func_type, name='foo') - - # return value pointer - func.args[0].add_attribute(lc.ATTR_STRUCT_RET) - - # pass structure by value - func.args[1].add_attribute(lc.ATTR_BY_VAL) - - # define function body - builder = lc.Builder.new(func.append_basic_block('')) - - arg = builder.load(func.args[1]) - e1, e2, e3 = [builder.extract_value(arg, i) for i in range(3)] - se1 = builder.fmul(e1, e2) - se2 = builder.fdiv(e1, e2) - ret = builder.insert_value(lc.Constant.undef(struct_type), se1, 0) - ret = builder.insert_value(ret, se2, 1) - ret = builder.insert_value(ret, e3, 2) - builder.store(ret, func.args[0]) - builder.ret_void() - - del builder - - # verify - m.verify() - - print(m) - # use with ctypes - engine = le.EngineBuilder.new(m).create() - ptr = engine.get_pointer_to_function(func) - - cfunctype = CFUNCTYPE(TwoDoubleOneByte, TwoDoubleOneByte) - cfunc = cfunctype(ptr) - - arg = TwoDoubleOneByte(x=1.321321, y=6.54352, z=128) - ret = cfunc(arg) - print(arg) - print(ret) - - self.assertClose(arg.x * arg.y, ret.x) - self.assertClose(arg.x / arg.y, ret.y) - self.assertEqual(arg.z, ret.z) - -tests.append(TestStructMicrosoftABI) - -if __name__ == "__main__": - unittest.main() diff --git a/llvm/tests/test_switch.py b/llvm/tests/test_switch.py deleted file mode 100644 index 12a4fbc..0000000 --- a/llvm/tests/test_switch.py +++ /dev/null @@ -1,36 +0,0 @@ -import unittest -from llvm.core import (Module, Type, Builder, Constant) - -from .support import TestCase, tests - -class TestSwitch(TestCase): - def test_arg_attr(self): - m = Module.new('oifjda') - fnty = Type.function(Type.void(), [Type.int()]) - func = m.add_function(fnty, 'foo') - bb = func.append_basic_block('') - bbdef = func.append_basic_block('') - bbsw1 = func.append_basic_block('') - bbsw2 = func.append_basic_block('') - bldr = Builder.new(bb) - - swt = bldr.switch(func.args[0], bbdef, n=2) - swt.add_case(Constant.int(Type.int(), 0), bbsw1) - swt.add_case(Constant.int(Type.int(), 1), bbsw2) - - bldr.position_at_end(bbsw1) - bldr.ret_void() - - bldr.position_at_end(bbsw2) - bldr.ret_void() - - bldr.position_at_end(bbdef) - bldr.ret_void() - - func.verify() - -tests.append(TestSwitch) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_target_machines.py b/llvm/tests/test_target_machines.py deleted file mode 100644 index 2bbe76e..0000000 --- a/llvm/tests/test_target_machines.py +++ /dev/null @@ -1,62 +0,0 @@ -import unittest -import llvm.core as lc -import llvm.ee as le -from llvm.core import Type, Builder -from .support import TestCase, tests, skip_if - -# Check PTX backend -if le.initialize_target('PTX', noraise=True): - PTX_ARCH = 'ptx64' -elif le.initialize_target('NVPTX', noraise=True): - PTX_ARCH = 'nvptx64' -else: - PTX_ARCH = None - -class TestTargetMachines(TestCase): - '''Exercise target machines - - Require PTX backend - ''' - def test_native(self): - m, _ = self._build_module() - tm = le.EngineBuilder.new(m).select_target() - - self.assertTrue(tm.target_name) - self.assertTrue(tm.target_data) - self.assertTrue(tm.target_short_description) - self.assertTrue(tm.triple) - self.assertIn('foo', tm.emit_assembly(m)) - self.assertTrue(le.get_host_cpu_name()) - - @skip_if(not PTX_ARCH, msg='LLVM is not compiled with PTX enabled') - def test_ptx(self): - arch = PTX_ARCH - print(arch) - m, func = self._build_module() - func.calling_convention = lc.CC_PTX_KERNEL # set calling conv - ptxtm = le.TargetMachine.lookup(arch=arch, cpu='sm_20') - self.assertTrue(ptxtm.triple) - self.assertTrue(ptxtm.cpu) - ptxasm = ptxtm.emit_assembly(m) - self.assertIn('foo', ptxasm) - if arch == 'nvptx64': - self.assertIn('.address_size 64', ptxasm) - self.assertIn('sm_20', ptxasm) - - def _build_module(self): - m = lc.Module.new('TestTargetMachines') - - fnty = Type.function(Type.void(), []) - func = m.add_function(fnty, name='foo') - - bldr = Builder.new(func.append_basic_block('entry')) - bldr.ret_void() - m.verify() - return m, func - - -tests.append(TestTargetMachines) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_type_hash.py b/llvm/tests/test_type_hash.py deleted file mode 100644 index 49455a1..0000000 --- a/llvm/tests/test_type_hash.py +++ /dev/null @@ -1,30 +0,0 @@ -import unittest -from llvm.core import Type -from .support import TestCase, tests - -class TestTypeHash(TestCase): - def test_scalar_type(self): - i32a = Type.int(32) - i32b = Type.int(32) - i64a = Type.int(64) - i64b = Type.int(64) - ts = set([i32a, i32b, i64a, i64b]) - self.assertTrue(len(ts)) - self.assertTrue(i32a in ts) - self.assertTrue(i64b in ts) - - def test_struct_type(self): - ta = Type.struct([Type.int(32), Type.float()]) - tb = Type.struct([Type.int(32), Type.float()]) - tc = Type.struct([Type.int(32), Type.int(32), Type.float()]) - ts = set([ta, tb, tc]) - self.assertTrue(len(ts) == 2) - self.assertTrue(ta in ts) - self.assertTrue(tb in ts) - self.assertTrue(tc in ts) - -tests.append(TestTypeHash) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_uses.py b/llvm/tests/test_uses.py deleted file mode 100644 index 3d3bdbc..0000000 --- a/llvm/tests/test_uses.py +++ /dev/null @@ -1,43 +0,0 @@ -import unittest -from llvm.core import Module, Type, Builder, Constant - -from .support import TestCase, tests - -class TestUses(TestCase): - - def test_uses(self): - m = Module.new('a') - t = Type.int() - ft = Type.function(t, [t, t, t]) - f = m.add_function(ft, "func") - b = f.append_basic_block('entry') - bld = Builder.new(b) - tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1") - tmp2 = bld.add(tmp1, f.args[1], "tmp2") - tmp3 = bld.add(tmp1, f.args[2], "tmp3") - bld.ret(tmp3) - - # Testing use count - self.assertEqual(f.args[0].use_count, 1) - self.assertEqual(f.args[1].use_count, 1) - self.assertEqual(f.args[2].use_count, 1) - self.assertEqual(tmp1.use_count, 2) - self.assertEqual(tmp2.use_count, 0) - self.assertEqual(tmp3.use_count, 1) - - # Testing uses - self.assert_(f.args[0].uses[0] is tmp1) - self.assertEqual(len(f.args[0].uses), 1) - self.assert_(f.args[1].uses[0] is tmp2) - self.assertEqual(len(f.args[1].uses), 1) - self.assert_(f.args[2].uses[0] is tmp3) - self.assertEqual(len(f.args[2].uses), 1) - self.assertEqual(len(tmp1.uses), 2) - self.assertEqual(len(tmp2.uses), 0) - self.assertEqual(len(tmp3.uses), 1) - -tests.append(TestUses) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/tests/test_volatile.py b/llvm/tests/test_volatile.py deleted file mode 100644 index dace8e8..0000000 --- a/llvm/tests/test_volatile.py +++ /dev/null @@ -1,59 +0,0 @@ -import unittest -from llvm.core import Module, Type, Builder -from .support import TestCase, tests - -class TestVolatile(TestCase): - - def test_volatile(self): - mod = Module.new('mod') - functype = Type.function(Type.void(), []) - func = mod.add_function(functype, name='foo') - bb = func.append_basic_block('entry') - bldr = Builder.new(bb) - ptr = bldr.alloca(Type.int()) - - # test load inst - val = bldr.load(ptr) - self.assertFalse(val.is_volatile, "default must be non-volatile") - val.set_volatile(True) - self.assertTrue(val.is_volatile, "fail to set volatile") - val.set_volatile(False) - self.assertFalse(val.is_volatile, "fail to unset volatile") - - # test store inst - store_inst = bldr.store(val, ptr) - self.assertFalse(store_inst.is_volatile, "default must be non-volatile") - store_inst.set_volatile(True) - self.assertTrue(store_inst.is_volatile, "fail to set volatile") - store_inst.set_volatile(False) - self.assertFalse(store_inst.is_volatile, "fail to unset volatile") - - def test_volatile_another(self): - mod = Module.new('mod') - functype = Type.function(Type.void(), []) - func = mod.add_function(functype, name='foo') - bb = func.append_basic_block('entry') - bldr = Builder.new(bb) - ptr = bldr.alloca(Type.int()) - - # test load inst - val = bldr.load(ptr, volatile=True) - self.assertTrue(val.is_volatile, "volatile kwarg does not work") - val.set_volatile(False) - self.assertFalse(val.is_volatile, "fail to unset volatile") - val.set_volatile(True) - self.assertTrue(val.is_volatile, "fail to set volatile") - - # test store inst - store_inst = bldr.store(val, ptr, volatile=True) - self.assertTrue(store_inst.is_volatile, "volatile kwarg does not work") - store_inst.set_volatile(False) - self.assertFalse(store_inst.is_volatile, "fail to unset volatile") - store_inst.set_volatile(True) - self.assertTrue(store_inst.is_volatile, "fail to set volatile") - -tests.append(TestVolatile) - -if __name__ == '__main__': - unittest.main() - diff --git a/llvm/utils/__init__.py b/llvm/utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/llvm/utils/check_intrinsics.py b/llvm/utils/check_intrinsics.py deleted file mode 100644 index 702dae3..0000000 --- a/llvm/utils/check_intrinsics.py +++ /dev/null @@ -1,181 +0,0 @@ -from __future__ import print_function, absolute_import -import sys -from llvm.core import Type, Function, Builder, Module -import llvm.core as lc -import llvm.ee as le -import multiprocessing -from ctypes import * - -INTRINSICS = {} - -CTYPES_MAP = { - Type.int(): c_int32, - Type.int(64): c_int64, - Type.float(): c_float, - Type.double(): c_double, -} - - -def register(name, retty, *args): - def wrap(fn): - INTRINSICS[name] = (retty, args), fn - return fn - return wrap - - -def intr_impl(intrcode, *types): - def impl(module, builder, args): - intr = Function.intrinsic(module, intrcode, types) - r = builder.call(intr, args) - return r - return impl - - -register("llvm.powi.f64", Type.double(), Type.double(), Type.int())\ - (intr_impl(lc.INTR_POWI, Type.double())) - -register("llvm.powi.f32", Type.float(), Type.float(), Type.int())\ - (intr_impl(lc.INTR_POWI, Type.float())) - -register("llvm.pow.f64", Type.double(), Type.double(), Type.double())\ - (intr_impl(lc.INTR_POW, Type.double())) - -register("llvm.pow.f32", Type.float(), Type.float(), Type.float())\ - (intr_impl(lc.INTR_POW, Type.float())) - -register("llvm.sin.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_SIN, Type.double())) - -register("llvm.sin.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_SIN, Type.float())) - -register("llvm.cos.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_COS, Type.double())) - -register("llvm.cos.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_COS, Type.float())) - -register("llvm.log.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_LOG, Type.double())) - -register("llvm.log.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_LOG, Type.float())) - -register("llvm.log2.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_LOG2, Type.double())) - -register("llvm.log2.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_LOG2, Type.float())) - -register("llvm.log10.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_LOG10, Type.double())) - -register("llvm.log10.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_LOG10, Type.float())) - -register("llvm.sqrt.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_SQRT, Type.double())) - -register("llvm.sqrt.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_SQRT, Type.float())) - -register("llvm.exp.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_EXP, Type.double())) - -register("llvm.exp.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_EXP, Type.float())) - -register("llvm.exp2.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_EXP2, Type.double())) - -register("llvm.exp2.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_EXP2, Type.float())) - -register("llvm.fabs.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_FABS, Type.double())) - -register("llvm.fabs.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_FABS, Type.float())) - -register("llvm.floor.f64", Type.double(), Type.double())\ - (intr_impl(lc.INTR_FLOOR, Type.double())) - -register("llvm.floor.f32", Type.float(), Type.float())\ - (intr_impl(lc.INTR_FLOOR, Type.float())) - - -def build_test(name): - (retty, args), impl = INTRINSICS[name] - module = Module.new("test.%s" % name) - fn = module.add_function(Type.function(retty, args), name="test_%s" % name) - builder = Builder.new(fn.append_basic_block("")) - retval = impl(module, builder, fn.args) - builder.ret(retval) - fn.verify() - module.verify() - return module, fn - - -def run_test(name): - module, fn = build_test(name) - eb = le.EngineBuilder.new(module).mcjit(True) - engine = eb.create() - ptr = engine.get_pointer_to_function(fn) - - argtys = fn.type.pointee.args - retty = fn.type.pointee.return_type - cargtys = [CTYPES_MAP[a] for a in argtys] - cretty = CTYPES_MAP[retty] - cfunc = CFUNCTYPE(cretty, *cargtys)(ptr) - args = [1] * len(cargtys) - cfunc(*args) - - -def spawner(name): - print("Testing %s" % name) - proc = multiprocessing.Process(target=run_test, args=(name,)) - - print('-' * 80) - proc.start() - proc.join() - - if proc.exitcode != 0: - print("FAILED") - ok = False - else: - print("PASSED") - ok = True - print('=' * 80) - print() - - return ok - -USAGE = """ -Args: [name] - -name: intrinsic name to test - -If no name is given, test all intrinsics. - -""" - - -def main(argv=()): - if len(argv) == 1: - intrname = argv[1] - spawner(intrname) - elif not argv: - failed = [] - for name in sorted(INTRINSICS): - if not spawner(name): - failed.append(name) - - print("Summary:") - for name in failed: - print("%s failed" % name) - else: - print(USAGE) - - -if __name__ == '__main__': - main(argv=sys.argv[1:]) diff --git a/llvm/workaround/avx_support.py b/llvm/workaround/avx_support.py index 4c65dc5..0b1c2da 100644 --- a/llvm/workaround/avx_support.py +++ b/llvm/workaround/avx_support.py @@ -12,11 +12,7 @@ http://software.intel.com/sites/default/files/m/a/b/3/4/d/41604-319433-012a.pdf """ -import sys -import os -import subprocess -import contextlib - +import sys, os, subprocess def detect_avx_support(option='detect'): '''Detect AVX support''' @@ -40,25 +36,13 @@ def detect_unix_like(): except IOError: return False - with contextlib.closing(info): - for line in info: - if line.lstrip().startswith('flags'): - features = line.split() - if 'avx' in features and 'xsave' in features: - # enable AVX if flags contain AVX - return True - return False - - -@contextlib.contextmanager -def _close_popen(popen): - if sys.version_info[0] >= 3: - with popen: - yield - else: - yield - popen.stdout.close() - + for line in info: + if line.lstrip().startswith('flags'): + features = line.split() + if 'avx' in features and 'xsave' in features: + # enable AVX if flags contain AVX + return True + return False def detect_osx_like(): try: @@ -66,11 +50,9 @@ def detect_osx_like(): stdout=subprocess.PIPE) except OSError: return False - - with _close_popen(info): - features = info.stdout.read().decode('UTF8') - features = features.split() - return 'AVX1.0' in features and 'OSXSAVE' in features and 'XSAVE' in features + features = info.stdout.read().decode('UTF8') + features = features.split() + return 'AVX1.0' in features and 'OSXSAVE' in features and 'XSAVE' in features if __name__ == '__main__': diff --git a/llvm_array/array.py b/llvm_array/array.py index de194a6..3cac244 100644 --- a/llvm_array/array.py +++ b/llvm_array/array.py @@ -1,18 +1,18 @@ # This should be moved to llvmpy -# +# # There are different array kinds parameterized by eltype and nd -# -# Contiguous or Fortran +# +# Contiguous or Fortran # struct { # eltype *data; -# intp shape[nd]; +# intp shape[nd]; # } contiguous_array(eltype, nd) # # struct { # eltype *data; # diminfo shape[nd]; # } strided_array(eltype, nd) -# +# # struct { # eltype *data; # intp shape[nd]; @@ -40,7 +40,7 @@ # int32 nd; # diminfo shape[nd]; # } strided_array_nd(eltype) -# +# # # Backward compatible but deprecated: # struct { @@ -50,25 +50,25 @@ # intp stride[nd]; # } strided_soa_array_nd(eltype) # -# +# # The most general (where the kind of array is stored as well as number # of dimensions) # Rarely needed. -# +# # struct { # eltype *data; # int16 nd; # int16 dimkind; # ??? # } array_nd(eltype) -# +# # where ??? is run-time interpreted based on the dimkind to either: # intp shape[nd]; for dimkind = C_CONTIGUOUS or F_CONTIGUOUS # # diminfo shape[nd]; for dimkind = STRIDED # # intp shape[ind]; -# intp strides[ind]; dimkind = STRIDED_SOA +# intp strides[ind]; dimkind = STRIDED_SOA # import llvm.core as lc @@ -95,7 +95,7 @@ STRIDED_DK = STRIDED + HAS_DIMKIND STRIDED_SOA_DK = STRIDED_SOA + HAS_DIMKIND array_kinds = (C_CONTIGUOUS, F_CONTIGUOUS, STRIDED, STRIDED_SOA, - C_CONTIGUOUS_ND, F_CONTIGUOUS_ND, STRIDED_ND, STRIDED_SOA_DK, + C_CONTIGUOUS_ND, F_CONTIGUOUS_ND, STRIDED_ND, STRIDED_SOA_DK, C_CONTIGUOUS_DK, F_CONTIGUOUS_DK, STRIDED_DK, STRIDED_SOA_DK) _invmap = {} @@ -105,7 +105,7 @@ def kind_to_str(kind): if not _invmap: for key, value in globals().items(): if isinstance(value, int) and value in array_kinds: - _invmap[value] = key + _invmap[value] = key return _invmap[kind] def str_to_kind(str): @@ -157,7 +157,7 @@ def array_type(nd, kind, el_type=char_type): terms.append(Type.array(intp_type, nd)) # shape elif base == STRIDED: terms.append(Type.array(diminfo_type, nd)) # diminfo - elif base == STRIDED_SOA: + elif base == STRIDED_SOA: terms.extend([Type.array(intp_type, nd), # shape Type.array(intp_type, nd)]) # strides @@ -184,8 +184,8 @@ def _raw_check_array(arrtyp): a0 = arrtyp.elements[0] a1 = arrtyp.elements[1] if not isinstance(a0, lc.PointerType) or \ - not (isinstance(a1, lc.ArrayType) or - (a1 == int32_type) or (a1 == int16_type)): + not (isinstance(a1, lc.ArrayType) or + (a1 == int32_type) or (a1 == int16_type)): return None data_type = a0.pointee @@ -214,7 +214,7 @@ def _raw_check_array(arrtyp): c_contiguous = C_CONTIGUOUS_DK f_contiguous = F_CONTIGUOUS_DK else: - num = 1 + num = 1 strided = STRIDED strided_soa = STRIDED_SOA c_contiguous = C_CONTIGUOUS @@ -254,4 +254,4 @@ def test(): assert check_array(arr) == (STRIDED_SOA, 3, char_type) if __name__ == '__main__': - test() + test() \ No newline at end of file diff --git a/llvm_cbuilder/builder.py b/llvm_cbuilder/builder.py index a2c0bda..eaabd67 100644 --- a/llvm_cbuilder/builder.py +++ b/llvm_cbuilder/builder.py @@ -349,7 +349,7 @@ class CBuilder(object): elif not isinstance(count, lc.Value): count = self.constant(types.int, count).value - ptr = self.builder.alloca(ty, size=count, name=name) + ptr = self.builder.alloca_array(ty, count, name=name) return CArray(self, ptr) def ret(self, val=None): diff --git a/llvmpy/capsule.cpp b/llvmpy/capsule.cpp index 5e0279d..561b28a 100644 --- a/llvmpy/capsule.cpp +++ b/llvmpy/capsule.cpp @@ -1,95 +1,55 @@ #include -#include #include #include #include -#include -#include -#include - -static PyObject* TheAPIModule = NULL; -static PyObject* TheCapsuleModule = NULL; -static PyObject* TheCapsuleClass = NULL; -static PyObject* TheWrapperClass = NULL; -static PyObject* TheCache = NULL; -static PyObject* TheAddrDtorDict = NULL; -static PyObject* TheClassesDict = NULL; -static PyObject* TheAddrRefCt = NULL; -static PyObject* ConstantOne = NULL; -static PyObject* TheDowncastModule = NULL; static -PyObject* GetAPIModule(){ - if (NULL == TheAPIModule) - TheAPIModule = PyImport_ImportModule("llvmpy._api"); - return TheAPIModule; +PyObject* getName(PyObject* self, PyObject* args) { + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)){ + return NULL; + } + const char* name = PyCapsule_GetName(obj); + if (!name) return NULL; + + return PyString_FromString(name); } static -PyObject* GetCapsuleModule(){ - if (NULL == TheCapsuleModule) - TheCapsuleModule = PyImport_ImportModule("llvmpy.capsule"); - return TheCapsuleModule; +PyObject* getPointer(PyObject* self, PyObject* args) { + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)){ + return NULL; + } + void* pointer = PyCapsule_GetPointer(obj, PyCapsule_GetName(obj)); + if (!pointer) return NULL; + + return PyLong_FromVoidPtr(pointer); } static -PyObject* GetCapsuleClass() { - if (NULL == TheCapsuleClass) - TheCapsuleClass = PyObject_GetAttrString(GetCapsuleModule(), - "Capsule"); - return TheCapsuleClass; +PyObject* check(PyObject* self, PyObject* args) { + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)){ + return NULL; + } + if (PyCapsule_CheckExact(obj)) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } } -static -PyObject* GetWrapperClass() { - if (NULL == TheWrapperClass) - TheWrapperClass = PyObject_GetAttrString(GetCapsuleModule(), - "Wrapper"); - return TheWrapperClass; -} +// ------------------ +// PyCapsule Context +// ------------------ static -PyObject* GetCache() { - if (NULL == TheCache) - TheCache = PyObject_GetAttrString(GetCapsuleModule(), "_cache"); - return TheCache; -} - -static -PyObject* GetAddrDtorDict() { - if (NULL == TheAddrDtorDict) - TheAddrDtorDict = PyObject_GetAttrString(GetCapsuleModule(), - "_addr2dtor"); - return TheAddrDtorDict; -} - -static -PyObject* GetClassesDict() { - if (NULL == TheClassesDict) - TheClassesDict = PyObject_GetAttrString(GetCapsuleModule(), - "_pyclasses"); - return TheClassesDict; -} - -static -PyObject* GetAddrRefCt() { - if (NULL == TheAddrRefCt) - TheAddrRefCt = PyObject_GetAttrString(GetCapsuleModule(), - "_addr2refct"); - return TheAddrRefCt; -} - -static -PyObject* GetDowncastModule() { - if (NULL == TheDowncastModule) - TheDowncastModule = PyObject_GetAttrString(GetAPIModule(), - "downcast"); - return TheDowncastModule; - -} - -static -CapsuleContext* GetContext(PyObject *obj) { +CapsuleContext* getContext(PyObject* self, PyObject* args) { + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } void* context = PyCapsule_GetContext(obj); if (!context) { PyErr_SetString(PyExc_TypeError, "PyCapsule has no context."); @@ -99,8 +59,9 @@ CapsuleContext* GetContext(PyObject *obj) { } static -PyObject* GetClassName(PyObject* obj) { - CapsuleContext* context = GetContext(obj); +PyObject* getClassName(PyObject* self, PyObject* args) { + CapsuleContext* context = getContext(self, args); + //Assert(context->_magic == 0xdead); if (!context) { return NULL; } else { @@ -108,476 +69,6 @@ PyObject* GetClassName(PyObject* obj) { } } -static -PyObject* getClassName(PyObject* self, PyObject* args) { - PyObject* obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - return GetClassName(obj); -} - -static -PyObject* GetName(PyObject* obj) { - const char* name = PyCapsule_GetName(obj); - if (!name) return NULL; - return PyString_FromString(name); -} - -static -PyObject* getName(PyObject* self, PyObject* args) { - PyObject* obj; - if (!PyArg_ParseTuple(args, "O", &obj)){ - return NULL; - } - return GetName(obj); -} - -static -PyObject* GetPointer(PyObject* obj){ - void *pointer = PyCapsule_GetPointer(obj, PyCapsule_GetName(obj)); - if (!pointer) return NULL; - return PyLong_FromVoidPtr(pointer); -} - -static -PyObject* getPointer(PyObject* self, PyObject* args) { - PyObject* obj; - if (!PyArg_ParseTuple(args, "O", &obj)){ - return NULL; - } - return GetPointer(obj); -} - -static -bool Check(PyObject* obj){ - return PyCapsule_CheckExact(obj); -} - -static -PyObject* check(PyObject* self, PyObject* args) { - PyObject* obj; - if (!PyArg_ParseTuple(args, "O", &obj)){ - return NULL; - } - if (Check(obj)) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } -} - - -static PyObject* Unwrap(PyObject* obj) { - if (PyObject_IsInstance(obj, GetWrapperClass())) { - return PyObject_GetAttrString(obj, "_ptr"); - } else { - Py_INCREF(obj); - return obj; - } -} - -/* -Unwrap a Wrapper instance into the underlying PyCapsule. -If `obj` is not a Wrapper instance, returns `obj`. -*/ -static PyObject* unwrap(PyObject* self, PyObject* args) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - return Unwrap(obj); -} - -static bool HasOwnership(PyObject* obj) { - PyObject* addr = GetPointer(obj); - PyObject* name = GetName(obj); - auto_pyobject nameaddr = PyTuple_Pack(2, name, addr); - PyObject* dtor = PyDict_GetItem(GetAddrDtorDict(), *nameaddr); - if (!dtor || dtor == Py_None) { - return false; - } else { - return true; - } -} - -static PyObject* has_ownership(PyObject* self, PyObject* args) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - if (HasOwnership(obj)) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } -} - -static -void NormalizeString(std::ostream &os, const char* str) { - for(; *str; ++str){ - if (*str == ':') { - os << '_'; - if(*(str + 1) == ':') { ++str; } - } else { - os << *str; - } - } -} - -static -PyObject* WrapCore(PyObject *oldCap, bool owned) { - auto_pyobject cap = PyObject_CallFunctionObjArgs(GetCapsuleClass(), oldCap, - NULL); - auto_pyobject cls = PyObject_CallMethod(*cap, "get_class", ""); - auto_pyobject addr = GetPointer(oldCap); - auto_pyobject name = GetName(oldCap); - - // look up cached object - auto_pyobject cache_cls = PyObject_GetItem(GetCache(), *cls); - Assert(*cache_cls); - int addr_in_cache = PyMapping_HasKey(*cache_cls, *addr); - - PyObject* obj = NULL; - if (addr_in_cache) { - obj = PyObject_GetItem(*cache_cls, *addr); - } else { - if (!owned) { - auto_pyobject hasDtor = PyObject_CallMethod(*cls, "_has_dtor", ""); - if (PyObject_IsTrue(*hasDtor)) { - auto_pyobject key = PyTuple_Pack(2, *name, *addr); - auto_pyobject val = PyObject_GetAttrString(*cls, "_delete_"); - - int ok = PyDict_SetItem(GetAddrDtorDict(), *key, *val); - Assert(ok != -1); - } - } - obj = PyObject_CallMethod(*cap, "instantiate", ""); - int ok = PyObject_SetItem(*cache_cls, *addr, obj); - Assert(ok != -1); - } - - Assert(obj); - return obj; -} - -static -PyObject* Wrap(PyObject* cap, bool owned){ - if (!Check(cap)) { - if (PyList_Check(cap)) { - const int N = PyList_Size(cap); - PyObject* result = PyList_New(N); - - for (int i = 0; i < N; ++i){ - PyObject* item = PyList_GetItem(cap, i); - if (!item) - return NULL; - PyObject* out = Wrap(item, false); - if (!out) return NULL; - if (-1 == PyList_SetItem(result, i, out)) - return NULL; - } - - return result; - } else { - Py_INCREF(cap); - return cap; - } - } - - return WrapCore(cap, owned); -} - - -static -PyObject* wrap(PyObject* self, PyObject* args) { - PyObject* obj; - PyObject* owned = NULL; - if (!PyArg_ParseTuple(args, "O|O", &obj, &owned)) { - return NULL; - } - bool ownedFlag = false; - if (owned) { - ownedFlag = PyObject_IsTrue(owned); - } - return Wrap(obj, ownedFlag); -} - -static -PyObject* downcast(PyObject* self, PyObject* args) { - PyObject *obj, *cls; - if (!PyArg_ParseTuple(args, "OO", &obj, &cls)) { - return NULL; - } - - auto_pyobject objType = PyObject_Type(obj); - - if (*objType == cls) { - Py_INCREF(obj); - return obj; - } - - PyObject* apiModule = GetAPIModule(); - - auto_pyobject fromTy = PyObject_GetAttrString(obj, "_llvm_type_"); - auto_pyobject toTy = PyObject_GetAttrString(cls, "_llvm_type_"); - - std::ostringstream oss; - - auto_pyobject fromTyStr = PyObject_Str(*fromTy); - auto_pyobject toTyStr = PyObject_Str(*toTy); - - const char * fromCS = PyString_AsString(*fromTyStr); - const char * toCS = PyString_AsString(*toTyStr); - - oss << "downcast_"; - NormalizeString(oss, fromCS); - oss << "_to_"; - NormalizeString(oss, toCS); - std::string fname = oss.str(); - - auto_pyobject caster = PyObject_GetAttrString(GetDowncastModule(), - fname.c_str()); - - if (!caster) { - std::ostringstream oss; - oss << "Downcast from " << fromCS << " to " << toCS; - std::string errmsg = oss.str(); - PyErr_SetString(PyExc_TypeError, errmsg.c_str()); - return NULL; - } - - auto_pyobject oldObj = Unwrap(obj); - auto_pyobject newObj = PyObject_CallFunctionObjArgs(*caster, *oldObj, - NULL); - - bool used_to_own = HasOwnership(*oldObj); - - PyObject *result = Wrap(*newObj, !used_to_own); - - int status = PyObject_Not(result); - switch(status) { - case 0: - return result; - case 1: - default: - PyErr_SetString(PyExc_ValueError, "Downcast failed"); - Py_XDECREF(result); - return NULL; - } -} - -/////////////////////////////////////////////////////////////////////////////// - -struct CapsuleObject { - PyObject_HEAD; - PyObject *capsule; -}; - -static -void Capsule_dealloc(CapsuleObject* self) { - Py_XDECREF(self->capsule); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -static -int Capsule_init(CapsuleObject *self, PyObject *args, PyObject *kwds) -{ - PyObject *cap; - if (!PyArg_ParseTuple(args, "O", &cap)) { - return -1; - } - - if (!Check(cap)) { - PyErr_SetString(PyExc_TypeError, "Expected PyCapsule object"); - return -1; - } - - Py_INCREF(cap); - self->capsule = cap; - - PyObject* addr2refct = GetAddrRefCt(); - - auto_pyobject ptr = GetPointer(self->capsule); - auto_pyobject refct = PyObject_GetItem(addr2refct, *ptr); - auto_pyobject inc = PyNumber_InPlaceAdd(*refct, ConstantOne); - return PyObject_SetItem(addr2refct, *ptr, *inc); -} - -static -PyObject* Capsule_getclassname(CapsuleObject* self, void *closure) { - return GetClassName(self->capsule); -} - -static -PyObject* Capsule_getname(CapsuleObject* self, void *closure) { - return GetName(self->capsule); -} - -static -PyObject* Capsule_getpointer(CapsuleObject* self, void *closure) { - return GetPointer(self->capsule); -} - - -static -PyObject* Capsule_GetClass(CapsuleObject *self){ - PyObject *pycls = GetClassesDict(); - auto_pyobject key = GetClassName(self->capsule); - return PyDict_GetItem(pycls, *key); // borrowed reference -} - -static -PyObject* Capsule_get_class(CapsuleObject* self, PyObject* args) { - PyObject* out = Capsule_GetClass(self); - Py_XINCREF(out); - return out; -} - -static -PyObject* Capsule_instantiate(CapsuleObject* self, PyObject* args) { - return PyObject_CallFunctionObjArgs(Capsule_GetClass(self), self, NULL); -} - -/// Rotate Right -static unsigned long RotR(unsigned long hash, int offset){ - if (offset == 0) return hash; - - unsigned long out = hash << (sizeof(hash) * 8 - offset); - out |= hash >> offset; - return out; -} - - -/* -This is called everytime an object is returned from LLVM. -It derserves to be optimized to reduce unnecessary Python object allocation. -The following implements a simple hash function that uses XOR and -right-rotation. -*/ -static -long Capsule_hash(CapsuleObject *self) { - const char* name = PyCapsule_GetName(self->capsule); - void *pointer = PyCapsule_GetPointer(self->capsule, name); - - unsigned long hash = 0xabcd1234 ^ (unsigned long)pointer; - - // The first loop accounts for the different LLVM class name and the - // length of the name. - for(const char* p = name; *p != '\0'; ++p) { - hash ^= *p; - hash = RotR(hash, 11); - } - - // The second loop accounts for the pointer identity. - for(int i = 0; i capsule, - PyCapsule_GetName(a->capsule)); - void* pb = PyCapsule_GetPointer(b->capsule, - PyCapsule_GetName(b->capsule)); - return pa == pb; - } - return false; -} - -static -PyObject* Capsule_richcmp(PyObject *a, PyObject *b, int op) { - bool ret = Capsule_eq(a, b); - switch(op) { - case Py_EQ: break; - case Py_NE: ret = !ret; break; - default: - return Py_NotImplemented; - } - if (ret) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } -} - -static PyMemberDef Capsule_members[] = { - {"capsule", T_OBJECT_EX, offsetof(CapsuleObject, capsule), READONLY, "capsule"}, - { NULL }, -}; - -static PyMethodDef Capsule_methods[] = { - { "get_class", (PyCFunction)Capsule_get_class, METH_NOARGS, - "Get Capsule class"}, - { "instantiate", (PyCFunction)Capsule_instantiate, METH_NOARGS, - "create a new instance"}, - { NULL }, -}; - -static PyGetSetDef Capsule_getseters[] = { - {"classname", (getter)Capsule_getclassname, NULL, "class name", NULL}, - {"name", (getter)Capsule_getname, NULL, "name", NULL}, - {"pointer", (getter)Capsule_getpointer, NULL, "pointer", NULL}, - { NULL }, -}; - -static PyTypeObject CapsuleType = { -#if (PY_MAJOR_VERSION < 3) - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ -#else - PyVarObject_HEAD_INIT(NULL, 0) -#endif - "_capsule.Capsule", /*tp_name*/ - sizeof(CapsuleObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)Capsule_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)Capsule_hash, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - "Capsule object", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)Capsule_richcmp, /*tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Capsule_methods, /* tp_methods */ - Capsule_members, /* tp_members */ - Capsule_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)Capsule_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - - -/////////////////////////////////////////////////////////////////////////////// - static PyMethodDef core_methods[] = { #define declmethod(func) { #func , ( PyCFunction )func , METH_VARARGS , NULL } @@ -585,10 +76,6 @@ static PyMethodDef core_methods[] = { declmethod(getPointer), declmethod(check), declmethod(getClassName), - declmethod(unwrap), - declmethod(wrap), - declmethod(has_ownership), - declmethod(downcast), { NULL }, #undef declmethod }; @@ -619,21 +106,10 @@ extern "C" { #else PyObject *module = Py_InitModule("_capsule", core_methods); #endif - if (module == NULL){ + if (module == NULL) INITERROR; - } - - if (module) { - CapsuleType.tp_new = PyType_GenericNew; - if (PyType_Ready(&CapsuleType) < 0) { - INITERROR; - } - Py_INCREF(&CapsuleType); - PyModule_AddObject(module, "Capsule", (PyObject*)(&CapsuleType)); - - ConstantOne = PyInt_FromLong(1); - } #if PY_MAJOR_VERSION >= 3 + return module; #endif } diff --git a/llvmpy/capsule.py b/llvmpy/capsule.py index 3fb9a39..5efed13 100644 --- a/llvmpy/capsule.py +++ b/llvmpy/capsule.py @@ -1,27 +1,17 @@ -from weakref import WeakValueDictionary +from weakref import WeakKeyDictionary, WeakValueDictionary, ref from collections import defaultdict import logging -from llvmpy._capsule import (unwrap, has_ownership, downcast, wrap, - getClassName, getName, getPointer, Capsule) - - logger = logging.getLogger(__name__) -NO_DEBUG = False - - def silent_logger(): ''' Silent logger for unless we have a error message. ''' - global NO_DEBUG logger.setLevel(logging.ERROR) - NO_DEBUG = True # comment out the line below to re-enable logging at DEBUG level. silent_logger() - def set_debug(enabled): ''' Side-effect: configure logger with it is not configured. @@ -36,63 +26,75 @@ def set_debug(enabled): else: logger.setLevel(logging.WARNING) +def _capsule_weakref_dtor(item): + addr = item.pointer + name = item.name + _addr2refct[addr] -= 1 + refct = _addr2refct[addr] + assert refct >= 0, "RefCt drop below 0" + if refct == 0: + dtor = _addr2dtor.pop((name, addr), None) + if dtor is not None: + logger.debug('Destroy %s %s', name, hex(addr)) + dtor(item.capsule) -#class Capsule(object): -# "Wraps PyCapsule so that we can build weakref of it." -# from ._capsule import check, getClassName, getName, getPointer -# __slots__ = "capsule" -# -# def __init__(self, capsule): -# assert Capsule.valid(capsule) -# self.capsule = capsule -# -# #weak = WeakRef(self, _capsule_weakref_dtor) -# #weak.pointer = self.pointer -# #weak.capsule = capsule -# #weak.name = self.name -# #_capsule2weak[self] = weak -# _addr2refct[self.pointer] += 1 -# -# @property -# def classname(self): -# return self.getClassName(self.capsule) -# -# @property -# def name(self): -# return self.getName(self.capsule) -# -# @property -# def pointer(self): -# return self.getPointer(self.capsule) -# -# @staticmethod -# def valid(capsule): -# return Capsule.check(capsule) -# -# def get_class(self): -# return _pyclasses[self.classname] -# -# def instantiate(self): -# cls = self.get_class() -# return cls(self) -# -# def __eq__(self, other): -# if isinstance(other, Capsule) and self.pointer == other.pointer: -# assert self.name == other.name -# return True -# else: -# return False -# -# def __hash__(self): -# return hash((self.pointer, self.name)) -# -# def __ne__(self, other): -# return not (self == other) +class Capsule(object): + "Wraps PyCapsule so that we can build weakref of it." + from ._capsule import check, getClassName, getName, getPointer + def __init__(self, capsule): + assert Capsule.valid(capsule) + self.capsule = capsule + + weak = WeakRef(self, _capsule_weakref_dtor) + weak.pointer = self.pointer + weak.capsule = capsule + weak.name = self.name + _capsule2weak[self] = weak + _addr2refct[self.pointer] += 1 + + @property + def classname(self): + return self.getClassName(self.capsule) + + @property + def name(self): + return self.getName(self.capsule) + + @property + def pointer(self): + return self.getPointer(self.capsule) + + @staticmethod + def valid(capsule): + return Capsule.check(capsule) + + def get_class(self): + return _pyclasses[self.classname] + + def instantiate(self): + cls = self.get_class() + return cls(self) + + def __eq__(self, other): + if self.pointer == other.pointer: + assert self.name == other.name + return True + else: + return False + + def __hash__(self): + return hash((self.pointer, self.name)) + + def __ne__(self, other): + return not (self == other) + +class WeakRef(ref): + pass _addr2refct = defaultdict(lambda: 0) -#_capsule2weak = WeakKeyDictionary() +_capsule2weak = WeakKeyDictionary() _addr2dtor = {} _pyclasses = {} @@ -100,16 +102,15 @@ _pyclasses = {} # NOTE: The same 'addr' may appear in multiple class bins. _cache = defaultdict(WeakValueDictionary) - def release_ownership(old): logger.debug('Release %s', old) - addr = getPointer(old) - name = getName(old) + addr = Capsule.getPointer(old) + name = Capsule.getName(old) if _addr2dtor.get((name, addr)) is None: - clsname = getClassName(old) + clsname = Capsule.getClassName(old) if not _pyclasses[clsname]._has_dtor(): return - # Guard duplicated release + # Guard duplicated release raise Exception("Already released") _addr2dtor[(name, addr)] = None @@ -119,86 +120,61 @@ def obtain_ownership(cap): if cls._has_dtor(): addr = cap.pointer name = cap.name - assert _addr2dtor[(name, addr)] is None + assert _addr2dtor[addr] is None _addr2dtor[(name, addr)] = cls._delete_ +def has_ownership(cap): + addr = Capsule.getPointer(cap) + name = Capsule.getName(cap) + return _addr2dtor.get((name, addr)) is not None -#def has_ownership(cap): -# addr = Capsule.getPointer(cap) -# name = Capsule.getName(cap) -# return _addr2dtor.get((name, addr)) is not None +def wrap(cap, owned=False): + '''Wrap a PyCapsule with the corresponding Wrapper class. + If `cap` is not a PyCapsule, returns `cap` + ''' + if not Capsule.valid(cap): + if isinstance(cap, list): + return list(map(wrap, cap)) + return cap # bypass if cap is not a PyCapsule and not a list + cap = Capsule(cap) + cls = cap.get_class() + addr = cap.pointer + name = cap.name + # lookup cached object + if cls in _cache and addr in _cache[cls]: + obj = _cache[cls][addr] + else: + if not owned and cls._has_dtor(): + _addr2dtor[(name, addr)] = cls._delete_ + obj = cap.instantiate() + _cache[cls][addr] = obj # cache it + return obj -#def wrap(cap, owned=False): -# '''Wrap a PyCapsule with the corresponding Wrapper class. -# If `cap` is not a PyCapsule, returns `cap` -# ''' -# if not Capsule.valid(cap): -# if isinstance(cap, list): -# return list(map(wrap, cap)) -# return cap # bypass if cap is not a PyCapsule and not a list -# -# cap = Capsule(cap) -# cls = cap.get_class() -# addr = cap.pointer -# name = cap.name -# # lookup cached object -# if cls in _cache and addr in _cache[cls]: -# obj = _cache[cls][addr] -# else: -# if not owned and cls._has_dtor(): -# _addr2dtor[(name, addr)] = cls._delete_ -# obj = cap.instantiate() -# _cache[cls][addr] = obj # cache it -# return obj - -#def unwrap(obj): +def unwrap(obj): '''Unwrap a Wrapper instance into the underlying PyCapsule. If `obj` is not a Wrapper instance, returns `obj`. ''' -# if isinstance(obj, Wrapper): -# return obj._ptr -# else: -# return obj + if isinstance(obj, Wrapper): + return obj._ptr + else: + return obj def register_class(clsname): def _wrapped(cls): _pyclasses[clsname] = cls return cls - return _wrapped class Wrapper(object): + __slots__ = '__capsule' def __init__(self, capsule): self.__capsule = capsule - def __del__(self): - if _addr2refct is None: - # System is tearing down - # No need to free anything - return - - item = self.__capsule - addr = item.pointer - name = item.name - - _addr2refct[addr] -= 1 - refct = _addr2refct[addr] - assert refct >= 0, "RefCt drop below 0" - if refct == 0: - dtor = _addr2dtor.pop((name, addr), None) - if dtor is not None: - if not NO_DEBUG: - # Some globals in logger could be removed by python GC - # at interpreter teardown. - # That can cause exception raised and ignored message. - logger.debug('Destroy %s %s', name, hex(addr)) - dtor(item.capsule) - @property def _capsule(self): return self.__capsule @@ -211,11 +187,10 @@ class Wrapper(object): return hash(self._capsule) def __eq__(self, other): - if isinstance(other, Wrapper): - return self._capsule == other._capsule + return self._capsule == other._capsule def __ne__(self, other): - return not (self == other) + return not(self == other) def _downcast(self, newcls): return downcast(self, newcls) @@ -224,25 +199,24 @@ class Wrapper(object): def _has_dtor(cls): return hasattr(cls, '_delete_') +def downcast(obj, cls): + from . import _api + if type(obj) is cls: + return obj + fromty = obj._llvm_type_ + toty = cls._llvm_type_ + logger.debug("Downcast %s to %s" , fromty, toty) + fname = 'downcast_%s_to_%s' % (fromty, toty) + fname = fname.replace('::', '_') + if not hasattr(_api.downcast, fname): + fmt = "Downcast from %s to %s is not supported" + raise TypeError(fmt % (fromty, toty)) + caster = getattr(_api.downcast, fname) + old = unwrap(obj) + new = caster(old) + used_to_own = has_ownership(old) + res = wrap(new, owned=not used_to_own) + if not res: + raise ValueError("Downcast failed") + return res -#def downcast(obj, cls): -# from . import _api -# -# if type(obj) is cls: -# return obj -# fromty = obj._llvm_type_ -# toty = cls._llvm_type_ -# logger.debug("Downcast %s to %s", fromty, toty) -# fname = 'downcast_%s_to_%s' % (fromty, toty) -# fname = fname.replace('::', '_') -# if not hasattr(_api.downcast, fname): -# fmt = "Downcast from %s to %s is not supported" -# raise TypeError(fmt % (fromty, toty)) -# caster = getattr(_api.downcast, fname) -# old = unwrap(obj) -# new = caster(old) -# used_to_own = has_ownership(old) -# res = wrap(new, owned=not used_to_own) -# if not res: -# raise ValueError("Downcast failed") -# return res diff --git a/llvmpy/gen/binding.py b/llvmpy/gen/binding.py index 5a6d8f4..db4fdbf 100644 --- a/llvmpy/gen/binding.py +++ b/llvmpy/gen/binding.py @@ -1,4 +1,5 @@ import inspect, textwrap +import functools import codegen as cg import os @@ -7,12 +8,10 @@ namespaces = {} RESERVED = frozenset(['None']) - def makedir(directory): if not os.path.exists(directory): os.makedirs(directory) - class SubModule(object): def __init__(self): self.methods = [] @@ -294,10 +293,6 @@ class Class(SubModule, _Type): writer.println('@capsule.register_class("%s")' % self.fullname) with writer.block('class %(clsname)s(%(bases)s):' % locals()): writer.println('_llvm_type_ = "%s"' % self.fullname) - if self.bases: - writer.println('__slots__ = ()') - else: - writer.println('__slots__ = "__weakref__"') for enum in self.enums: enum.compile_py(writer) for meth in self.methods: @@ -338,7 +333,7 @@ class Class(SubModule, _Type): writer.die_if_false(raw, verbose=name) ptrty = ptr(self).fullname ty = self.fullname - fmt = 'unwrap_as<%(ty)s, %(name)s >::from(%(raw)s)' + fmt = 'typecast< %(ty)s >::from(%(raw)s)' casted = writer.declare(ptrty, fmt % locals()) writer.die_if_false(casted) return casted @@ -404,7 +399,6 @@ class Enum(object): writer.println(fmt % locals()) writer.println() - class Method(object): _kind_ = 'meth' @@ -522,7 +516,6 @@ class Method(object): with writer.block('if len(%s) > %d:' % (unwrapped, i)): writer.release_ownership('%s[%d]' % (unwrapped, i)) - class CustomMethod(Method): def __init__(self, methodname, retty, *argtys): super(CustomMethod, self).__init__(retty, *argtys) @@ -601,7 +594,6 @@ class CustomFunction(Function): def fullname(self): return self.realname - class Destructor(Method): _kind_ = 'dtor' @@ -633,7 +625,6 @@ class Constructor(StaticMethod): ret = writer.declare(retty.fullname, stmt) return ret - class ref(_Type): def __init__(self, element): assert isinstance(element, Class), type(element) @@ -695,16 +686,13 @@ class ptr(_Type): return writer.pycapsule_new(val, self.element.capsule_name, self.element.fullname) - class ownedptr(ptr): pass - def const(ptr_or_ref): ptr_or_ref.const = True return ptr_or_ref - class cast(_Type): format = 'O' @@ -769,7 +757,6 @@ class CustomPythonMethod(object): for line in self.sourcelines: writer.println(line) - class CustomPythonStaticMethod(CustomPythonMethod): def compile_py(self, writer): writer.println('@staticmethod') @@ -858,7 +845,6 @@ class Attr(object): TARGETS_BUILT = os.environ.get('LLVM_TARGETS_BUILT', '').split() - def _parse_llvm_version(ver): import re m = re.compile(r'(\d+)\.(\d+)').match(ver) diff --git a/llvmpy/gen/codegen.py b/llvmpy/gen/codegen.py index 6e36683..f9585fd 100644 --- a/llvmpy/gen/codegen.py +++ b/llvmpy/gen/codegen.py @@ -202,8 +202,7 @@ class CppCodeWriter(CodeWriterBase): def pycapsule_new(self, ptr, name, clsname): name_soften = mangle(name) - cast_to_base = 'cast_to_base<%s >::from(%s)' % (name, ptr) - ret = self.call('pycapsule_new', 'PyObject*', cast_to_base, quote(name), + ret = self.call('pycapsule_new', 'PyObject*', ptr, quote(name), quote(clsname)) with self.block('if (!%(ret)s)' % locals()): self.return_null() diff --git a/llvmpy/gen/gen.py b/llvmpy/gen/gen.py index bb408a1..cd63b68 100644 --- a/llvmpy/gen/gen.py +++ b/llvmpy/gen/gen.py @@ -9,7 +9,7 @@ extern "C" { #if (PY_MAJOR_VERSION >= 3) -PyMODINIT_FUNC +PyObject * PyInit_%(module)s(void) { PyObject *module = create_python_module("%(module)s", meth_%(ns)s); diff --git a/llvmpy/include/llvm_binding/conversion.h b/llvmpy/include/llvm_binding/conversion.h index b37f618..a9f073c 100644 --- a/llvmpy/include/llvm_binding/conversion.h +++ b/llvmpy/include/llvm_binding/conversion.h @@ -256,7 +256,6 @@ template struct typecast { template static Td* from(Ts* src) { - // check why this is only used in Python3 return llvm::dyn_cast(src); } @@ -266,24 +265,3 @@ struct typecast { } }; -template -struct unwrap_as { - static - Td* from(void* src) { - Tbase* base = static_cast(src); - return static_cast(base); - } -}; - -template -struct cast_to_base { - template static - Td* from(Ts* src){ - return static_cast(src); - } - - template static - const Td* from(const Ts* src){ - return static_cast(src); - } -}; diff --git a/llvmpy/include/llvm_binding/extra.h b/llvmpy/include/llvm_binding/extra.h index bdd86d3..161c52e 100644 --- a/llvmpy/include/llvm_binding/extra.h +++ b/llvmpy/include/llvm_binding/extra.h @@ -1,6 +1,6 @@ #include #include -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 3 +#if LLVM_VERSION_MAJOR >= 3 and LLVM_VERSION_MINOR >= 3 #include #include #include @@ -8,10 +8,6 @@ #include #include #include - #if LLVM_VERSION_MINOR >= 4 - #include - #include - #endif #else #include #include @@ -40,7 +36,7 @@ namespace extra{ using namespace llvm; - + class raw_svector_ostream_helper: public raw_svector_ostream { SmallVectorImpl *SV; public: @@ -85,7 +81,7 @@ PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) { using extra::raw_svector_ostream_helper; using llvm::raw_svector_ostream; - + if (!PyArg_ParseTuple(args, "")) { return NULL; } @@ -99,7 +95,7 @@ PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) { using llvm::Type; typedef llvm::SmallVector SmallVector_Type; - + SmallVector_Type* SV = new SmallVector_Type; Py_ssize_t size = PyTuple_Size(args); for (Py_ssize_t i = 0; i < size; ++i) { @@ -186,8 +182,8 @@ PyObject* iterator_to_pylist_deref(iterator begin, iterator end, { PyObject* list = PyList_New(0); for(; begin != end; ++begin) { - auto_pyobject cap = pycapsule_new(&*begin, capsuleName, className); - PyList_Append(list, *cap); + PyObject* cap = pycapsule_new(&*begin, capsuleName, className); + PyList_Append(list, cap); } return list; } @@ -198,8 +194,8 @@ PyObject* iterator_to_pylist(iterator begin, iterator end, { PyObject* list = PyList_New(0); for(; begin != end; ++begin) { - auto_pyobject cap = pycapsule_new(*begin, capsuleName, className); - PyList_Append(list, *cap); + PyObject* cap = pycapsule_new(*begin, capsuleName, className); + PyList_Append(list, cap); } return list; } @@ -420,7 +416,7 @@ PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE, PyErr_SetString(PyExc_RuntimeError, "Failed to index into args?"); return NULL; } - + GenericValue* gv = static_cast( PyCapsule_GetPointer(obj, GVN)); @@ -575,11 +571,11 @@ PyObject* TargetMachine_addPassesToEmitFile( bool status = TM->addPassesToEmitFile(PM, fso, FTy, disableVerify); if (status) { StringRef sr = rso.str(); - auto_pyobject buf = PyString_FromStringAndSize(sr.data(), sr.size()); + PyObject* buf = PyString_FromStringAndSize(sr.data(), sr.size()); if (!buf) { return NULL; } - if (-1 == PyFile_WriteObject(*buf, Out, Py_PRINT_RAW)){ + if (-1 == PyFile_WriteObject(buf, Out, Py_PRINT_RAW)){ return NULL; } Py_RETURN_TRUE; @@ -626,7 +622,7 @@ PyObject* Linker_LinkInModule(llvm::Linker* Linker, if (! failed) { Py_RETURN_FALSE; } else { - + auto_pyobject buf = PyBytes_FromString(errmsg.c_str()); if (NULL == callwrite(ErrMsg, *buf)){ return NULL; @@ -861,27 +857,6 @@ PyObject* DynamicLibrary_LoadLibraryPermanently(const char * Filename, } } -static -PyObject* DynamicLibrary_getPermanentLibrary(const char * Filename, - PyObject* ErrMsg = 0) -{ - using namespace llvm::sys; - std::string errmsg; - DynamicLibrary dylib = DynamicLibrary::getPermanentLibrary(Filename, &errmsg); - if (!dylib.isValid()) { - if (ErrMsg) { - auto_pyobject buf = PyBytes_FromString(errmsg.c_str()); - if (!callwrite(ErrMsg, *buf)) - return NULL; - } - PyErr_SetString(PyExc_RuntimeError, errmsg.c_str()); - return NULL; - } - return pycapsule_new(new DynamicLibrary(dylib), - "llvm::sys::DynamicLibrary", - "llvm::sys::DynamicLibrary"); -} - class PassRegistryEnumerator : public llvm::PassRegistrationListener{ public: PyObject* List; @@ -891,8 +866,7 @@ public: inline virtual void passEnumerate(const llvm::PassInfo * pass_info){ PyObject* passArg = PyString_FromString(pass_info->getPassArgument()); PyObject* passName = PyString_FromString(pass_info->getPassName()); - auto_pyobject pair = Py_BuildValue("(OO)", passArg, passName); - PyList_Append(List, *pair); + PyList_Append(List, Py_BuildValue("(OO)", passArg, passName)); } }; @@ -947,6 +921,7 @@ PyObject* TargetRegistry_lookupTarget(const std::string &Arch, } } + static PyObject* TargetRegistry_getClosestTargetForJIT(PyObject* Error) { @@ -967,66 +942,6 @@ PyObject* TargetRegistry_getClosestTargetForJIT(PyObject* Error) } -static -PyObject* TargetRegistry_targets_list() -{ - using namespace llvm; - - return iterator_to_pylist_deref( - TargetRegistry::begin(), TargetRegistry::end(), - "llvm::Target", "llvm::Target"); -} - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 4 -static -PyObject* MemoryObject_readBytes(const llvm::MemoryObject *mobj, - uint64_t addr, - uint64_t size - ) -{ - int status; - uint8_t *bytes; - PyObject* po; - - if(size < 1) - goto fail; - - bytes = new uint8_t[size]; - if(bytes == NULL) - goto fail; - - status = mobj->readBytes(addr, size, bytes); - if(status != 0) { - delete bytes; - goto fail; - } - - po = PyBytes_FromStringAndSize((const char *) bytes, size); - delete bytes; - - return po; -fail: - Py_RETURN_NONE; -} - -static -PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm, - llvm::MCInst &instr, - const llvm::MemoryObject ®ion, - uint64_t address - ) -{ - uint64_t size; - llvm::MCDisassembler::DecodeStatus status; - - size = 0; - status = disasm->getInstruction(instr, size, region, address, - llvm::nulls(), llvm::nulls()); - return Py_BuildValue("(i,i)", int(status), size); -} - -#endif /* llvm >= 3.4 */ - static PyObject* llvm_sys_getHostCPUFeatures(PyObject* Features) { @@ -1068,5 +983,4 @@ PyObject* llvm_sys_isBigEndianHost() else Py_RETURN_FALSE; } -#endif - +#endif diff --git a/llvmpy/setup.py b/llvmpy/setup.py index a91bf66..bb23c32 100644 --- a/llvmpy/setup.py +++ b/llvmpy/setup.py @@ -31,7 +31,7 @@ components = ['core', 'analysis', 'scalaropts', 'interpreter', 'bitreader', 'bitwriter', 'instrumentation', 'ipa', 'ipo', 'transformutils', 'asmparser', - 'linker', 'support', 'vectorize', 'all-targets' + 'linker', 'support', 'vectorize', ] nvptx = ['nvptx', diff --git a/llvmpy/src/Attributes.py b/llvmpy/src/Attributes.py index 7985833..303d61d 100644 --- a/llvmpy/src/Attributes.py +++ b/llvmpy/src/Attributes.py @@ -21,14 +21,14 @@ if LLVM_VERSION >= (3, 3): @Attribute class Attribute: AttrKind = Enum('''None, Alignment, AlwaysInline, - ByVal, InlineHint, InReg, - MinSize, Naked, Nest, NoAlias, - NoBuiltin, NoCapture, NoDuplicate, NoImplicitFloat, - NoInline, NonLazyBind, NoRedZone, NoReturn, - NoUnwind, OptimizeForSize, ReadNone, ReadOnly, - Returned, ReturnsTwice, SExt, StackAlignment, - StackProtect, StackProtectReq, StackProtectStrong, StructRet, - SanitizeAddress, SanitizeThread, SanitizeMemory, UWTable, + ByVal, InlineHint, InReg, + MinSize, Naked, Nest, NoAlias, + NoBuiltin, NoCapture, NoDuplicate, NoImplicitFloat, + NoInline, NonLazyBind, NoRedZone, NoReturn, + NoUnwind, OptimizeForSize, ReadNone, ReadOnly, + Returned, ReturnsTwice, SExt, StackAlignment, + StackProtect, StackProtectReq, StackProtectStrong, StructRet, + SanitizeAddress, SanitizeThread, SanitizeMemory, UWTable, ZExt, EndAttrKinds''') delete = Destructor() diff --git a/llvmpy/src/BasicBlock.py b/llvmpy/src/BasicBlock.py index 3c82e17..6efe704 100644 --- a/llvmpy/src/BasicBlock.py +++ b/llvmpy/src/BasicBlock.py @@ -1,13 +1,12 @@ from binding import * from .namespace import llvm -from .Value import Function, BasicBlock, Value +from .Value import Function, BasicBlock from .Instruction import Instruction, TerminatorInst from .LLVMContext import LLVMContext from .ADT.StringRef import StringRef @BasicBlock class BasicBlock: - _downcast_ = Value Create = StaticMethod(ptr(BasicBlock), ref(LLVMContext), cast(str, StringRef), ptr(Function), diff --git a/llvmpy/src/CallingConv.py b/llvmpy/src/CallingConv.py index bdd5c1c..efca1fc 100644 --- a/llvmpy/src/CallingConv.py +++ b/llvmpy/src/CallingConv.py @@ -1,16 +1,10 @@ from binding import * from .namespace import llvm -ccs = ''' - C, Fast, Cold, GHC, FirstTargetCC, X86_StdCall, X86_FastCall, - ARM_APCS, ARM_AAPCS, ARM_AAPCS_VFP, MSP430_INTR, X86_ThisCall, - PTX_Kernel, PTX_Device, -''' - -if LLVM_VERSION <= (3, 3): - ccs += "MBLAZE_INTR, MBLAZE_SVOL," - -ccs += 'SPIR_FUNC, SPIR_KERNEL, Intel_OCL_BI' - CallingConv = llvm.Namespace('CallingConv') -ID = CallingConv.Enum('ID', ccs) # HiPE +ID = CallingConv.Enum('ID', ''' + C, Fast, Cold, GHC, FirstTargetCC, X86_StdCall, X86_FastCall, + ARM_APCS, ARM_AAPCS, ARM_AAPCS_VFP, MSP430_INTR, X86_ThisCall, + PTX_Kernel, PTX_Device, MBLAZE_INTR, MBLAZE_SVOL, SPIR_FUNC, + SPIR_KERNEL, Intel_OCL_BI + ''') # HiPE diff --git a/llvmpy/src/DIBuilder.py b/llvmpy/src/DIBuilder.py index 78aba4c..cb934d4 100644 --- a/llvmpy/src/DIBuilder.py +++ b/llvmpy/src/DIBuilder.py @@ -6,7 +6,7 @@ DIBuilder = llvm.Class() from .Module import Module from .Value import Value, MDNode, Function, BasicBlock from .Instruction import Instruction -from .DebugInfo import DIFile, DIEnumerator, DIType, DIBasicType, DIDerivedType, DICompositeType +from .DebugInfo import DIFile, DIEnumerator, DIType, DIBasicType, DIDerivedType from .DebugInfo import DIDescriptor, DIArray, DISubrange, DIGlobalVariable from .DebugInfo import DIVariable, DISubprogram, DINameSpace, DILexicalBlockFile from .DebugInfo import DILexicalBlock @@ -25,8 +25,7 @@ class DIBuilder: new = Constructor(ref(Module)) delete = Destructor() - if LLVM_VERSION <= (3, 3): - getCU = Method(const(ptr(MDNode))) + getCU = Method(const(ptr(MDNode))) finalize = Method() createCompileUnit = Method(Void, @@ -47,16 +46,12 @@ class DIBuilder: createEnumerator = Method(DIEnumerator, stringref_arg, # Name - uint64_arg if LLVM_VERSION <= (3, 3) else int64_arg, # Val + uint64_arg, # Val ) - if LLVM_VERSION <= (3, 3): - createNullPtrType = Method(DIType, - stringref_arg, # Name - ) - else: - createNullPtrType = Method(DIBasicType) - + createNullPtrType = Method(DIType, + stringref_arg, # Name + ) createBasicType = Method(DIType, stringref_arg, # Name @@ -90,7 +85,7 @@ class DIBuilder: ref(DIDescriptor), # Context ) - createFriend = Method(DIType if LLVM_VERSION <= (3, 3) else DIDerivedType, + createFriend = Method(DIType, ref(DIType), # Ty ref(DIType), # FriendTy ) @@ -174,7 +169,7 @@ class DIBuilder: ref(DIArray), # Subscripts ) - createVectorType = Method(DIType if LLVM_VERSION <= (3, 3) else DICompositeType, + createVectorType = Method(DIType, uint64_arg, # Size uint64_arg, # AlignInBits ref(DIType), # Ty @@ -204,7 +199,7 @@ class DIBuilder: createObjectPointerType = Method(DIType, ref(DIType), # Ty ) - + #createTemporaryType = Method(DIType, ref(DIFile)).require_only(0) createForwardDecl = Method(DIType, @@ -250,7 +245,7 @@ class DIBuilder: bool_arg, # isLocalToUnit ptr(Value), # Val ) - + createLocalVariable = Method(DIVariable, unsigned_arg, # Tag, ref(DIDescriptor), # Scope, @@ -273,14 +268,14 @@ class DIBuilder: ref(SmallVector_Value), # Addr, unsigned_arg, # ArgNo=0, ).require_only(7) - + createFunction = Method(DISubprogram, ref(DIDescriptor), # Scope stringref_arg, # Name stringref_arg, # LinkageName ref(DIFile), # File unsigned_arg, # LineNo - ref(DIType if LLVM_VERSION <= (3, 3) else DICompositeType), # Ty + ref(DIType), # Ty bool_arg, # isLocalToUnit bool_arg, # isDefinition unsigned_arg, # ScopeLine @@ -298,7 +293,7 @@ class DIBuilder: stringref_arg, # LinkageName ref(DIFile), # File unsigned_arg, # LineNo - ref(DIType if LLVM_VERSION <= (3, 3) else DICompositeType), # Ty + ref(DIType), # Ty bool_arg, # isLocalToUnit bool_arg, # isDefinition unsigned_arg, # Virtuality=0 @@ -318,7 +313,7 @@ class DIBuilder: unsigned_arg, # LineNo ) - createLexicalBlockFile = Method(DILexicalBlockFile, + createLexicalBlockFile = Method(DILexicalBlockFile, ref(DIDescriptor), # Scope, ref(DIFile), # File ) @@ -329,7 +324,7 @@ class DIBuilder: unsigned_arg, # Line, unsigned_arg, # Col ) - + _insertDeclare_1 = Method(ptr(Instruction), ptr(Value), # Storage, ref(DIVariable), # VarInfo diff --git a/llvmpy/src/DebugInfo.py b/llvmpy/src/DebugInfo.py index b316c62..8ddb1ee 100644 --- a/llvmpy/src/DebugInfo.py +++ b/llvmpy/src/DebugInfo.py @@ -44,7 +44,7 @@ class DIFile: @DIEnumerator class DIEnumerator: getName = Method(return_stringref) - getEnumValue = Method(cast(Uint64 if LLVM_VERSION <= (3, 3) else Int64, int)) + getEnumValue = Method(cast(Uint64, int)) Verify = Method(return_bool) @DIType diff --git a/llvmpy/src/Function.py b/llvmpy/src/Function.py index ac5b6fd..9c2c8b7 100644 --- a/llvmpy/src/Function.py +++ b/llvmpy/src/Function.py @@ -19,7 +19,7 @@ class Function: _include_ = 'llvm/IR/Function.h' else: _include_ = 'llvm/Function.h' - + _downcast_ = GlobalValue, Constant, Value getReturnType = Method(ptr(Type)) diff --git a/llvmpy/src/Instruction.py b/llvmpy/src/Instruction.py index 585b7ec..2771015 100644 --- a/llvmpy/src/Instruction.py +++ b/llvmpy/src/Instruction.py @@ -346,9 +346,6 @@ class AllocaInst: isStaticAlloca = Method(cast(Bool, bool)) getArraySize = Method(ptr(Value)) getAllocatedType = Method(ptr(Type)) - getAlignment = Method(cast(Unsigned, int)) - setAlignment = Method(Void, cast(int, Unsigned)) - getArraySize = Method(ptr(Value)) @CastInst diff --git a/llvmpy/src/MC/__init__.py b/llvmpy/src/MC/__init__.py deleted file mode 100644 index f7ff609..0000000 --- a/llvmpy/src/MC/__init__.py +++ /dev/null @@ -1,157 +0,0 @@ -#this file is not processed unless the llvm library is -#version 3.4 or higher. see llvmpy/__init__.py for details. -from binding import * -from ..namespace import llvm -from ..Support.StringRefMemoryObject import MemoryObject -from ..Support.raw_ostream import raw_ostream -from src.ADT.StringRef import StringRef - -MCSubtargetInfo = llvm.Class() -MCDisassembler = llvm.Class() -MCInst = llvm.Class() -MCOperand = llvm.Class() -MCExpr = llvm.Class() -MCAsmInfo = llvm.Class() -MCRegisterInfo = llvm.Class() -MCInstrInfo = llvm.Class() -MCInstrAnalysis = llvm.Class() -MCInstPrinter = llvm.Class() -MCInstrDesc = llvm.Class() - -TargetSubtargetInfo = llvm.Class(MCSubtargetInfo) -TargetInstrInfo = llvm.Class(MCInstrInfo) -TargetRegisterInfo = llvm.Class(MCRegisterInfo) - -@MCInstrDesc -class MCInstrDesc: - _include_ = "llvm/MC/MCInstrDesc.h" - - TSFlags = Attr(getter=cast(Uint64, int), setter=cast(int, Uint64)) - getFlags = Method(cast(Unsigned, int)) - getOpcode = Method(cast(Unsigned, int)) - - def _ret_bool(): - return Method(cast(Bool, bool)) - - isReturn = _ret_bool() - isCall = _ret_bool() - isBarrier = _ret_bool() - isBranch = _ret_bool() - isTerminator = _ret_bool() - isIndirectBranch = _ret_bool() - isConditionalBranch = _ret_bool() - isUnconditionalBranch = _ret_bool() - - -@MCSubtargetInfo -class MCSubtargetInfo: - pass - -@TargetSubtargetInfo -class TargetSubtargetInfo: - _include_ = 'llvm/Target/TargetSubtargetInfo.h' - -@MCExpr -class MCExpr: - _include_ = "llvm/MC/MCExpr.h" - - ExprKind = Enum('Binary', 'Constant', 'SymbolRef', 'Unary', 'Target') - getKind = Method(ExprKind) - -@MCOperand -class MCOperand: - _include_ = "llvm/MC/MCInst.h" - - isValid = Method(cast(Bool, bool)) - isReg = Method(cast(Bool, bool)) - isImm = Method(cast(Bool, bool)) - isFPImm = Method(cast(Bool, bool)) - isExpr = Method(cast(Bool, bool)) - isInst = Method(cast(Bool, bool)) - - getReg = Method(cast(Unsigned, int)) - getImm = Method(cast(Int64, int)) - getFPImm = Method(cast(Double, float)) - getExpr = Method(const(ownedptr(MCExpr))) - -@MCInst -class MCInst: - _include_ = "llvm/MC/MCInst.h" - new = Constructor() - - size = Method(cast(Size_t, int)) - getNumOperands = Method(cast(Unsigned, int)) - - getOperand = Method(const(ref(MCOperand)), cast(int, Unsigned)) - - getOpcode = Method(cast(Unsigned, int)) - -MCOperand.getInst = Method(const(ownedptr(MCInst))) - -@MCAsmInfo -class MCAsmInfo: - _include_ = "llvm/MC/MCAsmInfo.h" - - getAssemblerDialect = Method(cast(Unsigned, int)) - getMinInstAlignment = Method(cast(Unsigned, int)) - isLittleEndian = Method(cast(Bool, bool)) - -@MCRegisterInfo -class MCRegisterInfo: - _include_ = "llvm/MC/MCRegisterInfo.h" - - getName = Method(cast(ConstCharPtr, str), cast(int, Unsigned)) - -@TargetRegisterInfo -class TargetRegisterInfo: - _include_ = "llvm/Target/TargetRegisterInfo.h" - -@MCInstrInfo -class MCInstrInfo: - _include_ = "llvm/MC/MCInstrInfo.h" - - get = Method(const(ref(MCInstrDesc)), cast(int, Unsigned)) - -@TargetInstrInfo -class TargetInstrInfo: - _include_ = 'llvm/Target/TargetInstrInfo.h' - -@MCInstrAnalysis -class MCInstrAnalysis: - _include_ = "llvm/MC/MCInstrAnalysis.h" - - - def _take_mcinst_ret_bool(): - return Method(cast(Bool, bool), const(ref(MCInst))) - - isBranch = _take_mcinst_ret_bool() - isConditionalBranch = _take_mcinst_ret_bool() - isUnconditionalBranch = _take_mcinst_ret_bool() - isIndirectBranch = _take_mcinst_ret_bool() - isCall = _take_mcinst_ret_bool() - isReturn = _take_mcinst_ret_bool() - isTerminator = _take_mcinst_ret_bool() - -@MCInstPrinter -class MCInstPrinter: - _include_ = "llvm/MC/MCInstPrinter.h" - - printInst = Method(Void, - const(ptr(MCInst)), #MI - ref(raw_ostream), #OS - cast(str, StringRef) #Annot - ) - -@MCDisassembler -class MCDisassembler: - _include_ = "llvm/MC/MCDisassembler.h" - - DecodeStatus = Enum('Fail', 'SoftFail', 'Success') - - getInstruction = CustomMethod('MCDisassembler_getInstruction', - PyObjectPtr, - ref(MCInst), - ref(MemoryObject), - cast(int, Uint64) - ) - diff --git a/llvmpy/src/Support/Dwarf.py b/llvmpy/src/Support/Dwarf.py index ab537a4..caecc24 100644 --- a/llvmpy/src/Support/Dwarf.py +++ b/llvmpy/src/Support/Dwarf.py @@ -7,557 +7,557 @@ dwarf.includes.add('llvm/Support/Dwarf.h') dwarf_constants = dwarf.Enum('dwarf_constants', ''' -DWARF_VERSION -DW_TAG_array_type -DW_TAG_class_type -DW_TAG_entry_point -DW_TAG_enumeration_type -DW_TAG_formal_parameter -DW_TAG_imported_declaration -DW_TAG_label -DW_TAG_lexical_block -DW_TAG_member +DWARF_VERSION +DW_TAG_array_type +DW_TAG_class_type +DW_TAG_entry_point +DW_TAG_enumeration_type +DW_TAG_formal_parameter +DW_TAG_imported_declaration +DW_TAG_label +DW_TAG_lexical_block +DW_TAG_member DW_TAG_pointer_type -DW_TAG_reference_type -DW_TAG_compile_unit -DW_TAG_string_type -DW_TAG_structure_type -DW_TAG_subroutine_type -DW_TAG_typedef -DW_TAG_union_type -DW_TAG_unspecified_parameters -DW_TAG_variant -DW_TAG_common_block -DW_TAG_common_inclusion -DW_TAG_inheritance -DW_TAG_inlined_subroutine -DW_TAG_module -DW_TAG_ptr_to_member_type -DW_TAG_set_type -DW_TAG_subrange_type -DW_TAG_with_stmt -DW_TAG_access_declaration -DW_TAG_base_type -DW_TAG_catch_block -DW_TAG_const_type -DW_TAG_constant -DW_TAG_enumerator -DW_TAG_file_type -DW_TAG_friend -DW_TAG_namelist -DW_TAG_namelist_item -DW_TAG_packed_type -DW_TAG_subprogram -DW_TAG_template_type_parameter -DW_TAG_template_value_parameter -DW_TAG_thrown_type -DW_TAG_try_block -DW_TAG_variant_part -DW_TAG_variable -DW_TAG_volatile_type -DW_TAG_dwarf_procedure -DW_TAG_restrict_type -DW_TAG_interface_type -DW_TAG_namespace -DW_TAG_imported_module -DW_TAG_unspecified_type -DW_TAG_partial_unit -DW_TAG_imported_unit -DW_TAG_condition -DW_TAG_shared_type -DW_TAG_type_unit -DW_TAG_rvalue_reference_type -DW_TAG_template_alias -DW_TAG_MIPS_loop -DW_TAG_format_label -DW_TAG_function_template -DW_TAG_class_template -DW_TAG_GNU_template_template_param -DW_TAG_GNU_template_parameter_pack -DW_TAG_GNU_formal_parameter_pack -DW_TAG_lo_user -DW_TAG_APPLE_property -DW_TAG_hi_user -DW_CHILDREN_no -DW_CHILDREN_yes -DW_AT_sibling -DW_AT_location -DW_AT_name -DW_AT_ordering -DW_AT_byte_size -DW_AT_bit_offset -DW_AT_bit_size -DW_AT_stmt_list -DW_AT_low_pc -DW_AT_high_pc -DW_AT_language +DW_TAG_reference_type +DW_TAG_compile_unit +DW_TAG_string_type +DW_TAG_structure_type +DW_TAG_subroutine_type +DW_TAG_typedef +DW_TAG_union_type +DW_TAG_unspecified_parameters +DW_TAG_variant +DW_TAG_common_block +DW_TAG_common_inclusion +DW_TAG_inheritance +DW_TAG_inlined_subroutine +DW_TAG_module +DW_TAG_ptr_to_member_type +DW_TAG_set_type +DW_TAG_subrange_type +DW_TAG_with_stmt +DW_TAG_access_declaration +DW_TAG_base_type +DW_TAG_catch_block +DW_TAG_const_type +DW_TAG_constant +DW_TAG_enumerator +DW_TAG_file_type +DW_TAG_friend +DW_TAG_namelist +DW_TAG_namelist_item +DW_TAG_packed_type +DW_TAG_subprogram +DW_TAG_template_type_parameter +DW_TAG_template_value_parameter +DW_TAG_thrown_type +DW_TAG_try_block +DW_TAG_variant_part +DW_TAG_variable +DW_TAG_volatile_type +DW_TAG_dwarf_procedure +DW_TAG_restrict_type +DW_TAG_interface_type +DW_TAG_namespace +DW_TAG_imported_module +DW_TAG_unspecified_type +DW_TAG_partial_unit +DW_TAG_imported_unit +DW_TAG_condition +DW_TAG_shared_type +DW_TAG_type_unit +DW_TAG_rvalue_reference_type +DW_TAG_template_alias +DW_TAG_MIPS_loop +DW_TAG_format_label +DW_TAG_function_template +DW_TAG_class_template +DW_TAG_GNU_template_template_param +DW_TAG_GNU_template_parameter_pack +DW_TAG_GNU_formal_parameter_pack +DW_TAG_lo_user +DW_TAG_APPLE_property +DW_TAG_hi_user +DW_CHILDREN_no +DW_CHILDREN_yes +DW_AT_sibling +DW_AT_location +DW_AT_name +DW_AT_ordering +DW_AT_byte_size +DW_AT_bit_offset +DW_AT_bit_size +DW_AT_stmt_list +DW_AT_low_pc +DW_AT_high_pc +DW_AT_language DW_AT_discr -DW_AT_discr_value -DW_AT_visibility -DW_AT_import -DW_AT_string_length -DW_AT_common_reference -DW_AT_comp_dir -DW_AT_const_value -DW_AT_containing_type -DW_AT_default_value -DW_AT_inline -DW_AT_is_optional -DW_AT_lower_bound -DW_AT_producer -DW_AT_prototyped -DW_AT_return_addr -DW_AT_start_scope -DW_AT_bit_stride -DW_AT_upper_bound -DW_AT_abstract_origin -DW_AT_accessibility -DW_AT_address_class -DW_AT_artificial -DW_AT_base_types -DW_AT_calling_convention -DW_AT_count -DW_AT_data_member_location -DW_AT_decl_column -DW_AT_decl_file -DW_AT_decl_line -DW_AT_declaration -DW_AT_discr_list -DW_AT_encoding -DW_AT_external -DW_AT_frame_base -DW_AT_friend -DW_AT_identifier_case -DW_AT_macro_info -DW_AT_namelist_item -DW_AT_priority -DW_AT_segment -DW_AT_specification -DW_AT_static_link -DW_AT_type -DW_AT_use_location -DW_AT_variable_parameter -DW_AT_virtuality -DW_AT_vtable_elem_location -DW_AT_allocated -DW_AT_associated -DW_AT_data_location -DW_AT_byte_stride -DW_AT_entry_pc -DW_AT_use_UTF8 -DW_AT_extension -DW_AT_ranges -DW_AT_trampoline -DW_AT_call_column -DW_AT_call_file -DW_AT_call_line -DW_AT_description -DW_AT_binary_scale -DW_AT_decimal_scale -DW_AT_small -DW_AT_decimal_sign -DW_AT_digit_count -DW_AT_picture_string -DW_AT_mutable -DW_AT_threads_scaled -DW_AT_explicit -DW_AT_object_pointer -DW_AT_endianity -DW_AT_elemental -DW_AT_pure -DW_AT_recursive -DW_AT_signature -DW_AT_main_subprogram -DW_AT_data_bit_offset -DW_AT_const_expr -DW_AT_enum_class -DW_AT_linkage_name -DW_AT_lo_user -DW_AT_hi_user -DW_AT_MIPS_loop_begin -DW_AT_MIPS_tail_loop_begin -DW_AT_MIPS_epilog_begin -DW_AT_MIPS_loop_unroll_factor -DW_AT_MIPS_software_pipeline_depth -DW_AT_MIPS_linkage_name -DW_AT_MIPS_stride -DW_AT_MIPS_abstract_name -DW_AT_MIPS_clone_origin -DW_AT_MIPS_has_inlines -DW_AT_MIPS_stride_byte -DW_AT_MIPS_stride_elem -DW_AT_MIPS_ptr_dopetype -DW_AT_MIPS_allocatable_dopetype -DW_AT_MIPS_assumed_shape_dopetype -DW_AT_MIPS_assumed_size -DW_AT_sf_names -DW_AT_src_info -DW_AT_mac_info -DW_AT_src_coords -DW_AT_body_begin -DW_AT_body_end +DW_AT_discr_value +DW_AT_visibility +DW_AT_import +DW_AT_string_length +DW_AT_common_reference +DW_AT_comp_dir +DW_AT_const_value +DW_AT_containing_type +DW_AT_default_value +DW_AT_inline +DW_AT_is_optional +DW_AT_lower_bound +DW_AT_producer +DW_AT_prototyped +DW_AT_return_addr +DW_AT_start_scope +DW_AT_bit_stride +DW_AT_upper_bound +DW_AT_abstract_origin +DW_AT_accessibility +DW_AT_address_class +DW_AT_artificial +DW_AT_base_types +DW_AT_calling_convention +DW_AT_count +DW_AT_data_member_location +DW_AT_decl_column +DW_AT_decl_file +DW_AT_decl_line +DW_AT_declaration +DW_AT_discr_list +DW_AT_encoding +DW_AT_external +DW_AT_frame_base +DW_AT_friend +DW_AT_identifier_case +DW_AT_macro_info +DW_AT_namelist_item +DW_AT_priority +DW_AT_segment +DW_AT_specification +DW_AT_static_link +DW_AT_type +DW_AT_use_location +DW_AT_variable_parameter +DW_AT_virtuality +DW_AT_vtable_elem_location +DW_AT_allocated +DW_AT_associated +DW_AT_data_location +DW_AT_byte_stride +DW_AT_entry_pc +DW_AT_use_UTF8 +DW_AT_extension +DW_AT_ranges +DW_AT_trampoline +DW_AT_call_column +DW_AT_call_file +DW_AT_call_line +DW_AT_description +DW_AT_binary_scale +DW_AT_decimal_scale +DW_AT_small +DW_AT_decimal_sign +DW_AT_digit_count +DW_AT_picture_string +DW_AT_mutable +DW_AT_threads_scaled +DW_AT_explicit +DW_AT_object_pointer +DW_AT_endianity +DW_AT_elemental +DW_AT_pure +DW_AT_recursive +DW_AT_signature +DW_AT_main_subprogram +DW_AT_data_bit_offset +DW_AT_const_expr +DW_AT_enum_class +DW_AT_linkage_name +DW_AT_lo_user +DW_AT_hi_user +DW_AT_MIPS_loop_begin +DW_AT_MIPS_tail_loop_begin +DW_AT_MIPS_epilog_begin +DW_AT_MIPS_loop_unroll_factor +DW_AT_MIPS_software_pipeline_depth +DW_AT_MIPS_linkage_name +DW_AT_MIPS_stride +DW_AT_MIPS_abstract_name +DW_AT_MIPS_clone_origin +DW_AT_MIPS_has_inlines +DW_AT_MIPS_stride_byte +DW_AT_MIPS_stride_elem +DW_AT_MIPS_ptr_dopetype +DW_AT_MIPS_allocatable_dopetype +DW_AT_MIPS_assumed_shape_dopetype +DW_AT_MIPS_assumed_size +DW_AT_sf_names +DW_AT_src_info +DW_AT_mac_info +DW_AT_src_coords +DW_AT_body_begin +DW_AT_body_end DW_AT_APPLE_optimized -DW_AT_APPLE_flags -DW_AT_APPLE_isa -DW_AT_APPLE_block -DW_AT_APPLE_major_runtime_vers -DW_AT_APPLE_runtime_class -DW_AT_APPLE_omit_frame_ptr -DW_AT_APPLE_property_name -DW_AT_APPLE_property_getter -DW_AT_APPLE_property_setter -DW_AT_APPLE_property_attribute -DW_AT_APPLE_objc_complete_type -DW_AT_APPLE_property -DW_FORM_addr -DW_FORM_block2 -DW_FORM_block4 -DW_FORM_data2 -DW_FORM_data4 -DW_FORM_data8 -DW_FORM_string -DW_FORM_block -DW_FORM_block1 -DW_FORM_data1 -DW_FORM_flag -DW_FORM_sdata -DW_FORM_strp -DW_FORM_udata -DW_FORM_ref_addr -DW_FORM_ref1 -DW_FORM_ref2 -DW_FORM_ref4 -DW_FORM_ref8 -DW_FORM_ref_udata -DW_FORM_indirect -DW_FORM_sec_offset -DW_FORM_exprloc -DW_FORM_flag_present +DW_AT_APPLE_flags +DW_AT_APPLE_isa +DW_AT_APPLE_block +DW_AT_APPLE_major_runtime_vers +DW_AT_APPLE_runtime_class +DW_AT_APPLE_omit_frame_ptr +DW_AT_APPLE_property_name +DW_AT_APPLE_property_getter +DW_AT_APPLE_property_setter +DW_AT_APPLE_property_attribute +DW_AT_APPLE_objc_complete_type +DW_AT_APPLE_property +DW_FORM_addr +DW_FORM_block2 +DW_FORM_block4 +DW_FORM_data2 +DW_FORM_data4 +DW_FORM_data8 +DW_FORM_string +DW_FORM_block +DW_FORM_block1 +DW_FORM_data1 +DW_FORM_flag +DW_FORM_sdata +DW_FORM_strp +DW_FORM_udata +DW_FORM_ref_addr +DW_FORM_ref1 +DW_FORM_ref2 +DW_FORM_ref4 +DW_FORM_ref8 +DW_FORM_ref_udata +DW_FORM_indirect +DW_FORM_sec_offset +DW_FORM_exprloc +DW_FORM_flag_present DW_FORM_ref_sig8 -DW_OP_addr -DW_OP_deref -DW_OP_const1u -DW_OP_const1s -DW_OP_const2u -DW_OP_const2s -DW_OP_const4u -DW_OP_const4s -DW_OP_const8u -DW_OP_const8s -DW_OP_constu -DW_OP_consts -DW_OP_dup -DW_OP_drop -DW_OP_over -DW_OP_pick -DW_OP_swap -DW_OP_rot -DW_OP_xderef -DW_OP_abs -DW_OP_and -DW_OP_div -DW_OP_minus -DW_OP_mod -DW_OP_mul -DW_OP_neg -DW_OP_not -DW_OP_or -DW_OP_plus -DW_OP_plus_uconst -DW_OP_shl -DW_OP_shr -DW_OP_shra -DW_OP_xor -DW_OP_skip -DW_OP_bra -DW_OP_eq -DW_OP_ge -DW_OP_gt -DW_OP_le -DW_OP_lt -DW_OP_ne -DW_OP_lit0 -DW_OP_lit1 -DW_OP_lit2 -DW_OP_lit3 -DW_OP_lit4 -DW_OP_lit5 -DW_OP_lit6 -DW_OP_lit7 -DW_OP_lit8 -DW_OP_lit9 -DW_OP_lit10 -DW_OP_lit11 -DW_OP_lit12 -DW_OP_lit13 -DW_OP_lit14 -DW_OP_lit15 -DW_OP_lit16 -DW_OP_lit17 -DW_OP_lit18 -DW_OP_lit19 -DW_OP_lit20 -DW_OP_lit21 -DW_OP_lit22 -DW_OP_lit23 -DW_OP_lit24 -DW_OP_lit25 -DW_OP_lit26 -DW_OP_lit27 -DW_OP_lit28 -DW_OP_lit29 -DW_OP_lit30 -DW_OP_lit31 -DW_OP_reg0 -DW_OP_reg1 -DW_OP_reg2 -DW_OP_reg3 -DW_OP_reg4 -DW_OP_reg5 -DW_OP_reg6 -DW_OP_reg7 -DW_OP_reg8 -DW_OP_reg9 -DW_OP_reg10 -DW_OP_reg11 -DW_OP_reg12 -DW_OP_reg13 -DW_OP_reg14 -DW_OP_reg15 -DW_OP_reg16 -DW_OP_reg17 -DW_OP_reg18 -DW_OP_reg19 -DW_OP_reg20 -DW_OP_reg21 -DW_OP_reg22 -DW_OP_reg23 -DW_OP_reg24 -DW_OP_reg25 -DW_OP_reg26 -DW_OP_reg27 -DW_OP_reg28 -DW_OP_reg29 -DW_OP_reg30 -DW_OP_reg31 -DW_OP_breg0 -DW_OP_breg1 -DW_OP_breg2 -DW_OP_breg3 -DW_OP_breg4 -DW_OP_breg5 -DW_OP_breg6 -DW_OP_breg7 -DW_OP_breg8 -DW_OP_breg9 -DW_OP_breg10 -DW_OP_breg11 -DW_OP_breg12 -DW_OP_breg13 -DW_OP_breg14 -DW_OP_breg15 -DW_OP_breg16 -DW_OP_breg17 -DW_OP_breg18 -DW_OP_breg19 -DW_OP_breg20 -DW_OP_breg21 -DW_OP_breg22 -DW_OP_breg23 -DW_OP_breg24 -DW_OP_breg25 -DW_OP_breg26 -DW_OP_breg27 -DW_OP_breg28 -DW_OP_breg29 -DW_OP_breg30 -DW_OP_breg31 -DW_OP_regx -DW_OP_fbreg -DW_OP_bregx -DW_OP_piece -DW_OP_deref_size -DW_OP_xderef_size -DW_OP_nop -DW_OP_push_object_address -DW_OP_call2 -DW_OP_call4 -DW_OP_call_ref -DW_OP_form_tls_address -DW_OP_call_frame_cfa -DW_OP_bit_piece -DW_OP_implicit_value -DW_OP_stack_value -DW_OP_lo_user +DW_OP_addr +DW_OP_deref +DW_OP_const1u +DW_OP_const1s +DW_OP_const2u +DW_OP_const2s +DW_OP_const4u +DW_OP_const4s +DW_OP_const8u +DW_OP_const8s +DW_OP_constu +DW_OP_consts +DW_OP_dup +DW_OP_drop +DW_OP_over +DW_OP_pick +DW_OP_swap +DW_OP_rot +DW_OP_xderef +DW_OP_abs +DW_OP_and +DW_OP_div +DW_OP_minus +DW_OP_mod +DW_OP_mul +DW_OP_neg +DW_OP_not +DW_OP_or +DW_OP_plus +DW_OP_plus_uconst +DW_OP_shl +DW_OP_shr +DW_OP_shra +DW_OP_xor +DW_OP_skip +DW_OP_bra +DW_OP_eq +DW_OP_ge +DW_OP_gt +DW_OP_le +DW_OP_lt +DW_OP_ne +DW_OP_lit0 +DW_OP_lit1 +DW_OP_lit2 +DW_OP_lit3 +DW_OP_lit4 +DW_OP_lit5 +DW_OP_lit6 +DW_OP_lit7 +DW_OP_lit8 +DW_OP_lit9 +DW_OP_lit10 +DW_OP_lit11 +DW_OP_lit12 +DW_OP_lit13 +DW_OP_lit14 +DW_OP_lit15 +DW_OP_lit16 +DW_OP_lit17 +DW_OP_lit18 +DW_OP_lit19 +DW_OP_lit20 +DW_OP_lit21 +DW_OP_lit22 +DW_OP_lit23 +DW_OP_lit24 +DW_OP_lit25 +DW_OP_lit26 +DW_OP_lit27 +DW_OP_lit28 +DW_OP_lit29 +DW_OP_lit30 +DW_OP_lit31 +DW_OP_reg0 +DW_OP_reg1 +DW_OP_reg2 +DW_OP_reg3 +DW_OP_reg4 +DW_OP_reg5 +DW_OP_reg6 +DW_OP_reg7 +DW_OP_reg8 +DW_OP_reg9 +DW_OP_reg10 +DW_OP_reg11 +DW_OP_reg12 +DW_OP_reg13 +DW_OP_reg14 +DW_OP_reg15 +DW_OP_reg16 +DW_OP_reg17 +DW_OP_reg18 +DW_OP_reg19 +DW_OP_reg20 +DW_OP_reg21 +DW_OP_reg22 +DW_OP_reg23 +DW_OP_reg24 +DW_OP_reg25 +DW_OP_reg26 +DW_OP_reg27 +DW_OP_reg28 +DW_OP_reg29 +DW_OP_reg30 +DW_OP_reg31 +DW_OP_breg0 +DW_OP_breg1 +DW_OP_breg2 +DW_OP_breg3 +DW_OP_breg4 +DW_OP_breg5 +DW_OP_breg6 +DW_OP_breg7 +DW_OP_breg8 +DW_OP_breg9 +DW_OP_breg10 +DW_OP_breg11 +DW_OP_breg12 +DW_OP_breg13 +DW_OP_breg14 +DW_OP_breg15 +DW_OP_breg16 +DW_OP_breg17 +DW_OP_breg18 +DW_OP_breg19 +DW_OP_breg20 +DW_OP_breg21 +DW_OP_breg22 +DW_OP_breg23 +DW_OP_breg24 +DW_OP_breg25 +DW_OP_breg26 +DW_OP_breg27 +DW_OP_breg28 +DW_OP_breg29 +DW_OP_breg30 +DW_OP_breg31 +DW_OP_regx +DW_OP_fbreg +DW_OP_bregx +DW_OP_piece +DW_OP_deref_size +DW_OP_xderef_size +DW_OP_nop +DW_OP_push_object_address +DW_OP_call2 +DW_OP_call4 +DW_OP_call_ref +DW_OP_form_tls_address +DW_OP_call_frame_cfa +DW_OP_bit_piece +DW_OP_implicit_value +DW_OP_stack_value +DW_OP_lo_user DW_OP_hi_user -DW_ATE_address -DW_ATE_boolean -DW_ATE_complex_float -DW_ATE_float -DW_ATE_signed -DW_ATE_signed_char -DW_ATE_unsigned -DW_ATE_unsigned_char -DW_ATE_imaginary_float -DW_ATE_packed_decimal -DW_ATE_numeric_string -DW_ATE_edited -DW_ATE_signed_fixed -DW_ATE_unsigned_fixed -DW_ATE_decimal_float -DW_ATE_UTF -DW_ATE_lo_user -DW_ATE_hi_user -DW_DS_unsigned -DW_DS_leading_overpunch -DW_DS_trailing_overpunch -DW_DS_leading_separate -DW_DS_trailing_separate -DW_END_default -DW_END_big -DW_END_little -DW_END_lo_user -DW_END_hi_user -DW_ACCESS_public -DW_ACCESS_protected -DW_ACCESS_private -DW_VIS_local -DW_VIS_exported -DW_VIS_qualified -DW_VIRTUALITY_none -DW_VIRTUALITY_virtual -DW_VIRTUALITY_pure_virtual -DW_LANG_C89 -DW_LANG_C -DW_LANG_Ada83 -DW_LANG_C_plus_plus -DW_LANG_Cobol74 -DW_LANG_Cobol85 -DW_LANG_Fortran77 -DW_LANG_Fortran90 -DW_LANG_Pascal83 -DW_LANG_Modula2 -DW_LANG_Java -DW_LANG_C99 -DW_LANG_Ada95 -DW_LANG_Fortran95 -DW_LANG_PLI -DW_LANG_ObjC -DW_LANG_ObjC_plus_plus -DW_LANG_UPC -DW_LANG_D -DW_LANG_Python -DW_LANG_lo_user -DW_LANG_Mips_Assembler -DW_LANG_hi_user -DW_ID_case_sensitive -DW_ID_up_case -DW_ID_down_case -DW_ID_case_insensitive -DW_CC_normal -DW_CC_program -DW_CC_nocall -DW_CC_lo_user -DW_CC_hi_user -DW_INL_not_inlined -DW_INL_inlined -DW_INL_declared_not_inlined -DW_INL_declared_inlined -DW_ORD_row_major -DW_ORD_col_major -DW_DSC_label -DW_DSC_range -DW_LNS_extended_op -DW_LNS_copy -DW_LNS_advance_pc -DW_LNS_advance_line -DW_LNS_set_file -DW_LNS_set_column -DW_LNS_negate_stmt -DW_LNS_set_basic_block -DW_LNS_const_add_pc -DW_LNS_fixed_advance_pc -DW_LNS_set_prologue_end -DW_LNS_set_epilogue_begin -DW_LNS_set_isa -DW_LNE_end_sequence -DW_LNE_set_address -DW_LNE_define_file -DW_LNE_set_discriminator -DW_LNE_lo_user -DW_LNE_hi_user -DW_MACINFO_define -DW_MACINFO_undef -DW_MACINFO_start_file -DW_MACINFO_end_file -DW_MACINFO_vendor_ext -DW_CFA_extended -DW_CFA_nop -DW_CFA_advance_loc -DW_CFA_offset -DW_CFA_restore -DW_CFA_set_loc -DW_CFA_advance_loc1 -DW_CFA_advance_loc2 -DW_CFA_advance_loc4 -DW_CFA_offset_extended -DW_CFA_restore_extended -DW_CFA_undefined -DW_CFA_same_value -DW_CFA_register -DW_CFA_remember_state -DW_CFA_restore_state -DW_CFA_def_cfa -DW_CFA_def_cfa_register -DW_CFA_def_cfa_offset -DW_CFA_def_cfa_expression -DW_CFA_expression -DW_CFA_offset_extended_sf -DW_CFA_def_cfa_sf -DW_CFA_def_cfa_offset_sf -DW_CFA_val_offset -DW_CFA_val_offset_sf -DW_CFA_val_expression -DW_CFA_MIPS_advance_loc8 -DW_CFA_GNU_window_save -DW_CFA_GNU_args_size -DW_CFA_lo_user -DW_CFA_hi_user -DW_EH_PE_absptr -DW_EH_PE_omit +DW_ATE_address +DW_ATE_boolean +DW_ATE_complex_float +DW_ATE_float +DW_ATE_signed +DW_ATE_signed_char +DW_ATE_unsigned +DW_ATE_unsigned_char +DW_ATE_imaginary_float +DW_ATE_packed_decimal +DW_ATE_numeric_string +DW_ATE_edited +DW_ATE_signed_fixed +DW_ATE_unsigned_fixed +DW_ATE_decimal_float +DW_ATE_UTF +DW_ATE_lo_user +DW_ATE_hi_user +DW_DS_unsigned +DW_DS_leading_overpunch +DW_DS_trailing_overpunch +DW_DS_leading_separate +DW_DS_trailing_separate +DW_END_default +DW_END_big +DW_END_little +DW_END_lo_user +DW_END_hi_user +DW_ACCESS_public +DW_ACCESS_protected +DW_ACCESS_private +DW_VIS_local +DW_VIS_exported +DW_VIS_qualified +DW_VIRTUALITY_none +DW_VIRTUALITY_virtual +DW_VIRTUALITY_pure_virtual +DW_LANG_C89 +DW_LANG_C +DW_LANG_Ada83 +DW_LANG_C_plus_plus +DW_LANG_Cobol74 +DW_LANG_Cobol85 +DW_LANG_Fortran77 +DW_LANG_Fortran90 +DW_LANG_Pascal83 +DW_LANG_Modula2 +DW_LANG_Java +DW_LANG_C99 +DW_LANG_Ada95 +DW_LANG_Fortran95 +DW_LANG_PLI +DW_LANG_ObjC +DW_LANG_ObjC_plus_plus +DW_LANG_UPC +DW_LANG_D +DW_LANG_Python +DW_LANG_lo_user +DW_LANG_Mips_Assembler +DW_LANG_hi_user +DW_ID_case_sensitive +DW_ID_up_case +DW_ID_down_case +DW_ID_case_insensitive +DW_CC_normal +DW_CC_program +DW_CC_nocall +DW_CC_lo_user +DW_CC_hi_user +DW_INL_not_inlined +DW_INL_inlined +DW_INL_declared_not_inlined +DW_INL_declared_inlined +DW_ORD_row_major +DW_ORD_col_major +DW_DSC_label +DW_DSC_range +DW_LNS_extended_op +DW_LNS_copy +DW_LNS_advance_pc +DW_LNS_advance_line +DW_LNS_set_file +DW_LNS_set_column +DW_LNS_negate_stmt +DW_LNS_set_basic_block +DW_LNS_const_add_pc +DW_LNS_fixed_advance_pc +DW_LNS_set_prologue_end +DW_LNS_set_epilogue_begin +DW_LNS_set_isa +DW_LNE_end_sequence +DW_LNE_set_address +DW_LNE_define_file +DW_LNE_set_discriminator +DW_LNE_lo_user +DW_LNE_hi_user +DW_MACINFO_define +DW_MACINFO_undef +DW_MACINFO_start_file +DW_MACINFO_end_file +DW_MACINFO_vendor_ext +DW_CFA_extended +DW_CFA_nop +DW_CFA_advance_loc +DW_CFA_offset +DW_CFA_restore +DW_CFA_set_loc +DW_CFA_advance_loc1 +DW_CFA_advance_loc2 +DW_CFA_advance_loc4 +DW_CFA_offset_extended +DW_CFA_restore_extended +DW_CFA_undefined +DW_CFA_same_value +DW_CFA_register +DW_CFA_remember_state +DW_CFA_restore_state +DW_CFA_def_cfa +DW_CFA_def_cfa_register +DW_CFA_def_cfa_offset +DW_CFA_def_cfa_expression +DW_CFA_expression +DW_CFA_offset_extended_sf +DW_CFA_def_cfa_sf +DW_CFA_def_cfa_offset_sf +DW_CFA_val_offset +DW_CFA_val_offset_sf +DW_CFA_val_expression +DW_CFA_MIPS_advance_loc8 +DW_CFA_GNU_window_save +DW_CFA_GNU_args_size +DW_CFA_lo_user +DW_CFA_hi_user +DW_EH_PE_absptr +DW_EH_PE_omit DW_EH_PE_uleb128 -DW_EH_PE_udata2 -DW_EH_PE_udata4 -DW_EH_PE_udata8 -DW_EH_PE_sleb128 -DW_EH_PE_sdata2 -DW_EH_PE_sdata4 -DW_EH_PE_sdata8 -DW_EH_PE_signed -DW_EH_PE_pcrel -DW_EH_PE_textrel -DW_EH_PE_datarel -DW_EH_PE_funcrel -DW_EH_PE_aligned -DW_EH_PE_indirect -DW_APPLE_PROPERTY_readonly -DW_APPLE_PROPERTY_readwrite -DW_APPLE_PROPERTY_assign -DW_APPLE_PROPERTY_retain -DW_APPLE_PROPERTY_copy -DW_APPLE_PROPERTY_nonatomic +DW_EH_PE_udata2 +DW_EH_PE_udata4 +DW_EH_PE_udata8 +DW_EH_PE_sleb128 +DW_EH_PE_sdata2 +DW_EH_PE_sdata4 +DW_EH_PE_sdata8 +DW_EH_PE_signed +DW_EH_PE_pcrel +DW_EH_PE_textrel +DW_EH_PE_datarel +DW_EH_PE_funcrel +DW_EH_PE_aligned +DW_EH_PE_indirect +DW_APPLE_PROPERTY_readonly +DW_APPLE_PROPERTY_readwrite +DW_APPLE_PROPERTY_assign +DW_APPLE_PROPERTY_retain +DW_APPLE_PROPERTY_copy +DW_APPLE_PROPERTY_nonatomic ''') ### The following enums are not available in LLVM 3.2 # DW_AT_GNU_dwo_name -# DW_AT_GNU_vector +# DW_AT_GNU_vector # DW_AT_GNU_template_name # DW_AT_GNU_dwo_id -# DW_AT_GNU_ranges_base -# DW_AT_GNU_addr_base -# DW_AT_GNU_pubnames -# DW_AT_GNU_pubtypes -# DW_FORM_GNU_addr_index +# DW_AT_GNU_ranges_base +# DW_AT_GNU_addr_base +# DW_AT_GNU_pubnames +# DW_AT_GNU_pubtypes +# DW_FORM_GNU_addr_index # DW_FORM_GNU_str_index -# DW_OP_GNU_addr_index +# DW_OP_GNU_addr_index # DW_OP_GNU_const_index diff --git a/llvmpy/src/Support/DynamicLibrary.py b/llvmpy/src/Support/DynamicLibrary.py index e3b1d37..7dce97a 100644 --- a/llvmpy/src/Support/DynamicLibrary.py +++ b/llvmpy/src/Support/DynamicLibrary.py @@ -26,10 +26,3 @@ class DynamicLibrary: cast(str, StringRef), # symbolName cast(int, VoidPtr), # address ) - - getPermanentLibrary = CustomStaticMethod( - 'DynamicLibrary_getPermanentLibrary', - PyObjectPtr, - cast(str, ConstCharPtr), # filename - PyObjectPtr, # std::string * errmsg = 0 - ).require_only(1) diff --git a/llvmpy/src/Support/Host.py b/llvmpy/src/Support/Host.py index f7d361b..cd063e8 100644 --- a/llvmpy/src/Support/Host.py +++ b/llvmpy/src/Support/Host.py @@ -17,7 +17,7 @@ if LLVM_VERSION >= (3, 3): cast(Bool, bool)) else: - + isLittleEndianHost = sys.Function('isLittleEndianHost', cast(Bool, bool)) diff --git a/llvmpy/src/Support/StringRefMemoryObject.py b/llvmpy/src/Support/StringRefMemoryObject.py deleted file mode 100644 index a5ba0c1..0000000 --- a/llvmpy/src/Support/StringRefMemoryObject.py +++ /dev/null @@ -1,32 +0,0 @@ -from binding import * -from ..namespace import llvm -from ..ADT.StringRef import StringRef - -if LLVM_VERSION >= (3, 4): - MemoryObject = llvm.Class() - StringRefMemoryObject = llvm.Class(MemoryObject) - - @MemoryObject - class MemoryObject: - _include_ = "llvm/Support/MemoryObject.h" - - getBase = Method(cast(Uint64, int)) - getExtent = Method(cast(Uint64, int)) - - readBytes = CustomMethod('MemoryObject_readBytes', - PyObjectPtr, - cast(int, Uint64), #address - cast(int, Uint64) #size - ) - @CustomPythonMethod - def readAll(self): - result = self.readBytes(self.getBase(), self.getExtent()) - if not result: - raise Exception("expected readBytes to be successful!") - return result - - @StringRefMemoryObject - class StringRefMemoryObject: - _include_ = "llvm/Support/StringRefMemoryObject.h" - - new = Constructor(cast(bytes, StringRef), cast(int, Uint64)) diff --git a/llvmpy/src/Support/TargetRegistry.py b/llvmpy/src/Support/TargetRegistry.py index 0635e2b..2a445e7 100644 --- a/llvmpy/src/Support/TargetRegistry.py +++ b/llvmpy/src/Support/TargetRegistry.py @@ -12,18 +12,9 @@ from src.Target.TargetMachine import TargetMachine from src.Target.TargetOptions import TargetOptions from src.Support.CodeGen import Reloc, CodeModel, CodeGenOpt -if LLVM_VERSION >= (3, 4): - from src.MC import MCSubtargetInfo - from src.MC import MCDisassembler - from src.MC import MCRegisterInfo - from src.MC import MCAsmInfo - from src.MC import MCInstrInfo - from src.MC import MCInstrAnalysis - from src.MC import MCInstPrinter - @Target class Target: - getNext = Method(const(ownedptr(Target))) + getNext = Method(const(ptr(Target))) getName = Method(cast(StdString, str)) getShortDescription = Method(cast(StdString, str)) @@ -52,35 +43,7 @@ class Target: CodeGenOpt.Level, # = CodeGenOpt.Default ).require_only(4) - if LLVM_VERSION >= (3, 4): - createMCSubtargetInfo = Method(ptr(MCSubtargetInfo), - cast(str, StringRef), #triple - cast(str, StringRef), #cpu - cast(str, StringRef) #features - ) - createMCDisassembler = Method(ptr(MCDisassembler), ref(MCSubtargetInfo)) - - createMCRegInfo = Method(ptr(MCRegisterInfo), - cast(str, StringRef) #Triple - ) - - createMCAsmInfo = Method(ptr(MCAsmInfo), - const(ref(MCRegisterInfo)), #MRI - cast(str, StringRef) #Triple - ) - - createMCInstrInfo = Method(ptr(MCInstrInfo)) - - createMCInstrAnalysis = Method(ptr(MCInstrAnalysis), const(ptr(MCInstrInfo))) - - createMCInstPrinter = Method(ptr(MCInstPrinter), - cast(int, Unsigned), #SyntaxVariant - const(ref(MCAsmInfo)), #MAI - const(ref(MCInstrInfo)), #MII - const(ref(MCRegisterInfo)), #MRI - const(ref(MCSubtargetInfo)) #STI - ) @TargetRegistry class TargetRegistry: printRegisteredTargetsForVersion = StaticMethod() @@ -103,6 +66,3 @@ class TargetRegistry: PyObjectPtr, # const Target* PyObjectPtr, # std::string &Error ) - - targetsList = CustomStaticMethod('TargetRegistry_targets_list', PyObjectPtr) - diff --git a/llvmpy/src/Support/TargetSelect.py b/llvmpy/src/Support/TargetSelect.py index a5fb776..3e638bc 100644 --- a/llvmpy/src/Support/TargetSelect.py +++ b/llvmpy/src/Support/TargetSelect.py @@ -14,13 +14,10 @@ InitializeNativeTargetAsmParser = llvm.Function( InitializeNativeTargetDisassembler = llvm.Function( 'InitializeNativeTargetDisassembler', cast(Bool, bool)) -InitializeAllTargets = llvm.Function('InitializeAllTargets') -InitializeAllTargetInfos = llvm.Function('InitializeAllTargetInfos') -InitializeAllTargetMCs = llvm.Function('InitializeAllTargetMCs') -InitializeAllAsmPrinters = llvm.Function('InitializeAllAsmPrinters') -InitializeAllDisassemblers = llvm.Function('InitializeAllDisassemblers') -InitializeAllAsmParsers = llvm.Function('InitializeAllAsmParsers') - +#InitializeAllTargets = llvm.Function('InitializeAllTargets') +#InitializeAllTargetInfos = llvm.Function('InitializeAllTargetInfos') +#InitializeAllTargetMCs = llvm.Function('InitializeAllTargetMCs') +#InitializeAllAsmPrinters = llvm.Function('InitializeAllAsmPrinters') for target in TARGETS_BUILT: decls = 'Target', 'TargetInfo', 'TargetMC', 'AsmPrinter' diff --git a/llvmpy/src/Target/TargetMachine.py b/llvmpy/src/Target/TargetMachine.py index 1b52359..84c0d5d 100644 --- a/llvmpy/src/Target/TargetMachine.py +++ b/llvmpy/src/Target/TargetMachine.py @@ -8,11 +8,6 @@ from src.ADT.StringRef import StringRef from src.Support.CodeGen import CodeModel, TLSModel, CodeGenOpt, Reloc from src.GlobalValue import GlobalValue from src.DataLayout import DataLayout -if LLVM_VERSION >= (3, 4): - from src.MC import MCAsmInfo, \ - TargetInstrInfo, \ - TargetSubtargetInfo, \ - TargetRegisterInfo if LLVM_VERSION < (3, 3): from src.TargetTransformInfo import (ScalarTargetTransformInfo, @@ -53,9 +48,6 @@ class TargetMachine: getVectorTargetTransformInfo = Method(const( ownedptr(VectorTargetTransformInfo))) - else: - addAnalysisPasses = Method(Void, ref(PassManagerBase)) - addPassesToEmitFile = Method(cast(bool, Bool), ref(PassManagerBase), ref(formatted_raw_ostream), @@ -63,12 +55,4 @@ class TargetMachine: cast(bool, Bool) ).require_only(3) - if LLVM_VERSION >= (3, 4): - getSubtargetImpl = Method(const(ownedptr(TargetSubtargetInfo))) - - getMCAsmInfo = Method(const(ownedptr(MCAsmInfo))) - - getInstrInfo = Method(const(ownedptr(TargetInstrInfo))) - - getRegisterInfo = Method(const(ownedptr(TargetRegisterInfo))) diff --git a/llvmpy/src/Transforms/PassManagerBuilder.py b/llvmpy/src/Transforms/PassManagerBuilder.py index a654578..146d409 100644 --- a/llvmpy/src/Transforms/PassManagerBuilder.py +++ b/llvmpy/src/Transforms/PassManagerBuilder.py @@ -33,9 +33,7 @@ class PassManagerBuilder: return Attr(getter=cast(Bool, bool), setter=cast(bool, Bool)) - if LLVM_VERSION <= (3, 3): - DisableSimplifyLibCalls = _attr_bool() - + DisableSimplifyLibCalls = _attr_bool() DisableUnitAtATime = _attr_bool() DisableUnrollLoops = _attr_bool() if LLVM_VERSION >= (3, 3): diff --git a/llvmpy/src/Transforms/Utils/BasicBlockUtils.py b/llvmpy/src/Transforms/Utils/BasicBlockUtils.py index 8217f2e..8a571c2 100644 --- a/llvmpy/src/Transforms/Utils/BasicBlockUtils.py +++ b/llvmpy/src/Transforms/Utils/BasicBlockUtils.py @@ -13,4 +13,4 @@ SplitBlockAndInsertIfThen = llvm.Function('SplitBlockAndInsertIfThen', ReplaceInstWithInst = llvm.Function('ReplaceInstWithInst', Void, ptr(Instruction), # from - ptr(Instruction)) # to + ptr(Instruction)) # to \ No newline at end of file diff --git a/llvmpy/src/__init__.py b/llvmpy/src/__init__.py index 8ebb465..69b6609 100644 --- a/llvmpy/src/__init__.py +++ b/llvmpy/src/__init__.py @@ -1,7 +1,4 @@ import os.path -from binding import LLVM_VERSION - -above_33 = ("MC") def _init(root=__name__, file=__file__): base = os.path.dirname(file) @@ -12,10 +9,6 @@ def _init(root=__name__, file=__file__): is_python_module = is_directory and not fname.startswith('__') if (is_python_module or is_python_script) and not is_init_script: print(fname) - if fname in above_33 and LLVM_VERSION <= (3, 3): - print("skip %s because llvm version is not above 3.3" % fname) - continue - modname = os.path.basename(fname).rsplit('.', 1)[0] #importlib.import_module('.' + modname, __name__) __import__('.'.join([root, modname])) diff --git a/setup.py b/setup.py index 08d59b6..e94a258 100644 --- a/setup.py +++ b/setup.py @@ -63,7 +63,7 @@ def auto_intrinsic_gen(incdir): print("Generate intrinsic IDs") from tools import intrgen - if llvm_version.startswith('3.3') or llvm_version.startswith('3.4'): + if llvm_version.startswith('3.3'): path = "%s/llvm/IR/Intrinsics.gen" % incdir else: path = "%s/llvm/Intrinsics.gen" % incdir @@ -128,7 +128,7 @@ else: ['core', 'analysis', 'scalaropts', 'executionengine', 'mcjit', 'jit', 'native', 'interpreter', 'bitreader', 'bitwriter', 'instrumentation', 'ipa', 'ipo', 'transformutils', - 'asmparser', 'linker', 'support', 'vectorize', 'all-targets'] + 'asmparser', 'linker', 'support', 'vectorize'] + extra_components) if sys.platform == 'win32': @@ -184,14 +184,10 @@ setup( maintainer_email = 'llvmpy@continuum.io', url = 'http://www.llvmpy.org/', packages = ['llvm', 'llvm.workaround', - 'llvm.mc', 'llvm_cbuilder', 'llpython', 'llvm_array', - 'llvmpy.api', 'llvmpy.api.llvm', - 'llvm.tests', - 'llvm.utils',], - package_data = {'llvm': ['llrt/*.ll']}, + 'llvmpy.api', 'llvmpy.api.llvm'], py_modules = ['llvmpy', 'llvmpy._capsule', 'llvmpy._api', diff --git a/test/example-disassemble.py b/test/example-disassemble.py deleted file mode 100644 index 75ffb18..0000000 --- a/test/example-disassemble.py +++ /dev/null @@ -1,64 +0,0 @@ -import llvm - -if llvm.version >= (3, 4): - - from llvm.target import TargetMachine - from llvm import mc - from llvm.mc import Disassembler - - llvm.target.initialize_all() - - def print_instructions(dasm, bs, align=None): - branch_properties = [ - 'is_branch', - 'is_cond_branch', - 'is_uncond_branch', - 'is_indirect_branch', - 'is_call', - 'is_return', - 'is_terminator', - 'is_barrier' - ] - - print("print instructions") - for (addr, data, inst) in dasm.decode(bs, 0x4000, align): - - if inst is None: - print("\t0x%x => (bad)" % (addr)) - else: - ops = ", ".join(map(lambda op: repr(op), inst.operands())) - if isinstance(inst, mc.BadInstr): - print("\t0x%x (bad) ops = %s" % (addr, ops)) - else: - print("\t0x%x ops = %s" % (addr, ops)) - - print("\t\topcode = 0x%x, flags = 0x%x, tsflags = 0x%x" % (inst.opcode, inst.flags, inst.ts_flags)) - for line in str(inst).split("\n"): - print("\t\t%-24s %s" % ("".join(map(lambda b: "%02x" % b, data))+":", line.strip())) - - for bp in branch_properties: - print("\t\t%-22s%r" % (bp+":", getattr(inst, bp)() )) - - - x86 = TargetMachine.x86() - print("x86: LE=%s" % x86.is_little_endian()) - print_instructions(Disassembler(x86), "\x01\xc3\xc3\xcc\x90") - - x86_64 = TargetMachine.x86_64() - print("x86-64: LE=%s" % x86_64.is_little_endian()) - print_instructions(Disassembler(x86_64), "\x55\x48\x89\xe8") - - arm = TargetMachine.arm() - print("arm: LE=%s" % arm.is_little_endian()) - code = [ - "\xe9\x2d\x48\x00", - "\xea\x00\x00\x06", - "\xe2\x4d\xd0\x20", - "\xe2\x8d\xb0\x04", - "\xe5\x0b\x00\x20", - "\x03\x30\x22\xe0", #bad instruction to test alignment - "\x73\x20\xef\xe6", #bad instruction to test alignment - "\x18\x00\x1b\xe5", - "\x10\x30\xa0\xe3" - ] - print_instructions(Disassembler(arm), "".join(map(lambda s: s[::-1], code)), 4) diff --git a/test/example-instruction-info.py b/test/example-instruction-info.py deleted file mode 100644 index 7ed79e5..0000000 --- a/test/example-instruction-info.py +++ /dev/null @@ -1,38 +0,0 @@ -import llvm.target -from llvmpy import api, extra - - -def main(): - if llvm.version < (3, 4): - return 0 - - triple = "i386--" - - print("init start") - api.llvm.InitializeAllTargets() - api.llvm.InitializeAllTargetInfos() - api.llvm.InitializeAllTargetMCs() - api.llvm.InitializeAllAsmParsers() - api.llvm.InitializeAllAsmPrinters() - api.llvm.InitializeAllDisassemblers() - print("init done\n") - - tm = llvm.target.TargetMachine.x86() - if not tm: - print("error: failed to lookup target x86 \n") - return 1 - - print("created target machine\n") - - MII = tm.instr_info - if not MII: - print("error: no instruction info for target " + triple + "\n") - return 1 - - print("created instr info\n") - MID = MII.get(919) #int3 - print("INT3(%d): flags=0x%x, tsflags=0x%x\n" % (MID.getOpcode(), MID.getFlags(), MID.TSFlags)) - - return 0 - -exit(main()) diff --git a/test/inlineasm.py b/test/inlineasm.py index 26ee4b5..64a4cbe 100644 --- a/test/inlineasm.py +++ b/test/inlineasm.py @@ -3,7 +3,7 @@ # Import the llvm-py modules. from llvm import * from llvm.core import * -from llvm.tests.support import TestCase +from llvm.test_llvmpy import TestCase import logging import unittest diff --git a/test/loopvectorize.py b/test/loopvectorize.py index dc11cb3..2c12d5b 100644 --- a/test/loopvectorize.py +++ b/test/loopvectorize.py @@ -2,7 +2,7 @@ from llvm.core import * from llvm.passes import * from llvm.ee import * import llvm -from llvm.tests.support import TestCase +from llvm.test_llvmpy import TestCase from os.path import dirname, join as join_path diff --git a/test/metadata.py b/test/metadata.py index 0062bcc..3228159 100644 --- a/test/metadata.py +++ b/test/metadata.py @@ -1,7 +1,7 @@ from __future__ import print_function import unittest -from llvm.tests.support import TestCase +from llvm.test_llvmpy import TestCase from llvm.core import * class TestMetaData(TestCase): diff --git a/test/pass.py b/test/pass.py index a84e7e2..20429d7 100644 --- a/test/pass.py +++ b/test/pass.py @@ -27,7 +27,7 @@ class TestPass(unittest.TestCase): self.assertTrue(tli.description) pm.add(tli) - if llvm.version >= (3, 2) and llvm.version < (3, 3): + if llvm.version >= (3, 2): tti = TargetTransformInfo.new(tm) self.assertFalse(tti.name) self.assertTrue(tti.description) diff --git a/test/target_info.py b/test/target_info.py deleted file mode 100644 index 2242bbb..0000000 --- a/test/target_info.py +++ /dev/null @@ -1,30 +0,0 @@ -from llvmpy.api import llvm; -llvm.InitializeAllTargets() -llvm.InitializeAllTargetInfos() -llvm.InitializeAllTargetMCs() -llvm.InitializeAllAsmPrinters() -llvm.InitializeAllDisassemblers() -llvm.InitializeAllAsmParsers() - -mthds = ( - ("description:", "getShortDescription"), - ("has JIT:", "hasJIT" ), - ("has target machine:", "hasTargetMachine" ), - ("has asm backend:", "hasMCAsmBackend" ), - ("has asm parser:", "hasMCAsmParser" ), - ("has asm printer:", "hasAsmPrinter" ), - ("has disassembler:", "hasMCDisassembler" ), - ("has inst printer:", "hasMCInstPrinter" ), - ("has code emitter:", "hasMCCodeEmitter" ), - ("has object streamer:", "hasMCObjectStreamer"), - ("has asm streamer:", "hasAsmStreamer" ) -) - -for target in llvm.TargetRegistry.targetsList(): - print("target %s" % target.getName()) - fmt = "%3s%-25s%r" - for (desc, mthd) in mthds: - print(fmt % ("", desc, getattr(target, mthd)())) - - print("") - diff --git a/test/tbaa.py b/test/tbaa.py index 4a24de8..ad11081 100644 --- a/test/tbaa.py +++ b/test/tbaa.py @@ -1,6 +1,6 @@ from llvm.core import * from llvm.tbaa import * -from llvm.tests.support import TestCase +from llvm.test_llvmpy import TestCase import unittest class TestTBAABuilder(TestCase): diff --git a/test/test.py b/test/test.py index e23aca3..3b46281 100644 --- a/test/test.py +++ b/test/test.py @@ -7,7 +7,7 @@ import unittest, sys, logging from llvm import * from llvm.core import * -from llvm.tests.support import TestCase +from llvm.test_llvmpy import TestCase class TestModule(TestCase): diff --git a/test/test_debuginfo.py b/test/test_debuginfo.py index d31563c..b6a5d6f 100644 --- a/test/test_debuginfo.py +++ b/test/test_debuginfo.py @@ -4,7 +4,7 @@ import unittest import llvm.ee from llvm.core import * from llvm import _dwarf, debuginfo -from llvm.tests.support import TestCase +from llvm.test_llvmpy import TestCase class TestDebugInfo(TestCase): diff --git a/test/testall.py b/test/testall.py index 8591123..231bca3 100644 --- a/test/testall.py +++ b/test/testall.py @@ -266,8 +266,8 @@ def do_argument(): ft = Type.function(tip, [tip]) f = Function.new(m, ft, 'func') a = f.args[0] - a.add_attribute(ATTR_NEST) - a.remove_attribute(ATTR_NEST) + a.add_attribute(ATTR_ZEXT) + a.remove_attribute(ATTR_ZEXT) a.alignment = 16 a1 = a.alignment @@ -299,9 +299,7 @@ def do_function(): g = list(f.basic_blocks) f.add_attribute(ATTR_NO_RETURN) f.add_attribute(ATTR_ALWAYS_INLINE) - #for some reason removeFnAttr is just gone in 3.3 - if version <= (3, 2): - f.remove_attribute(ATTR_NO_RETURN) + f.remove_attribute(ATTR_NO_RETURN) # LLVM misbehaves: #try: @@ -333,10 +331,9 @@ def do_callorinvokeinstruction(): i = bb.invoke(f, [Constant.int(ti, 10)], b, b) a = i.calling_convention i.calling_convention = CC_FASTCALL - if version <= (3, 2): - i.add_parameter_attribute(0, ATTR_SEXT) - i.remove_parameter_attribute(0, ATTR_SEXT) - i.set_parameter_alignment(0, 8) + i.add_parameter_attribute(0, ATTR_SEXT) + i.remove_parameter_attribute(0, ATTR_SEXT) + i.set_parameter_alignment(0, 8) #tc = i.tail_call #i.tail_call = 1 @@ -566,10 +563,10 @@ def do_executionengine(): ee2 = ExecutionEngine.new(m3, False) m4 = Module.new('d') m5 = Module.new('e') - #ee3 = ExecutionEngine.new(m4, False) - #ee3.add_module(m5) - #x = ee3.remove_module(m5) - #isinstance(x, Module) + ee3 = ExecutionEngine.new(m4, False) + ee3.add_module(m5) + x = ee3.remove_module(m5) + isinstance(x, Module) def do_llvm_ee(): @@ -619,51 +616,6 @@ def do_llvm_passes(): do_passmanager() do_functionpassmanager() -def do_llvm_target(): - print(" Testing module llvm.target") - from llvm import target - - target.initialize_all() - target.print_registered_targets() - target.get_host_cpu_name() - target.get_default_triple() - - tm = TargetMachine.new() - tm = TargetMachine.lookup("arm") - tm = TargetMachine.arm() - tm = TargetMachine.thumb() - tm = TargetMachine.x86() - tm = TargetMachine.x86_64() - tm.target_data - tm.target_name - tm.target_short_description - tm.triple - tm.cpu - tm.feature_string - tm.target - - if llvm.version >= (3, 4): - tm.reg_info - tm.subtarget_info - tm.asm_info - tm.instr_info - tm.instr_analysis - tm.disassembler - tm.is_little_endian() - -def do_llvm_mc(): - if llvm.version < (3, 4): - return - - from llvm import target - from llvm import mc - - target.initialize_all() - tm = TargetMachine.x86() - dasm = mc.Disassembler(tm) - - for (offset, data, instr) in dasm.decode("c3", 0): - pass def main(): print("Testing package llvm") @@ -671,8 +623,7 @@ def main(): do_llvm_core() do_llvm_ee() do_llvm_passes() - do_llvm_target() - do_llvm_mc() + if __name__ == '__main__': main()