Compare commits

..

No commits in common. "master" and "llrt" have entirely different histories.

109 changed files with 2695 additions and 5706 deletions

View file

@ -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

View file

@ -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 *

View file

@ -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::

View file

@ -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

View file

@ -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'

View file

@ -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`

View file

@ -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()

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
from __future__ import absolute_import
import opcode

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
from __future__ import absolute_import
import dis

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
'''Defines a bytecode based LLVM translator for llpython code.
'''

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
from __future__ import absolute_import
import itertools

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
import ctypes

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
import pprint

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
from __future__ import absolute_import
from . import opcode_util

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
from __future__ import absolute_import
import sys

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
import dis

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
from .bytecode_visitor import BytecodeFlowVisitor, BenignBytecodeVisitorMixin

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
import ctypes

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
def doslice (in_string, lower, upper):

View file

@ -1,3 +1,4 @@
#! /usr/bin/env python
# ______________________________________________________________________
import llvm.core as lc

View file

@ -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:

View file

@ -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

View file

@ -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=""):

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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()

1602
llvm/test_llvmpy.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -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()

View file

@ -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')

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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 '<string>'.
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 '<string>'.
m2.id = m.id # Copy the name from `m`
self.assertEqual(str(m2).strip(), asm.strip())
tests.append(TestAsm)
if __name__ == '__main__':
unittest.main()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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 ) ; <i32>:0 [#uses
# }
#
# declare i32 @llvm.bswap.i32(i32) nounwind readnone
#
# define float @mysin(float %x) {
# entry:
# %cosx = call float @llvm.cos.f32( float %x ) ; <float
# %cos2 = call float @llvm.powi.f32( float %cosx, i32 2 )
# %onemc2 = sub float 1.000000e+00, %cos2 ; <float> [#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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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 '<x=%f y=%f z=%d>' % (self.x, self.y, self.z)
class TwoDouble(Structure):
_fields_ = ('x', c_double), ('y', c_double)
def __repr__(self):
return '<x=%f y=%f>' % (self.x, self.y)
class TwoFloat(Structure):
_fields_ = ('x', c_float), ('y', c_float)
def __repr__(self):
return '<x=%f y=%f>' % (self.x, self.y)
class OneByte(Structure):
_fields_ = [('x', c_uint8)]
def __repr__(self):
return '<x=%d>' % (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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

View file

@ -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:])

View file

@ -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__':

View file

@ -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()

View file

@ -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):

View file

@ -1,95 +1,55 @@
#include <Python.h>
#include <structmember.h>
#include <python3adapt.h>
#include <capsulethunk.h>
#include <llvm_binding/capsule_context.h>
#include <llvm_binding/auto_pyobject.h>
#include <string>
#include <sstream>
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 <sizeof(pointer); ++i) {
hash ^= ((unsigned char*)&pointer)[i];
hash = RotR(hash, 11);
}
return hash;
}
static
bool Capsule_eq(PyObject *self, PyObject *other) {
if (PyObject_Type(self) == PyObject_Type(other)) {
CapsuleObject *a = (CapsuleObject*)self;
CapsuleObject *b = (CapsuleObject*)other;
void* pa = PyCapsule_GetPointer(a->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
}

View file

@ -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

View file

@ -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)

View file

@ -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()

View file

@ -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);

View file

@ -256,7 +256,6 @@ template<class Td>
struct typecast {
template<class Ts> static
Td* from(Ts* src) {
// check why this is only used in Python3
return llvm::dyn_cast<Td>(src);
}
@ -266,24 +265,3 @@ struct typecast {
}
};
template<class Td, class Tbase>
struct unwrap_as {
static
Td* from(void* src) {
Tbase* base = static_cast<Tbase*>(src);
return static_cast<Td*>(base);
}
};
template<class Td>
struct cast_to_base {
template<class Ts> static
Td* from(Ts* src){
return static_cast<Td*>(src);
}
template<class Ts> static
const Td* from(const Ts* src){
return static_cast<const Td*>(src);
}
};

View file

@ -1,6 +1,6 @@
#include <Python.h>
#include <llvm/ADT/SmallVector.h>
#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 3
#if LLVM_VERSION_MAJOR >= 3 and LLVM_VERSION_MINOR >= 3
#include <llvm/IR/Value.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Function.h>
@ -8,10 +8,6 @@
#include <llvm/IR/Constants.h>
#include <llvm/IR/Intrinsics.h>
#include <llvm/IR/IRBuilder.h>
#if LLVM_VERSION_MINOR >= 4
#include <llvm/Support/MemoryObject.h>
#include <llvm/MC/MCDisassembler.h>
#endif
#else
#include <llvm/Value.h>
#include <llvm/DerivedTypes.h>
@ -40,7 +36,7 @@
namespace extra{
using namespace llvm;
class raw_svector_ostream_helper: public raw_svector_ostream {
SmallVectorImpl<char> *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<llvm::Type*, 8> 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<GenericValue*>(
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::iterator>(
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 &region,
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

View file

@ -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',

View file

@ -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()

View file

@ -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),

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -19,7 +19,7 @@ class Function:
_include_ = 'llvm/IR/Function.h'
else:
_include_ = 'llvm/Function.h'
_downcast_ = GlobalValue, Constant, Value
getReturnType = Method(ptr(Type))

View file

@ -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

View file

@ -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)
)

File diff suppressed because it is too large Load diff

View file

@ -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)

View file

@ -17,7 +17,7 @@ if LLVM_VERSION >= (3, 3):
cast(Bool, bool))
else:
isLittleEndianHost = sys.Function('isLittleEndianHost',
cast(Bool, bool))

View file

@ -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))

View file

@ -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)

View file

@ -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'

View file

@ -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)))

View file

@ -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):

View file

@ -13,4 +13,4 @@ SplitBlockAndInsertIfThen = llvm.Function('SplitBlockAndInsertIfThen',
ReplaceInstWithInst = llvm.Function('ReplaceInstWithInst',
Void,
ptr(Instruction), # from
ptr(Instruction)) # to
ptr(Instruction)) # to

View file

@ -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]))

View file

@ -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',

View file

@ -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)

View file

@ -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())

Some files were not shown because too many files have changed in this diff Show more