Merge branch 'newbinding_integrate'

Conflicts:
	llvm/core.py
This commit is contained in:
Siu Kwan Lam 2013-02-27 13:52:37 -06:00
commit 17096867f7
111 changed files with 7927 additions and 11314 deletions

3
.gitignore vendored
View file

@ -2,4 +2,7 @@
build
_build
*.pyc
*.so
/llvm/_intrinsic_ids.py
llvm_
newbinding/api/*

File diff suppressed because it is too large Load diff

View file

@ -1,154 +1,42 @@
"""
Common classes related to LLVM.
"""
from ._version import get_versions
__version__ = get_versions()['version']
del get_versions
from weakref import WeakValueDictionary
from . import _core
from llvmpy import extra
version = extra.get_llvm_version()
del extra
#===----------------------------------------------------------------------===
# LLVM Version
#===----------------------------------------------------------------------===
class Wrapper(object):
def __init__(self, ptr):
assert ptr
self.__ptr = ptr
version = _core.LLVMGetVersion()
@property
def _ptr(self):
try:
return self.__ptr
except AttributeError:
raise AttributeError("_ptr resource has been removed")
def require_version_at_least(major, minor):
'''Sentry to guard version requirement
'''
if version < (major, minor):
raise Exception(major, minor)
@_ptr.deleter
def _ptr(self):
del self.__ptr
#===----------------------------------------------------------------------===
# Exceptions
#===----------------------------------------------------------------------===
def _extract_ptrs(objs):
return [(x._ptr if x is not None else None)
for x in objs]
class LLVMException(Exception):
"""Generic LLVM exception."""
def __init__(self, msg=""):
Exception.__init__(self, msg)
#===----------------------------------------------------------------------===
# Ownables
#===----------------------------------------------------------------------===
class Ownable(object):
"""Objects that can be owned.
Modules and Module Providers can be owned, i.e., the responsibility of
destruction of ownable objects can be handed over to other objects. The
llvm.Ownable class represents objects that can be so owned. This class
is NOT intended for public use.
"""
def __init__(self, ptr, del_fn):
self.ptr = ptr
self.owner = None
self.del_fn = del_fn
def _own(self, owner):
if self.owner:
raise LLVMException("object already owned")
self.owner = owner
def _disown(self):
if not self.owner:
raise LLVMException("not owned")
self.owner = None
def __del__(self):
if not self.owner:
self.del_fn(self.ptr)
#===----------------------------------------------------------------------===
# Dummy owner, will not delete ownee. Be careful.
#===----------------------------------------------------------------------===
class DummyOwner(object):
pass
#===----------------------------------------------------------------------===
# A metaclass to prevent aliasing. It stores a (weak) reference to objects
# constructed based on a PyCObject. If an object is constructed based on a
# PyCObject with the same underlying pointer as a previous object, a reference
# to the previous object is returned rather than a new one.
#===----------------------------------------------------------------------===
class _ObjectCache(type):
"""A metaclass to prevent aliasing.
Classes using 'ObjectCache' as a metaclass must have constructors
that take a PyCObject as their first argument. When the class is
called (to create a new instance of the class), the value of the
pointer wrapped by the PyCObj is checked:
If no previous object has been created based on the same
underlying pointer (note that different PyCObject objects can
wrap the same pointer), the object will be initialized as
usual and returned.
If a previous has been created based on the same pointer,
then a reference to that object will be returned, and no
object initialization is performed.
"""
__instances = WeakValueDictionary()
def __call__(cls, ptr, *args, **kwargs):
objid = _core.PyCObjectVoidPtrToPyLong(ptr)
key = "%s:%d" % (cls.__name__, objid)
obj = _ObjectCache.__instances.get(key)
if obj is None:
obj = super(_ObjectCache, cls).__call__(ptr, *args, **kwargs)
_ObjectCache.__instances[key] = obj
return obj
@staticmethod
def forget(obj):
objid = _core.PyCObjectVoidPtrToPyLong(obj.ptr)
key = "%s:%d" % (type(obj).__name__, objid)
if key in _ObjectCache.__instances:
del _ObjectCache.__instances[key]
#===----------------------------------------------------------------------===
# Cacheables
#===----------------------------------------------------------------------===
# version 2/3 compatibility help
# version 2 metaclass
# class Cacheable(object):
# __metaclass__ = _ObjectCache # Doing nothing for version 3
#
# version 3 metaclass
# class Cacheable(metaclass=_ObjectCache):
#
# Reference: http://mikewatkins.ca/2008/11/29/python-2-and-3-metaclasses/#using-the-metaclass-in-python-3-x
ObjectCache = _ObjectCache('ObjectCache', (object, ), {})
class Cacheable(ObjectCache):
"""Objects that can be cached.
Objects that wrap a PyCObject are cached to avoid "aliasing", i.e.,
two Python objects each containing a PyCObject which internally points
to the same C pointer."""
def forget(self):
ObjectCache.forget(self)
def test(verbosity=1):
"""test(verbosity=1) -> TextTestResult
Run self-test, and return unittest.runner.TextTestResult object.
"""
Run self-test, and return unittest.runner.TextTestResult object.
"""
from llvm.test_llvmpy import run
return run(verbosity=verbosity)

File diff suppressed because it is too large Load diff

View file

@ -1,86 +0,0 @@
#include <Python.h>
#include <llvm/Support/Dwarf.h>
namespace llvmpy {
namespace dwarf {
using namespace llvm::dwarf;
const char *constant_names[] = {
"LLVMDebugVersion",
#define define(x) #x,
#include "_dwarf.h"
#undef define
};
int constant_values[] = {
llvm::LLVMDebugVersion,
#define define(x) x,
#include "_dwarf.h"
#undef define
};
enum enum_values {
__llvmpy_LLVMDebugVersion,
#define define(x) __llvmpy_##x,
#include "_dwarf.h"
#undef define
NVALUES /* Get the number of constants */
};
} // End namespace dwarf
int
set_dwarf_constants(PyObject *module)
{
int i;
for (i = 0; i < dwarf::NVALUES; i++) {
if (PyModule_AddIntConstant(module, dwarf::constant_names[i],
dwarf::constant_values[i]) > 0)
return -1;
}
return 0;
}
} // End namespace llvmpy
#if (PY_MAJOR_VERSION >= 3)
struct PyModuleDef module_def = {
PyModuleDef_HEAD_INIT,
"_dwarf",
NULL,
-1,
NULL, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
#define INITERROR return NULL
PyObject *PyInit__dwarf(void)
#else
#define INITERROR return
PyMODINIT_FUNC init_dwarf(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
PyObject *module = PyModule_Create( &module_def );
#else
PyObject *module = Py_InitModule("_dwarf", NULL);
#endif
if (module == NULL)
INITERROR;
if (llvmpy::set_dwarf_constants(module) < 0)
INITERROR;
#if PY_MAJOR_VERSION >= 3
return module;
#endif
}

View file

@ -1,101 +0,0 @@
/* Dwarf constant wrapping. See include/llvm/Support/Dwarf.h */
define(DWARF_VERSION)
/* Dwarf tags */
define(DW_TAG_array_type)
define(DW_TAG_class_type)
define(DW_TAG_entry_point)
define(DW_TAG_enumeration_type)
define(DW_TAG_formal_parameter)
define(DW_TAG_imported_declaration)
define(DW_TAG_label)
define(DW_TAG_lexical_block)
define(DW_TAG_member)
define(DW_TAG_pointer_type)
define(DW_TAG_reference_type)
define(DW_TAG_compile_unit)
define(DW_TAG_string_type)
define(DW_TAG_structure_type)
define(DW_TAG_subroutine_type)
define(DW_TAG_typedef)
define(DW_TAG_union_type)
define(DW_TAG_unspecified_parameters)
define(DW_TAG_variant)
define(DW_TAG_common_block)
define(DW_TAG_common_inclusion)
define(DW_TAG_inheritance)
define(DW_TAG_inlined_subroutine)
define(DW_TAG_module)
define(DW_TAG_ptr_to_member_type)
define(DW_TAG_set_type)
define(DW_TAG_subrange_type)
define(DW_TAG_with_stmt)
define(DW_TAG_access_declaration)
define(DW_TAG_base_type)
define(DW_TAG_catch_block)
define(DW_TAG_const_type)
define(DW_TAG_constant)
define(DW_TAG_enumerator)
define(DW_TAG_file_type)
define(DW_TAG_friend)
define(DW_TAG_namelist)
define(DW_TAG_namelist_item)
define(DW_TAG_packed_type)
define(DW_TAG_subprogram)
define(DW_TAG_template_type_parameter)
define(DW_TAG_template_value_parameter)
define(DW_TAG_thrown_type)
define(DW_TAG_try_block)
define(DW_TAG_variant_part)
define(DW_TAG_variable)
define(DW_TAG_volatile_type)
define(DW_TAG_dwarf_procedure)
define(DW_TAG_restrict_type)
define(DW_TAG_interface_type)
define(DW_TAG_namespace)
define(DW_TAG_imported_module)
define(DW_TAG_unspecified_type)
define(DW_TAG_partial_unit)
define(DW_TAG_imported_unit)
define(DW_TAG_condition)
define(DW_TAG_shared_type)
define(DW_TAG_type_unit)
define(DW_TAG_rvalue_reference_type)
define(DW_TAG_template_alias)
define(DW_TAG_MIPS_loop)
define(DW_TAG_format_label)
define(DW_TAG_function_template)
define(DW_TAG_class_template)
define(DW_TAG_GNU_template_template_param)
define(DW_TAG_GNU_template_parameter_pack)
define(DW_TAG_GNU_formal_parameter_pack)
define(DW_TAG_lo_user)
define(DW_TAG_APPLE_property)
define(DW_TAG_hi_user)
/* Dwarf language constants */
define(DW_LANG_C89)
define(DW_LANG_C)
define(DW_LANG_Ada83)
define(DW_LANG_C_plus_plus)
define(DW_LANG_Cobol74)
define(DW_LANG_Cobol85)
define(DW_LANG_Fortran77)
define(DW_LANG_Fortran90)
define(DW_LANG_Pascal83)
define(DW_LANG_Modula2)
define(DW_LANG_Java)
define(DW_LANG_C99)
define(DW_LANG_Ada95)
define(DW_LANG_Fortran95)
define(DW_LANG_PLI)
define(DW_LANG_ObjC)
define(DW_LANG_ObjC_plus_plus)
define(DW_LANG_UPC)
define(DW_LANG_D)
define(DW_LANG_Python)
define(DW_LANG_lo_user)
define(DW_LANG_Mips_Assembler)
define(DW_LANG_hi_user)

View file

@ -1,108 +0,0 @@
#
# Copyright (c) 2008-10, Mahadevan R All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of this software, nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""Utility functions and classes.
Used only in other modules, not for public use."""
import llvm
import llvm._core as _core # for PyCObjectVoidPtrToPyLong
#===----------------------------------------------------------------------===
# A set of helpers to check various things. Raises exceptions on
# failures.
#===----------------------------------------------------------------------===
def check_gen(obj, typ):
if not isinstance(obj, typ):
typ_str = typ.__name__
msg = "argument not an instance of llvm.core.%s" % typ_str
raise TypeError(msg)
def check_is_unowned(ownable):
if ownable.owner:
raise llvm.LLVMException("object is already owned")
#===----------------------------------------------------------------------===
# A set of helpers to unpack a list of Python wrapper objects
# into a list of PyCObject wrapped objects, checking types along
# the way.
#===----------------------------------------------------------------------===
def unpack_gen(objlist, check_fn):
for obj in objlist: check_fn(obj)
return [ obj.ptr for obj in objlist ]
def unpack_gen_allow_none(objlist, check_fn):
for obj in objlist:
if obj is not None:
check_fn(obj)
return [ (obj.ptr if obj is not None else None) for obj in objlist ]
#===----------------------------------------------------------------------===
# Helper to wrap over iterables (LLVMFirstXXX, LLVMNextXXX). This used
# to be a generator, but that loses subscriptability of the result, so
# we now return a list.
#===----------------------------------------------------------------------===
def wrapiter(first, next, container, wrapper):
ret = []
ptr = first(container)
while ptr:
ret.append(wrapper(ptr))
ptr = next(ptr)
return ret
#===----------------------------------------------------------------------===
# Py2/3 compatibility string check
#===----------------------------------------------------------------------===
def _isstring_py2(x):
return isinstance(x, basestring)
def _isstring_py3(x):
return isinstance(x, str)
def _isstring_choose():
try:
basestring
return _isstring_py2
except:
return _isstring_py3
isstring = _isstring_choose()
try:
unicode_type = unicode
except NameError: # Py3
unicode_type = str

View file

@ -1,134 +0,0 @@
#ifndef __CAPSULETHUNK_H
#define __CAPSULETHUNK_H
#if ( (PY_VERSION_HEX < 0x02070000) \
|| ((PY_VERSION_HEX >= 0x03000000) \
&& (PY_VERSION_HEX < 0x03010000)) )
#define __PyCapsule_GetField(capsule, field, default_value) \
( PyCapsule_CheckExact(capsule) \
? (((PyCObject *)capsule)->field) \
: (default_value) \
) \
#define __PyCapsule_SetField(capsule, field, value) \
( PyCapsule_CheckExact(capsule) \
? (((PyCObject *)capsule)->field = value), 1 \
: 0 \
) \
#define PyCapsule_Type PyCObject_Type
#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule))
#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule))
#define PyCapsule_New(pointer, name, destructor) \
(PyCObject_FromVoidPtr(pointer, destructor))
#define PyCapsule_GetPointer(capsule, name) \
(PyCObject_AsVoidPtr(capsule))
/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */
#define PyCapsule_SetPointer(capsule, pointer) \
__PyCapsule_SetField(capsule, cobject, pointer)
#define PyCapsule_GetDestructor(capsule) \
__PyCapsule_GetField(capsule, destructor)
#define PyCapsule_SetDestructor(capsule, dtor) \
__PyCapsule_SetField(capsule, destructor, dtor)
/*
* Sorry, there's simply no place
* to store a Capsule "name" in a CObject.
*/
#define PyCapsule_GetName(capsule) NULL
static int
PyCapsule_SetName(PyObject *capsule, const char *unused)
{
unused = unused;
PyErr_SetString(PyExc_NotImplementedError,
"can't use PyCapsule_SetName with CObjects");
return 1;
}
#define PyCapsule_GetContext(capsule) \
__PyCapsule_GetField(capsule, descr)
#define PyCapsule_SetContext(capsule, context) \
__PyCapsule_SetField(capsule, descr, context)
static void *
PyCapsule_Import(const char *name, int no_block)
{
PyObject *object = NULL;
void *return_value = NULL;
char *trace;
size_t name_length = (strlen(name) + 1) * sizeof(char);
char *name_dup = (char *)PyMem_MALLOC(name_length);
if (!name_dup) {
return NULL;
}
memcpy(name_dup, name, name_length);
trace = name_dup;
while (trace) {
char *dot = strchr(trace, '.');
if (dot) {
*dot++ = '\0';
}
if (object == NULL) {
if (no_block) {
object = PyImport_ImportModuleNoBlock(trace);
} else {
object = PyImport_ImportModule(trace);
if (!object) {
PyErr_Format(PyExc_ImportError,
"PyCapsule_Import could not "
"import module \"%s\"", trace);
}
}
} else {
PyObject *object2 = PyObject_GetAttrString(object, trace);
Py_DECREF(object);
object = object2;
}
if (!object) {
goto EXIT;
}
trace = dot;
}
if (PyCObject_Check(object)) {
PyCObject *cobject = (PyCObject *)object;
return_value = cobject->cobject;
} else {
PyErr_Format(PyExc_AttributeError,
"PyCapsule_Import \"%s\" is not valid",
name);
}
EXIT:
Py_XDECREF(object);
if (name_dup) {
PyMem_FREE(name_dup);
}
return return_value;
}
#endif /* #if PY_VERSION_HEX < 0x02070000 */
#endif /* __CAPSULETHUNK_H */

File diff suppressed because it is too large Load diff

View file

@ -1,398 +0,0 @@
"""
Support for debug info metadata.
"""
import functools
import llvm.core
from llvm import _dwarf
#----------------------------------------------------------------------------
# Some types and type checking functions
#----------------------------------------------------------------------------
int32_t = llvm.core.Type.int(32)
bool_t = llvm.core.Type.int(1)
p_int32_t = llvm.core.Type.pointer(int32_t)
null = llvm.core.Constant.null(p_int32_t)
i32 = functools.partial(llvm.core.Constant.int, int32_t)
i1 = functools.partial(llvm.core.Constant.int, bool_t)
def is_md(value):
return isinstance(value, (llvm.core.MetaData, llvm.core.NamedMetaData,
llvm.core.Value))
def is_mdstr(value):
return isinstance(value, (llvm.core.MetaDataString, llvm.core.Value))
#----------------------------------------------------------------------------
# Callbacks for debug type descriptors
#----------------------------------------------------------------------------
def get_i32(llvm_module, value):
return i32(value)
def get_i1(llvm_module, value):
return i1(value)
def get_md(llvm_module, value):
if is_md(value):
return value
return value.get_metadata(llvm_module)
def get_mdstr(llvm_module, value):
if is_mdstr(value):
return value
return llvm.core.MetaDataString.get(llvm_module, value)
def get_mdlist(llvm_module, value):
if isinstance(value, list):
value = MDList([value])
return get_md(llvm_module, value)
def get_lfunc(llvm_module, lfunc):
assert lfunc.module is llvm_module
return lfunc
#----------------------------------------------------------------------------
# Debug descriptors that generate LLVM Metadata
#----------------------------------------------------------------------------
class desc(object):
"""
Descriptor of a debug field.
field_name:
name of the field (keyword argument name)
build_metadata:
metadata callback :: (llvm_module, Python value) -> LLVM Value
default:
default value for this field
"""
def __init__(self, field_name, build_metadata, default=None):
self.field_name = field_name
self.build_metadata = build_metadata
self.default = default
def build_operand_list(type_descriptors, idx2name, operands, kwargs):
"""
Build the list of operands from the positional and keyword arguments
to a DebugInfoDescriptor.
E.g. FileDescriptor("foo.c", "/path/to/file", compile_unit=compile_unit)
idx2name: {0 : 'source_filename',
1 : 'source_filedir',
2 : 'compile_unit' }
operands: ["foo.c", "/path/to/file"]
kwargs: { 'compile_unit' : compile_unit }
"""
for i in range(len(operands), len(type_descriptors)):
name = idx2name[i]
if name in kwargs:
op = kwargs[name]
else:
typedesc = type_descriptors[i]
assert typedesc.default is not None, (
"No value found for field %s" % typedesc.field_name)
op = typedesc.default
operands.append(op)
return operands
class DebugInfoDescriptor(object):
"""
Base class to describe a debug info descriptor.
See http://llvm.org/docs/SourceLevelDebugging.html
"""
type_descriptors = None # [desc(...)]
idx2name = None # { "field_idx" : field_name }
name2idx = None # { "field_name" : field_idx }
# Whether the debug descriptor is allowed to be incomplete
# The policy seems unclear ?
accept_optional_data = False
def __init__(self, *args, **kwargs):
self.class_init()
self.metadata_cache = {}
operands = list(args)
if kwargs or not self.accept_optional_data:
operands = build_operand_list(self.type_descriptors,
self.idx2name, operands, kwargs)
self.operands = operands
self.operands_dict = dict(
(typedesc.field_name, operand)
for typedesc, operand in zip(self.type_descriptors, operands))
@classmethod
def class_init(cls):
if cls.idx2name is None and cls.type_descriptors is not None:
cls.name2idx = {}
cls.idx2name = {}
for i, typedesc in enumerate(cls.type_descriptors):
cls.name2idx[typedesc.field_name] = i
cls.idx2name[i] = typedesc.field_name
def add_metadata(self, metadata_name, metadata):
"""
Replace a metadata value in the operand list.
"""
idx = self.name2idx[metadata_name]
self.operands[idx] = metadata
#------------------------------------------------------------------------
# Define metadata in a module
#------------------------------------------------------------------------
def get_metadata(self, llvm_module):
"""
Get an existing metadata node for the given LLVM module, or build
one from this instance.
"""
if llvm_module in self.metadata_cache:
node = self.metadata_cache[llvm_module]
else:
node = self.build_metadata(llvm_module)
self.metadata_cache[llvm_module] = node
return node
def build_metadata(self, llvm_module):
"Build a metadata node for the given LLVM module"
mdops = []
for type_desc, operand in zip(self.type_descriptors, self.operands):
try:
field_value = type_desc.build_metadata(llvm_module, operand)
except Exception, e:
if type_desc.build_metadata is get_md:
raise
raise ValueError("Invalid value for field %r: %s" % (
type_desc.field_name, e))
mdops.append(field_value)
return llvm.core.MetaData.get(llvm_module, mdops)
def define(self, llvm_module):
"""
Define this debug descriptor as named debug metadata for the module.
"""
md = self.get_metadata(llvm_module)
llvm.core.MetaData.add_named_operand(llvm_module, "dbg", md)
#----------------------------------------------------------------------------
# Convenience descriptors
#----------------------------------------------------------------------------
class MDList(DebugInfoDescriptor):
"""
[MetaData]
"""
def __init__(self, operands):
self.type_descriptors = [desc("op", get_md)] * len(operands)
super(MDList, self).__init__(*operands)
empty = MDList([])
#----------------------------------------------------------------------------
# Dwarf Debug descriptors
#----------------------------------------------------------------------------
class CompileUnitDescriptor(DebugInfoDescriptor):
"""
!0 = metadata !{
i32, ;; Tag = 17 + LLVMDebugVersion (DW_TAG_compile_unit)
i32, ;; Unused field.
i32, ;; DWARF language identifier (ex. DW_LANG_C89)
metadata, ;; Source file name
metadata, ;; Source file directory (includes trailing slash)
metadata ;; Producer (ex. "4.0.1 LLVM (LLVM research group)")
i1, ;; True if this is a main compile unit.
i1, ;; True if this is optimized.
metadata, ;; Flags
i32 ;; Runtime version
metadata ;; List of enums types
metadata ;; List of retained types
metadata ;; List of subprograms
metadata ;; List of global variables
}
"""
accept_optional_data = True
type_descriptors = [
desc("tag", get_i32),
desc("unused", get_i32),
# Positional argument list starts here:
desc("langid", get_i32),
desc("source_filename", get_mdstr),
desc("source_filedir", get_mdstr),
desc("producer", get_mdstr),
desc("is_main", get_i1, default=False),
desc("is_optimized", get_i1, default=False),
desc("compile_flags", get_mdstr, default=""),
desc("runtime_version", get_i32, default=0),
desc("enum_types", get_mdlist, default=empty),
desc("retained_types", get_mdlist, default=empty),
desc("subprograms", get_mdlist, default=empty),
desc("global_vars", get_mdlist, default=empty),
]
def __init__(self, *args, **kwargs):
super(CompileUnitDescriptor, self).__init__(
_dwarf.DW_TAG_compile_unit + _dwarf.LLVMDebugVersion, # tag
0, # unused
*args, **kwargs)
def define(self, llvm_module):
"""
Define this debug descriptor as named debug metadata for the module.
"""
md = self.get_metadata(llvm_module)
llvm.core.MetaData.add_named_operand(llvm_module, "llvm.dbg.cu", md)
class FileDescriptor(DebugInfoDescriptor):
"""
!0 = metadata !{
i32, ;; Tag = 41 + LLVMDebugVersion (DW_TAG_file_type)
metadata, ;; Source file name
metadata, ;; Source file directory (includes trailing slash)
metadata ;; Unused
}
"""
type_descriptors = [
desc("tag", get_i32),
# Positional argument list starts here:
desc("source_filename", get_mdstr),
desc("source_filedir", get_mdstr),
desc("compile_unit", get_md, default=null),
]
def __init__(self, *args, **kwargs):
super(FileDescriptor, self).__init__(
_dwarf.DW_TAG_file_type + _dwarf.LLVMDebugVersion, # Tag
*args, **kwargs)
@classmethod
def from_compileunit(cls, compile_unit_descriptor):
return cls(compile_unit_descriptor.operands_dict["source_filename"],
compile_unit_descriptor.operands_dict["source_filedir"],
compile_unit_descriptor)
class SubprogramDescriptor(DebugInfoDescriptor):
"""
!2 = metadata !{
i32, ;; Tag = 46 + LLVMDebugVersion (DW_TAG_subprogram)
i32, ;; Unused field.
metadata, ;; Reference to context descriptor
metadata, ;; Name
metadata, ;; Display name (fully qualified C++ name)
metadata, ;; MIPS linkage name (for C++)
metadata, ;; Reference to file where defined
i32, ;; Line number where defined
metadata, ;; Reference to type descriptor
i1, ;; True if the global is local to compile unit (static)
i1, ;; True if the global is defined in the compile unit (not extern)
i32, ;; Line number where the scope of the subprogram begins
i32, ;; Virtuality, e.g. dwarf::DW_VIRTUALITY__virtual
i32, ;; Index into a virtual function
metadata, ;; indicates which base type contains the vtable pointer for the
;; derived class
i32, ;; Flags - Artifical, Private, Protected, Explicit, Prototyped.
i1, ;; isOptimized
Function * , ;; Pointer to LLVM function
metadata, ;; Lists function template parameters
metadata, ;; Function declaration descriptor
metadata ;; List of function variables
}
"""
accept_optional_data = True
type_descriptors = [
desc("tag", get_i32),
desc("unused", get_i32),
# Positional argument list starts here:
desc("file_desc", get_md),
desc("name", get_mdstr),
desc("display_name", get_mdstr),
desc("mips_linkage_name", get_mdstr),
desc("source_file_ref", get_md),
desc("line_number", get_i32),
desc("signature", get_md),
desc("is_local", get_i1, default=False),
desc("is_definition", get_i1, default=True),
desc("virtual_attribute", get_i32, default=0),
desc("virtual_index", get_i32, default=0),
desc("virttab", get_i32, default=0),
desc("flags", get_i32, default=0),
desc("is_optimized", get_i1, default=False),
desc("llvm_func", get_lfunc),
# Template params
# Func decl
# Func vars
]
def __init__(self, *args, **kwargs):
super(SubprogramDescriptor, self).__init__(
_dwarf.DW_TAG_subprogram + _dwarf.LLVMDebugVersion, # Tag
0, # Unused
*args, **kwargs)
class BlockDescriptor(DebugInfoDescriptor):
"""
!3 = metadata !{
i32, ;; Tag = 11 + LLVMDebugVersion (DW_TAG_lexical_block)
metadata,;; Reference to context descriptor
i32, ;; Line number
i32 ;; Column number
}
"""
type_descriptors = [
desc("tag", get_i32),
# Positional argument list starts here:
desc("context_descr", get_md), # FileDescr | BlockDescr |
# SubprogDescr | ComputeUnit
desc("line_number", get_i32),
desc("col_number", get_i32),
]
def __init__(self, *args, **kwargs):
super(BlockDescriptor, self).__init__(
_dwarf.DW_TAG_lexical_block + _dwarf.LLVMDebugVersion,
*args, **kwargs)
class PositionInfoDescriptor(DebugInfoDescriptor):
"""
line number, column number, scope, and original scope
"""
type_descriptors = [
desc("line_number", get_i32),
desc("col_number", get_i32),
desc("context_descr", get_md), # Scope of instruction
# (FileDescr etc)
desc("original_context_descr", get_md, # The original scope if inlined
default=null),
]

View file

@ -28,44 +28,15 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""Execution Engine and related classes.
"Execution Engine and related classes."
"""
import llvm # top-level, for common stuff
import llvm.core as core # module, function etc.
import llvm._core as _core # C wrappers
import llvm._util as _util # utility functions
import logging
import os
logger = logging.getLogger(__name__)
# re-export TargetData for backward compatibility.
from llvm.passes import TargetData
def _detect_avx_support():
'''FIXME: This is a workaround for AVX support.
'''
disable_avx_detect = int(os.environ.get('LLVMPY_DISABLE_AVX_DETECT', 0))
if disable_avx_detect:
return False # enable AVX if user disable AVX detect
force_disable_avx = int(os.environ.get('LLVMPY_FORCE_DISABLE_AVX', 0))
if force_disable_avx:
return True # force disable AVX
# auto-detect avx
try:
for line in open('/proc/cpuinfo'):
if line.lstrip().startswith('flags') and 'avx' in line.split():
# enable AVX if flags contain AVX
return False
except IOError:
pass # disable AVX if no /proc/cpuinfo is found
return True # disable AVX if flags does not have AVX
FORCE_DISABLE_AVX = _detect_avx_support()
from io import BytesIO
import contextlib
import llvm
from llvm import core
from llvm.passes import TargetData, TargetTransformInfo
from llvmpy import api, extra
#===----------------------------------------------------------------------===
# Enumerations
#===----------------------------------------------------------------------===
@ -74,39 +45,41 @@ BO_BIG_ENDIAN = 0
BO_LITTLE_ENDIAN = 1
# CodeModel
CM_DEFAULT = 0
CM_JITDEFAULT = 1
CM_SMALL = 2
CM_KERNEL = 3
CM_MEDIUM = 4
CM_LARGE = 5
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
#===----------------------------------------------------------------------===
# Generic value
#===----------------------------------------------------------------------===
class GenericValue(object):
class GenericValue(llvm.Wrapper):
@staticmethod
def int(ty, intval):
core.check_is_type(ty)
ptr = _core.LLVMCreateGenericValueOfInt(ty.ptr, intval, 0)
ptr = api.llvm.GenericValue.CreateInt(ty._ptr, int(intval), False)
return GenericValue(ptr)
@staticmethod
def int_signed(ty, intval):
core.check_is_type(ty)
ptr = _core.LLVMCreateGenericValueOfInt(ty.ptr, intval, 1)
ptr = api.llvm.GenericValue.CreateInt(ty._ptr, int(intval), True)
return GenericValue(ptr)
@staticmethod
def real(ty, floatval):
core.check_is_type(ty) # only float or double
ptr = _core.LLVMCreateGenericValueOfFloat(ty.ptr, floatval)
if str(ty) == 'float':
ptr = api.llvm.GenericValue.CreateFloat(float(floatval))
elif str(ty) == 'double':
ptr = api.llvm.GenericValue.CreateDouble(float(floatval))
else:
raise Exception('Unreachable')
return GenericValue(ptr)
@staticmethod
def pointer(*args):
def pointer(addr):
'''
One argument version takes (addr).
Two argument version takes (ty, addr). [Deprecated]
@ -114,79 +87,46 @@ class GenericValue(object):
`ty` is unused.
`addr` is an integer representing an address.
TODO: remove two argument version.
'''
if len(args)==2:
logger.warning("Deprecated: Two argument version of "
"GenericValue.pointer() is deprecated.")
addr = args[1]
elif len(args)!=1:
raise TypeError("pointer() takes 1 or 2 arguments.")
else:
addr = args[0]
ptr = _core.LLVMCreateGenericValueOfPointer(addr)
ptr = api.llvm.GenericValue.CreatePointer(int(addr))
return GenericValue(ptr)
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMDisposeGenericValue(self.ptr)
def as_int(self):
return _core.LLVMGenericValueToInt(self.ptr, 0)
return self._ptr.toUnsignedInt()
def as_int_signed(self):
return _core.LLVMGenericValueToInt(self.ptr, 1)
return self._ptr.toSignedInt()
def as_real(self, ty):
core.check_is_type(ty) # only float or double
return _core.LLVMGenericValueToFloat(ty.ptr, self.ptr)
return self._ptr.toFloat(ty._ptr)
def as_pointer(self):
return _core.LLVMGenericValueToPointer(self.ptr)
# helper functions for generic value objects
def check_is_generic_value(obj): _util.check_gen(obj, GenericValue)
def _unpack_generic_values(objlist):
return _util.unpack_gen(objlist, check_is_generic_value)
return self._ptr.toPointer()
#===----------------------------------------------------------------------===
# Engine builder
#===----------------------------------------------------------------------===
class EngineBuilder(object):
class EngineBuilder(llvm.Wrapper):
@staticmethod
def new(module):
core.check_is_module(module)
_util.check_is_unowned(module)
obj = _core.LLVMCreateEngineBuilder(module.ptr)
return EngineBuilder(obj, module)
def __init__(self, ptr, module):
self.ptr = ptr
self._module = module
self.__has_mattrs = False
def __del__(self):
_core.LLVMDisposeEngineBuilder(self.ptr)
ptr = api.llvm.EngineBuilder.new(module._ptr)
return EngineBuilder(ptr)
def force_jit(self):
_core.LLVMEngineBuilderForceJIT(self.ptr)
self._ptr.setEngineKind(api.llvm.EngineKind.Kind.JIT)
return self
def force_interpreter(self):
_core.LLVMEngineBuilderForceInterpreter(self.ptr)
self._ptr.setEngineKind(api.llvm.EngineKind.Kind.Interpreter)
return self
def opt(self, level):
'''
level valid [0, 1, 2, 3] -- [None, Less, Default, Aggressive]
'''
assert level in range(4)
_core.LLVMEngineBuilderSetOptLevel(self.ptr, level)
assert 0 <= level <= 3
self._ptr.setOptLevel = level
return self
def mattrs(self, string):
@ -194,45 +134,39 @@ class EngineBuilder(object):
e.g: +sse,-3dnow
'''
self.__has_mattrs = True
if FORCE_DISABLE_AVX:
if 'avx' not in map(lambda x: x.strip(), string.split(',')):
# User did not override
string += ',-avx'
_core.LLVMEngineBuilderSetMAttrs(self.ptr, string.replace(',', ' '))
self._ptr.setMAttrs(string.split(','))
return self
def create(self, tm=None):
'''
tm --- Optional. Provide a TargetMachine. Ownership is transfered
to the returned execution engine.
to the returned execution engine.
'''
if not self.__has_mattrs and FORCE_DISABLE_AVX:
self.mattrs('-avx')
if tm:
_util.check_is_unowned(tm)
ret = _core.LLVMEngineBuilderCreateTM(self.ptr, tm.ptr)
if tm is not None:
engine = self._ptr.create(tm._ptr)
else:
ret = _core.LLVMEngineBuilderCreate(self.ptr)
if isinstance(ret, str):
raise llvm.LLVMException(ret)
engine = ExecutionEngine(ret, self._module)
if tm:
tm._own(owner=llvm.DummyOwner)
return engine
engine = self._ptr.create()
return ExecutionEngine(engine)
def select_target(self):
def select_target(self, *args):
'''get the corresponding target machine
Accept no arguments or (triple, march, mcpu, mattrs)
'''
ptr = _core.LLVMTargetMachineFromEngineBuilder(self.ptr)
if args:
triple, march, mcpu, mattrs = args
ptr = self._ptr.selectTarget(triple, march, mcpu,
mattrs.split(','))
else:
ptr = self._ptr.selectTarget()
return TargetMachine(ptr)
#===----------------------------------------------------------------------===
# Execution engine
#===----------------------------------------------------------------------===
class ExecutionEngine(object):
class ExecutionEngine(llvm.Wrapper):
@staticmethod
def new(module, force_interpreter=False):
@ -241,65 +175,42 @@ class ExecutionEngine(object):
eb.force_interpreter()
return eb.create()
def __init__(self, ptr, module):
self.ptr = ptr
module._own(self)
def __del__(self):
_core.LLVMDisposeExecutionEngine(self.ptr)
def disable_lazy_compilation(self, disabled=True):
_core.LLVMExecutionEngineDisableLazyCompilation(self.ptr,
int(bool(disabled)))
self._ptr.DisableLazyCompilation(disabled)
def run_function(self, fn, args):
core.check_is_function(fn)
ptrs = _unpack_generic_values(args)
gvptr = _core.LLVMRunFunction2(self.ptr, fn.ptr, ptrs)
return GenericValue(gvptr)
ptr = self._ptr.runFunction(fn._ptr, list(map(lambda x: x._ptr, args)))
return GenericValue(ptr)
def get_pointer_to_function(self, fn):
core.check_is_function(fn)
return _core.LLVMGetPointerToFunction(self.ptr,fn.ptr)
return self._ptr.getPointerToFunction(fn._ptr)
def get_pointer_to_global(self, val):
core.check_is_global_value(val)
return _core.LLVMGetPointerToGlobal(self.ptr, val.ptr)
return self._ptr.getPointerToGlobal(val._ptr)
def add_global_mapping(self, gvar, addr):
assert addr >= 0, "Address cannot not be negative"
_core.LLVMAddGlobalMapping(self.ptr, gvar.ptr, addr)
self._ptr.addGlobalMapping(gvar._ptr, addr)
def run_static_ctors(self):
_core.LLVMRunStaticConstructors(self.ptr)
self._ptr.runStaticConstructorsDestructors(False)
def run_static_dtors(self):
_core.LLVMRunStaticDestructors(self.ptr)
self._ptr.runStaticConstructorsDestructors(True)
def free_machine_code_for(self, fn):
core.check_is_function(fn)
_core.LLVMFreeMachineCodeForFunction(self.ptr, fn.ptr)
self._ptr.freeMachineCodeForFunction(fn._ptr)
def add_module(self, module):
core.check_is_module(module)
_core.LLVMAddModule(self.ptr, module.ptr)
module._own(self)
self._ptr.addModule(module._ptr)
def remove_module(self, module):
core.check_is_module(module)
if module.owner != self:
raise llvm.LLVMException("module is not owned by self")
ret = _core.LLVMRemoveModule2(self.ptr, module.ptr)
if isinstance(ret, str):
raise llvm.LLVMException(ret)
return core.Module(ret)
return self._ptr.removeModule(module._ptr)
@property
def target_data(self):
td = TargetData(_core.LLVMGetExecutionEngineTargetData(self.ptr))
td._own(self)
return td
ptr = self._ptr.getDataLayout()
return TargetData(ptr)
#===----------------------------------------------------------------------===
# Target machine
@ -309,84 +220,114 @@ def print_registered_targets():
'''
Note: print directly to stdout
'''
_core.LLVMPrintRegisteredTargetsForVersion()
api.llvm.TargetRegistry.printRegisteredTargetsForVersion()
def get_host_cpu_name():
'''return the string name of the host CPU
'''
return _core.LLVMGetHostCPUName()
return api.llvm.sys.getHostCPUName()
def get_default_triple():
'''return the target triple of the host in str-rep
'''
return _core.LLVMDefaultTargetTriple()
return api.llvm.sys.getDefaultTargetTriple()
class TargetMachine(llvm.Ownable):
class TargetMachine(llvm.Wrapper):
@staticmethod
def new(triple='', cpu='', features='', opt=2, cm=CM_DEFAULT):
if not triple and not cpu:
if not triple:
triple = get_default_triple()
if not cpu:
cpu = get_host_cpu_name()
ptr = _core.LLVMCreateTargetMachine(triple, cpu, features, opt, cm)
return TargetMachine(ptr)
with contextlib.closing(BytesIO()) as error:
target = api.llvm.TargetRegistry.lookupTarget(triple, error)
if not target:
raise llvm.LLVMException(error)
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,
api.llvm.Reloc.Model.Default,
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):
'''create a targetmachine given an architecture name
For a list of architectures,
For a list of architectures,
use: `llc -help`
For a list of available CPUs,
For a list of available CPUs,
use: `llvm-as < /dev/null | llc -march=xyz -mcpu=help`
For a list of available attributes (features),
For a list of available attributes (features),
use: `llvm-as < /dev/null | llc -march=xyz -mattr=help`
'''
ptr = _core.LLVMTargetMachineLookup(arch, cpu, features, opt, cm)
return TargetMachine(ptr)
'''
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)
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,
api.llvm.Reloc.Model.Default,
cm, opt)
if not tm:
raise llvm.LLVMException("Cannot create target machine")
return TargetMachine(tm)
def __init__(self, ptr):
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeTargetMachine)
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)
return os.str()
def emit_assembly(self, module):
'''returns byte string of the module as assembly code of the target machine
'''
return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, True)
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
'''
return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, False)
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
'''
ptr = _core.LLVMTargetMachineGetTargetData(self.ptr)
td = TargetData(ptr)
td._own(self)
return td
return TargetData(self._ptr.getDataLayout())
@property
def target_name(self):
return _core.LLVMTargetMachineGetTargetName(self.ptr)
return self._ptr.getTarget().getName()
@property
def target_short_description(self):
return _core.LLVMTargetMachineGetTargetShortDescription(self.ptr)
return self._ptr.getTarget().getShortDescription()
@property
def triple(self):
return _core.LLVMTargetMachineGetTriple(self.ptr)
return self._ptr.getTargetTriple()
@property
def cpu(self):
return _core.LLVMTargetMachineGetCPU(self.ptr)
return self._ptr.getTargetCPU()
@property
def feature_string(self):
return _core.LLVMTargetMachineGetFS(self.ptr)
return self._ptr.getTargetFeatureString()

File diff suppressed because it is too large Load diff

View file

@ -1,676 +0,0 @@
/*
* Copyright (c) 2008-10, Mahadevan R All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of this software, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* These are some "extra" functions not available in the standard LLVM-C
* bindings, but are required / good-to-have inorder to implement the
* Python bindings.
*/
#ifndef LLVM_PY_EXTRA_H
#define LLVM_PY_EXTRA_H
// select PTX or NVPTX
#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2
#define LLVM_HAS_NVPTX 1
#else
#define LLVM_HAS_NVPTX 0
#endif
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm_c_extra.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2
/*
* Wraps new TargetTransformInfo(
* TargetMachine::getScalarTargetTransformInfo,
* TargetMachine::getVectorTargetTransformInfo)
*/
LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref);
#endif
/*
* Wraps new TargetLibraryInfo
*/
LLVMPassRef LLVMCreateTargetLibraryInfo(const char * triple);
/*
* Wraps llvm::getDefaultTargetTriple
*/
const char * LLVMDefaultTargetTriple();
/*
* Wraps Pass::lookupPassInfo and PassInfo::createPass
*/
LLVMPassRef LLVMCreatePassByName(const char *name);
/*
* Wraps operator delete (Pass*)
*/
void LLVMDisposePass(LLVMPassRef passref);
/*
* Wraps Pass::getPassName
*/
const char * LLVMGetPassName(LLVMPassRef passref);
/*
* Wraps PassManager::add
*/
void LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref);
/*
* Wraps Pass::dump
*/
void LLVMPassDump(LLVMPassRef passref);
/*
* Wraps llvm:InlineAsm::get
*/
LLVMValueRef LLVMGetFunctionFromInlineAsm(LLVMTypeRef funcType,
const char inlineAsm[],
const char constrains[],
bool hasSideEffect,
bool isAlignStack,
int asmDialect);
/*
* Wraps llvm::CloneModule
*/
LLVMModuleRef LLVMCloneModule(LLVMModuleRef mod);
/*
* Wraps NamedMDNode::print()
*/
const char * LLVMDumpNamedMDToString(LLVMNamedMDRef nmd);
/*
* Wraps NamedMDNode::getName()
*/
const char * LLVMNamedMetaDataGetName(LLVMNamedMDRef nmd);
/*
* Wraps NamedMDNode::addOperand()
*/
void LLVMNamedMetaDataAddOperand(LLVMNamedMDRef nmd, LLVMValueRef md);
/*
* Wraps NamedMDNode::eraseFromParent()
*/
void LLVMEraseNamedMetaData(LLVMNamedMDRef nmd);
/*
* Wraps Module::getOrInsertNamedMetadata
*/
LLVMNamedMDRef LLVMModuleGetOrInsertNamedMetaData(LLVMModuleRef mod, const char *name);
/*
* Wraps Module::getNamedMetadata
*/
LLVMNamedMDRef LLVMModuleGetNamedMetaData(LLVMModuleRef mod, const char *name);
/*
* Wraps Instruction::setMetadata()
*/
void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind,
LLVMValueRef metaref);
/*
* Wraps MDNode::get()
*/
LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs,
unsigned valct);
/*
* Wraps MDNode::getOperand()
*/
LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index);
/*
* Wraps MDNode::getNumOperands()
*/
unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref);
/*
* Wraps MDString::get()
*/
LLVMValueRef LLVMMetaDataStringGet(LLVMModuleRef modref, const char *s);
/*
* Wraps ConstantExpr::getOpcodeName()
*/
const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst);
/*
* Wraps ConstantExpr::getOpcode()
*/
unsigned LLVMGetConstExprOpcode(LLVMValueRef inst);
/*
* Wraps LoadInst::SetAlignment
*/
void LLVMLdSetAlignment(LLVMValueRef inst, unsigned align);
/*
* Wraps StoreInst::SetAlignment
*/
void LLVMStSetAlignment(LLVMValueRef inst, unsigned align);
const char * LLVMGetHostCPUName();
int LLVMInitializeNativeTargetAsmPrinter();
LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu,
const char *features, int opt,
int codemodel, std::string &error);
LLVMTargetMachineRef LLVMCreateTargetMachine(const char *arch, const char *cpu,
const char *features, int opt,
int codemodel,
std::string &error);
/*
* Wraps EngineBuilder::selectTarget
*/
LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb);
/*
* Wraps operator delete
*/
void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm);
/*
* Wraps TargetMachine::addPassesToEmitFile
*/
unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref,
LLVMModuleRef modref,
int assembly, size_t * lenp,
std::string &error);
/*
* Wraps TargetMachine::getTargetData
*/
LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm);
/*
* Wraps TargetMachine::getTarget().getName()
*/
const char* LLVMTargetMachineGetTargetName(LLVMTargetMachineRef tm);
/*
* Wraps TargetMachine::getTarget().getShortDescription()
*/
const char* LLVMTargetMachineGetTargetShortDescription(LLVMTargetMachineRef tm);
/*
* Wraps TargetMachine::getTargetTriple
*/
const char * LLVMTargetMachineGetTriple(LLVMTargetMachineRef tm);
/*
* Wraps TargetMachine::getTargetCPU
*/
const char * LLVMTargetMachineGetCPU(LLVMTargetMachineRef tm);
/*
* Wraps TargetMachine::getTargetFeatureString
*/
const char * LLVMTargetMachineGetFS(LLVMTargetMachineRef tm);
/*
* Wraps TargetRegister::printRegisteredTargetsForVersion
*/
void LLVMPrintRegisteredTargetsForVersion();
/*
* Wraps TargetMachine::addPassesToEmitFile
*/
unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly,
size_t * lenp, std::string &error);
/*
* Wraps IRBuilder::CreateFence
*/
LLVMValueRef LLVMBuildFence(LLVMBuilderRef builder, const char* ordering,
int crossthread);
/*
* Wraps IRBuilder::CreateLoad, LoadInst::setAtomic
*/
LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr,
unsigned align, const char* ordering,
int crossthread);
/*
* Wraps IRBuilder::CreateStore, StoreInst::setAtomic
*/
LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder,
LLVMValueRef ptr, LLVMValueRef val,
unsigned align, const char* ordering,
int crossthread);
/*
* Wraps IRBuilder::CreateAtomicRMW
*/
LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef builder, const char * op,
LLVMValueRef ptr, LLVMValueRef val,
const char* ordering, int crossthread);
/*
* Wraps IRBuilder::CreateAtomicCmpXchg
*/
LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr,
LLVMValueRef cmp, LLVMValueRef val,
const char* ordering, int crossthread);
/*
* Wraps new EngineBuilder
*/
LLVMEngineBuilderRef LLVMCreateEngineBuilder(LLVMModuleRef mod);
/*
* Wraps delete EngineBuilder
*/
void LLVMDisposeEngineBuilder(LLVMEngineBuilderRef eb);
/*
* Wraps EngineBuilder::setEngineKind(EngineKind::JIT)
*/
void LLVMEngineBuilderForceJIT(LLVMEngineBuilderRef eb);
/*
* Wraps EngineBuilder::setEngineKind(EngineKind::Interpreter)
*/
void LLVMEngineBuilderForceInterpreter(LLVMEngineBuilderRef eb);
/*
* Wraps EngineBuilder::setOptLevel
*/
void LLVMEngineBuilderSetOptLevel(LLVMEngineBuilderRef eb, int level);
/*
* Wraps EngineBuilder::setMCPU
*/
void LLVMEngineBuilderSetMCPU(LLVMEngineBuilderRef eb, const char * mcpu);
/*
* Wraps EngineBuilder::setMAttrs
*/
void LLVMEngineBuilderSetMAttrs(LLVMEngineBuilderRef eb, const char * mattrs);
/*
* Wraps EngineBuilder::setErrorStr and EngineBuilder::create
*/
LLVMExecutionEngineRef LLVMEngineBuilderCreate(LLVMEngineBuilderRef eb,
std::string &error);
/*
* Wraps EngineBuilder::create(TargetMachine*)
*/
LLVMExecutionEngineRef LLVMEngineBuilderCreateTM(LLVMEngineBuilderRef ebref,
LLVMTargetMachineRef tmref,
std::string & error);
/*
* Wraps PassManagerBuilder::OptLevel
*/
int LLVMPassManagerBuilderGetOptLevel(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::SizeLevel
*/
int LLVMPassManagerBuilderGetSizeLevel(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::Vectorize
*/
void LLVMPassManagerBuilderSetVectorize(LLVMPassManagerBuilderRef pmb, int flag);
/*
* Wraps PassManagerBuilder::Vectorize
*/
int LLVMPassManagerBuilderGetVectorize(LLVMPassManagerBuilderRef pmb);
#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2
/*
* Wraps PassManagerBuilder::LoopVectorize
*/
void LLVMPassManagerBuilderSetLoopVectorize(LLVMPassManagerBuilderRef pmb,
int flag);
/*
* Wraps PassManagerBuilder::LoopVectorize
*/
int LLVMPassManagerBuilderGetLoopVectorize(LLVMPassManagerBuilderRef pmb);
#endif // llvm-3.2
/*
* Wraps PassManagerBuilder::DisableUnitAtATime
*/
int LLVMPassManagerBuilderGetDisableUnitAtATime(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::DisableUnrollLoops
*/
int LLVMPassManagerBuilderGetDisableUnrollLoops(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::DisableSimplifyLibCalls
*/
int LLVMPassManagerBuilderGetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManager::add
*/
int LLVMAddPassByName(LLVMPassManagerRef pm, const char * name);
/*
* Wraps initialize*
*/
void LLVMInitializePasses(void);
/*
* Wraps PassRegistry::enumerateWith()
* Returns a '\n' separated string of all passes available to `opt`.
*/
const char * LLVMDumpPasses(void);
/*
* Wraps StructType::isLiteral()
*/
int LLVMIsLiteralStruct(LLVMTypeRef type);
/*
* Wraps StructType::create()
*/
LLVMTypeRef LLVMStructTypeIdentified(const char * name);
/*
* StructType::setBody()
*/
void LLVMSetStructBody(LLVMTypeRef type, LLVMTypeRef* elemtys, unsigned elemct, int is_packed);
/*
* Wraps llvm::StructType::setName()
*/
void LLVMSetStructName(LLVMTypeRef type, const char * name);
/*
* Wraps llvm::Module::getModuleIdentifier()
*/
char *LLVMGetModuleIdentifier(LLVMModuleRef module);
/*
* Wraps llvm::Module::setModuleIdentifier()
*/
void LLVMSetModuleIdentifier(LLVMModuleRef module, const char * name);
/* Notes:
* - Some returned strings must be disposed of by LLVMDisposeMessage. These are
* indicated in the comments. Where it is not indicated, DO NOT call dispose.
*/
/* Wraps llvm::Module::print(). Dispose the returned string after use, via
* LLVMDisposeMessage(). */
char *LLVMDumpModuleToString(LLVMModuleRef module);
/* Wraps llvm::Module::addLibrary(name). */
void LLVMModuleAddLibrary(LLVMModuleRef module, const char *name);
/* Wraps llvm::Type::print(). Dispose the returned string after use, via
* LLVMDisposeMessage(). */
char *LLVMDumpTypeToString(LLVMTypeRef type);
/* Wraps llvm::Value::print(). Dispose the returned string after use, via
* LLVMDisposeMessage(). */
char *LLVMDumpValueToString(LLVMValueRef Val);
/* Wraps llvm::IRBuilder::CreateRet(). */
LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef bulder, LLVMValueRef *values,
unsigned n_values);
/* Wraps llvm::IRBuilder::CreateGetResult(). */
LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value,
unsigned index, const char *name);
/* Wraps llvm::Value::getValueID(). */
unsigned LLVMValueGetID(LLVMValueRef value);
/* Wraps llvm::Value::getNumUses(). */
unsigned LLVMValueGetNumUses(LLVMValueRef value);
/* Wraps llvm::Value::use_{begin,end}. Allocates LLVMValueRef's as
* required. Number of objects are returned as return value. If that is
* greater than zero, the pointer given out must be freed by a
* subsequent call to LLVMDisposeValueRefArray(). */
unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs);
/* See above. */
void LLVMDisposeValueRefArray(LLVMValueRef *refs);
/* Wraps llvm:User::getNumOperands(). */
unsigned LLVMUserGetNumOperands(LLVMValueRef user);
/* Wraps llvm:User::getOperand(). */
LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx);
/* Wraps llvm::ConstantExpr::getVICmp(). */
LLVMValueRef LLVMConstVICmp(LLVMIntPredicate predicate, LLVMValueRef lhs,
LLVMValueRef rhs);
/* Wraps llvm::ConstantExpr::getVFCmp(). */
LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate predicate, LLVMValueRef lhs,
LLVMValueRef rhs);
/* Wraps llvm::IRBuilder::CreateVICmp(). */
LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef builder, LLVMIntPredicate predicate,
LLVMValueRef lhs, LLVMValueRef rhs, const char *name);
/* Wraps llvm::IRBuilder::CreateVFCmp(). */
LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef builder, LLVMRealPredicate predicate,
LLVMValueRef lhs, LLVMValueRef rhs, const char *name);
/* Wraps llvm::Intrinsic::getDeclaration(). */
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef builder, int id,
LLVMTypeRef *types, unsigned n_types);
/* Wraps llvm::Function::doesNotThrow(). */
unsigned LLVMGetDoesNotThrow(LLVMValueRef fn);
/* Wraps llvm::Function::setDoesNotThrow(). */
void LLVMSetDoesNotThrow(LLVMValueRef fn, int DoesNotThrow);
/* Wraps llvm::Module::getPointerSize(). */
unsigned LLVMModuleGetPointerSize(LLVMModuleRef module);
/* Wraps llvm::Module::getOrInsertFunction(). */
LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module,
const char *name, LLVMTypeRef function_type);
/* Wraps llvm::GlobalVariable::hasInitializer(). */
int LLVMHasInitializer(LLVMValueRef global_var);
/* The following functions wrap various llvm::Instruction::isXXX() functions.
* All of them take an instruction and return 0 (isXXX returned false) or 1
* (isXXX returned false). */
unsigned LLVMInstIsTerminator (LLVMValueRef inst);
unsigned LLVMInstIsBinaryOp (LLVMValueRef inst);
unsigned LLVMInstIsShift (LLVMValueRef inst);
unsigned LLVMInstIsCast (LLVMValueRef inst);
unsigned LLVMInstIsLogicalShift (LLVMValueRef inst);
unsigned LLVMInstIsArithmeticShift (LLVMValueRef inst);
unsigned LLVMInstIsAssociative (LLVMValueRef inst);
unsigned LLVMInstIsCommutative (LLVMValueRef inst);
unsigned LLVMInstIsTrapping (LLVMValueRef inst);
/* As above, but these are wrap methods from subclasses of Instruction. */
unsigned LLVMInstIsVolatile (LLVMValueRef inst);
/* Wraps llvm::Instruction::getOpcodeName(). */
const char *LLVMInstGetOpcodeName(LLVMValueRef inst);
/* Wraps llvm::Instruction::getOpcode(). */
unsigned LLVMInstGetOpcode(LLVMValueRef inst);
/* Wraps llvm::CmpInst::getPredicate(). */
unsigned LLVMCmpInstGetPredicate(LLVMValueRef cmpinst);
/* Wraps llvm::CallSite::getCalledFunction.
*/
LLVMValueRef LLVMInstGetCalledFunction(LLVMValueRef inst);
/* Wraps llvm::CallSite::setCalledFunction.
*/
void LLVMInstSetCalledFunction(LLVMValueRef inst, LLVMValueRef fn);
/* Wraps llvm::ParseAssemblyString(). Returns a module reference or NULL (with
* `out' pointing to an error message). Dispose error message after use, via
* LLVMDisposeMessage(). */
LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtxt, char **out);
/* Wraps llvm::ParseBitcodeFile(). Returns a module reference or NULL (with
* `out' pointing to an error message). Dispose error message after use, via
* LLVMDisposeMessage(). */
LLVMModuleRef LLVMGetModuleFromBitcode(const char *bc, unsigned bclen,
char **out);
#if LLVM_VERSION_MAJOR <= 3 && LLVM_VERSION_MINOR < 2
/* Wraps llvm::Linker::LinkModules(). Returns 0 on failure (with errmsg
* filled in) and 1 on success. Dispose error message after use with
* LLVMDisposeMessage(). */
unsigned LLVMLinkModules(LLVMModuleRef dest, LLVMModuleRef src, int mode,
char **errmsg);
#endif
/* Returns pointer to a heap-allocated block of `*len' bytes containing bit code
* for the given module. NULL on error. */
unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, size_t *len);
/* Wraps llvm::sys::DynamicLibrary::LoadLibraryPermanently(). Returns 0 on
* failure (with errmsg filled in) and 1 on success. Dispose error message after
* use, via LLVMDisposeMessage(). */
unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg);
/* Wraps llvm::ExecutionEngine::DisableLazyCompilation(bool)
*/
void LLVMExecutionEngineDisableLazyCompilation(LLVMExecutionEngineRef ee,
int flag);
/* Wraps llvm::ExecutionEngine::getPointerToFunction(). Returns a pointer
* to the JITted function. */
void *LLVMGetPointerToFunction(LLVMExecutionEngineRef ee, LLVMValueRef fn);
/* Wraps llvm::InlineFunction(). Inlines a function. C is the call
* instruction, created by LLVMBuildCall. Even if it fails, the Function
* containing the call is still in a proper state (not changed).
*/
int LLVMInlineFunction(LLVMValueRef call);
/* Wraps llvm::getAlignmentFromAttrs from Attributes.h. Compliments the
* already available LLVMSetParamAlignment(). */
unsigned LLVMGetParamAlignment(LLVMValueRef arg);
/* Passes. Some passes are used directly from LLVM-C, rest are declared
* here. */
/*
#define declare_pass(P) \
void LLVMAdd ## P ## Pass (LLVMPassManagerRef PM);
declare_pass( AAEval )
declare_pass( AliasAnalysisCounter )
declare_pass( AlwaysInliner )
declare_pass( BasicAliasAnalysis )
declare_pass( BlockPlacement )
declare_pass( BreakCriticalEdges )
declare_pass( CodeGenPrepare )
declare_pass( DbgInfoPrinter )
declare_pass( DeadCodeElimination )
declare_pass( DeadInstElimination )
declare_pass( DemoteRegisterToMemory )
declare_pass( DomOnlyPrinter )
declare_pass( DomOnlyViewer )
declare_pass( DomPrinter )
declare_pass( DomViewer )
declare_pass( EdgeProfiler )
//declare_pass( GEPSplitter )
declare_pass( GlobalsModRef )
declare_pass( InstCount )
declare_pass( InstructionNamer )
declare_pass( LazyValueInfo )
declare_pass( LCSSA )
//declare_pass( LiveValues )
declare_pass( LoopDependenceAnalysis )
declare_pass( LoopExtractor )
declare_pass( LoopSimplify )
declare_pass( LoopStrengthReduce )
declare_pass( LowerInvoke )
declare_pass( LowerSwitch )
declare_pass( MergeFunctions )
declare_pass( NoAA )
declare_pass( NoProfileInfo )
declare_pass( OptimalEdgeProfiler )
declare_pass( PartialInlining )
//declare_pass( PartialSpecialization )
declare_pass( PostDomOnlyPrinter )
declare_pass( PostDomOnlyViewer )
declare_pass( PostDomPrinter )
declare_pass( PostDomViewer )
declare_pass( ProfileEstimator )
declare_pass( ProfileLoader )
declare_pass( ProfileVerifier )
declare_pass( ScalarEvolutionAliasAnalysis )
declare_pass( SimplifyHalfPowrLibCalls )
declare_pass( SingleLoopExtractor )
declare_pass( StripNonDebugSymbols )
declare_pass( StructRetPromotion )
declare_pass( TailDuplication )
declare_pass( UnifyFunctionExitNodes )
declare_pass( Internalize2 )
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LLVM_PY_EXTRA_H */

View file

@ -1,31 +0,0 @@
#ifndef LLVM_C_EXTRA_H_
#define LLVM_C_EXTRA_H_
#include <llvm-c/Core.h>
#ifdef __cplusplus
extern "C" {
#endif
// Resurrect from llvm-c/Core.h
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
inline ty *unwrap(ref P) { \
return reinterpret_cast<ty*>(P); \
} \
\
inline ref wrap(const ty *P) { \
return reinterpret_cast<ref>(const_cast<ty*>(P)); \
}
typedef struct LLVMOpaqueEngineBuilder *LLVMEngineBuilderRef;
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
typedef struct LLVMOpaqueNamedMD *LLVMNamedMDRef;
typedef struct LLVMOpaquePass *LLVMPassRef;
#ifdef __cplusplus
}
#endif
#endif //LLVM_C_EXTRA_H_

View file

@ -37,122 +37,99 @@ are available.
import llvm # top-level, for common stuff
import llvm.core as core # module, function etc.
import llvm._core as _core # C wrappers
import llvm._util as _util # Utility functions
from llvmpy import api
import warnings
#===----------------------------------------------------------------------===
# Pass manager builder
#===----------------------------------------------------------------------===
class PassManagerBuilder(object):
class PassManagerBuilder(llvm.Wrapper):
@staticmethod
def new():
return PassManagerBuilder(_core.LLVMPassManagerBuilderCreate())
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMPassManagerBuilderDispose(self.ptr)
return PassManagerBuilder(api.llvm.PassManagerBuilder.new())
def populate(self, pm):
if isinstance(pm, FunctionPassManager):
return _core.LLVMPassManagerBuilderPopulateFunctionPassManager(
self.ptr, pm.ptr)
self._ptr.populateFunctionPassManager(pm._ptr)
else:
return _core.LLVMPassManagerBuilderPopulateModulePassManager(
self.ptr, pm.ptr)
self._ptr.populateModulePassManager(pm._ptr)
@property
def opt_level(self):
return self._ptr.OptLevel
def _set_opt_level(self, optlevel):
_core.LLVMPassManagerBuilderSetOptLevel(self.ptr, optlevel)
@opt_level.setter
def opt_level(self, optlevel):
self._ptr.OptLevel = optlevel
def _get_opt_level(self):
return _core.LLVMPassManagerBuilderGetOptLevel(self.ptr)
@property
def size_level(self):
return self._ptr.SizeLevel
opt_level = property(_get_opt_level, _set_opt_level)
@size_level.setter
def size_level(self, sizelevel):
self._ptr.SizeLevel = sizelevel
def _set_size_level(self, sizelevel):
_core.LLVMPassManagerBuilderSetSizeLevel(self.ptr, sizelevel)
@property
def vectorize(self):
return self._ptr.Vectorize
def _get_size_level(self):
return _core.LLVMPassManagerBuilderGetSizeLevel(self.ptr)
@vectorize.setter
def vectorize(self, enable):
self._ptr.Vectorize = enable
size_level = property(_get_size_level, _set_size_level)
def _set_vectorize(self, enable):
_core.LLVMPassManagerBuilderSetVectorize(self.ptr, int(bool(enable)))
def _get_vectorize(self):
return bool(_core.LLVMPassManagerBuilderGetVectorize(self.ptr))
vectorize = property(_get_vectorize, _set_vectorize)
def _set_loop_vectorize(self, enable):
if llvm.version >= (3, 2):
_core.LLVMPassManagerBuilderSetLoopVectorize(self.ptr,
int(bool(enable)))
elif enable:
warnings.warn("Ignored. LLVM-3.1 & prior do not support loop vectorizer.")
def _get_loop_vectorize(self):
@property
def loop_vectorize(self):
try:
return bool(_core.LLVMPassManagerBuilderGetLoopVectorize(self.ptr))
return self._ptr.LoopVectorize
except AttributeError:
return False
loop_vectorize = property(_get_loop_vectorize, _set_loop_vectorize)
@loop_vectorize.setter
def loop_vectorize(self, enable):
if llvm.version >= (3, 2):
self._ptr.LoopVectorize = enable
elif enable:
warnings.warn("Ignored. LLVM-3.1 & prior do not support loop vectorizer.")
def _set_disable_unit_at_a_time(self, disable):
return _core.LLVMPassManagerBuilderSetDisableUnitAtATime(
self.ptr, disable)
@property
def disable_unit_at_a_time(self):
return self._ptr.DisableUnitAtATime
def _get_disable_unit_at_a_time(self):
return _core.LLVMPassManagerBuilderGetDisableUnitAtATime(
self.ptr)
@disable_unit_at_a_time.setter
def disable_unit_at_a_time(self, disable):
self._ptr.DisableUnitAtATime = disable
disable_unit_at_a_time = property(_get_disable_unit_at_a_time,
_set_disable_unit_at_a_time)
@property
def disable_unroll_loops(self):
return self._ptr.DisableUnrollLoops
def _set_disable_unroll_loops(self, disable):
return _core.LLVMPassManagerBuilderGetDisableUnrollLoops(
self.ptr, disable)
@disable_unroll_loops.setter
def disable_unroll_loops(self, disable):
self._ptr.DisableUnrollLoops = disable
def _get_disable_unroll_loops(self):
return _core.LLVMPassManagerBuilderGetDisableUnrollLoops(self.ptr)
@property
def disable_simplify_lib_calls(self):
return self._ptr.DisableSimplifyLibCalls
disable_unroll_loops = property(_get_disable_unroll_loops,
_set_disable_unroll_loops)
def _set_disable_simplify_lib_calls(self, disable):
return _core.LLVMPassManagerBuilderGetDisableSimplifyLibCalls(
self.ptr, disable)
def _get_disable_simplify_lib_calls(self):
return _core.LLVMPassManagerBuilderGetDisableSimplifyLibCalls(self.ptr)
disable_simplify_lib_calls = property(_get_disable_simplify_lib_calls,
_set_disable_simplify_lib_calls)
@disable_simplify_lib_calls.setter
def disable_simplify_lib_calls(self, disable):
self._ptr.DisableSimplifyLibCalls = disable
def use_inliner_with_threshold(self, threshold):
_core.LLVMPassManagerBuilderUseInlinerWithThreshold(self.ptr, threshold)
self._ptr.Inliner = api.llvm.createFunctionInliningPass(threshold)
#===----------------------------------------------------------------------===
# Pass manager
#===----------------------------------------------------------------------===
class PassManager(object):
class PassManager(llvm.Wrapper):
@staticmethod
def new():
return PassManager(_core.LLVMCreatePassManager())
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMDisposePassManager(self.ptr)
return PassManager(api.llvm.PassManager.new())
def add(self, pass_obj):
'''Add a pass to the pass manager.
@ -160,68 +137,59 @@ class PassManager(object):
pass_obj --- Either a Pass instance, a string name of a pass
'''
if isinstance(pass_obj, Pass):
_util.check_is_unowned(pass_obj)
_core.LLVMAddPass(self.ptr, pass_obj.ptr)
pass_obj._own(self) # PassManager owns the pass
elif _util.isstring(pass_obj):
self._add_pass(pass_obj)
self._ptr.add(pass_obj._ptr)
else:
raise llvm.LLVMException("invalid pass_id (%s)" % pass_obj)
self._add_pass(str(pass_obj))
def _add_pass(self, pass_name):
status = _core.LLVMAddPassByName(self.ptr, pass_name)
if not status:
passreg = api.llvm.PassRegistry.getPassRegistry()
a_pass = passreg.getPassInfo(pass_name).createPass()
if not a_pass:
assert pass_name not in PASSES, "Registered but not found?"
raise llvm.LLVMException('Invalid pass name "%s"' % pass_name)
self._ptr.add(a_pass)
def run(self, module):
core.check_is_module(module)
return _core.LLVMRunPassManager(self.ptr, module.ptr)
return self._ptr.run(module._ptr)
class FunctionPassManager(PassManager):
@staticmethod
def new(module):
core.check_is_module(module)
ptr = _core.LLVMCreateFunctionPassManagerForModule(module.ptr)
ptr = api.llvm.FunctionPassManager.new(module._ptr)
return FunctionPassManager(ptr)
def __init__(self, ptr):
PassManager.__init__(self, ptr)
def initialize(self):
_core.LLVMInitializeFunctionPassManager(self.ptr)
self._ptr.doInitialization()
def run(self, fn):
core.check_is_function(fn)
return _core.LLVMRunFunctionPassManager(self.ptr, fn.ptr)
return self._ptr.run(fn._ptr)
def finalize(self):
_core.LLVMFinalizeFunctionPassManager(self.ptr)
self._ptr.doFinalization()
#===----------------------------------------------------------------------===
# Passes
#===----------------------------------------------------------------------===
class Pass(llvm.Ownable):
class Pass(llvm.Wrapper):
'''Pass Inferface
'''
def __init__(self, ptr):
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposePass)
self.__name = ''
'''
@staticmethod
def new(name):
'''Create a new pass by name.
Note: Not all pass has a default constructor. LLVM will kill
the process if an the pass requires arguments to construct.
The error cannot be caught.
'''
ptr = _core.LLVMCreatePassByName(name)
p = Pass(ptr)
Note: Not all pass has a default constructor. LLVM will kill
the process if an the pass requires arguments to construct.
The error cannot be caught.
'''
passreg = api.llvm.PassRegistry.getPassRegistry()
a_pass = passreg.getPassInfo(name).createPass()
p = Pass(a_pass)
p.__name = name
return p
@ -229,15 +197,17 @@ class Pass(llvm.Ownable):
def name(self):
'''The name used in PassRegistry.
'''
return self.__name
try:
return self.__name
except AttributeError:
return
@property
def description(self):
return _core.LLVMGetPassName(self.ptr)
return self._ptr.getPassName()
def dump(self):
return _core.LLVMPassDump(self.ptr)
return self._ptr.dump()
#===----------------------------------------------------------------------===
# Target data
@ -247,67 +217,59 @@ class TargetData(Pass):
@staticmethod
def new(strrep):
return TargetData(_core.LLVMCreateTargetData(strrep))
ptr = api.llvm.DataLayout.new(strrep)
return TargetData(ptr)
def clone(self):
return TargetData.new(str(self))
def __str__(self):
return _core.LLVMTargetDataAsString(self.ptr)
return self._ptr.getStringRepresentation()
@property
def byte_order(self):
return _core.LLVMByteOrder(self.ptr)
if self._ptr.isLittleEndian():
return 1
else:
return 0
@property
def pointer_size(self):
return _core.LLVMPointerSize(self.ptr)
return self._ptr.getPointerSize()
@property
def target_integer_type(self):
ptr = _core.LLVMIntPtrType(self.ptr);
return core.IntegerType(ptr, core.TYPE_INTEGER)
context = api.llvm.getGlobalContext()
return api.llvm.IntegerType(api.llvm.Type.getInt32Ty(context))
def size(self, ty):
core.check_is_type(ty)
return _core.LLVMSizeOfTypeInBits(self.ptr, ty.ptr)
return self._ptr.getTypeSizeInBits(ty._ptr)
def store_size(self, ty):
core.check_is_type(ty)
return _core.LLVMStoreSizeOfType(self.ptr, ty.ptr)
return self._ptr.getTypeStoreSize(ty._ptr)
def abi_size(self, ty):
core.check_is_type(ty)
return _core.LLVMABISizeOfType(self.ptr, ty.ptr)
return self._ptr.getTypeAllocSize(ty._ptr)
def abi_alignment(self, ty):
core.check_is_type(ty)
return _core.LLVMABIAlignmentOfType(self.ptr, ty.ptr)
return self._ptr.getABITypeAlignment(ty._ptr)
def callframe_alignment(self, ty):
core.check_is_type(ty)
return _core.LLVMCallFrameAlignmentOfType(self.ptr, ty.ptr)
return self._ptr.getCallFrameTypeAlignment(ty._ptr)
def preferred_alignment(self, ty_or_gv):
if isinstance(ty_or_gv, core.Type):
return _core.LLVMPreferredAlignmentOfType(self.ptr,
ty_or_gv.ptr)
return self._ptr.getPrefTypeAlignment(ty_or_gv._ptr)
elif isinstance(ty_or_gv, core.GlobalVariable):
return _core.LLVMPreferredAlignmentOfGlobal(self.ptr,
ty_or_gv.ptr)
return self._ptr.getPreferredAlignment(ty_or_gv._ptr)
else:
raise core.LLVMException("argument is neither a type nor a global variable")
def element_at_offset(self, ty, ofs):
core.check_is_type_struct(ty)
ofs = int(ofs) # ofs is unsigned long long
return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs)
return self._ptr.getStructLayout(ty._ptr).getElementContainingOffset(ofs)
def offset_of_element(self, ty, el):
core.check_is_type_struct(ty)
el = int(el) # el should be an int
return _core.LLVMOffsetOfElement(self.ptr, ty.ptr, el)
return self._ptr.getStructLayout(ty._ptr).getElementOffset(el)
#===----------------------------------------------------------------------===
# Target Library Info
@ -316,19 +278,20 @@ class TargetData(Pass):
class TargetLibraryInfo(Pass):
@staticmethod
def new(triple):
ptr = _core.LLVMCreateTargetLibraryInfo(triple)
triple = api.llvm.Triple.new(str(triple))
ptr = api.llvm.TargetLibraryInfo.new(triple)
return TargetLibraryInfo(ptr)
#===----------------------------------------------------------------------===
# Target Transform Info
# Target Transformation Info
#===----------------------------------------------------------------------===
class TargetTransformInfo(Pass):
@staticmethod
def new(targetmachine):
llvm.require_version_at_least(3, 2)
ptr = _core.LLVMCreateTargetTransformInfo(targetmachine.ptr)
scalartti = targetmachine._ptr.getScalarTargetTransformInfo()
vectortti = targetmachine._ptr.getVectorTargetTransformInfo()
ptr = api.llvm.TargetTransformInfo.new(scalartti, vectortti)
return TargetTransformInfo(ptr)
@ -339,18 +302,18 @@ class TargetTransformInfo(Pass):
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.
loop_vectorize --- [boolean] Whether to use loop-vectorizer.
vectorize --- [boolean] Whether to use basic-block vectorizer.
inline_threshold --- [int] Threshold for the inliner.
features --- [str] CPU feature string.
pm --- [boolean] Whether to build a module-level pass-manager.
fpm --- [boolean] Whether to build a function-level pass-manager.
mod --- [Module] The module object for the FunctionPassManager.
'''
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.
loop_vectorize --- [boolean] Whether to use loop-vectorizer.
vectorize --- [boolean] Whether to use basic-block vectorizer.
inline_threshold --- [int] Threshold for the inliner.
features --- [str] CPU feature string.
pm --- [boolean] Whether to build a module-level pass-manager.
fpm --- [boolean] Whether to build a function-level pass-manager.
mod --- [Module] The module object for the FunctionPassManager.
'''
if pm:
pm = PassManager.new()
if fpm:
@ -383,7 +346,6 @@ def build_pass_managers(tm, opt=2, loop_vectorize=False, vectorize=False,
from collections import namedtuple
return namedtuple('passmanagers', ['pm', 'fpm'])(pm=pm, fpm=fpm)
#===----------------------------------------------------------------------===
# Misc.
#===----------------------------------------------------------------------===
@ -392,16 +354,26 @@ def build_pass_managers(tm, opt=2, loop_vectorize=False, vectorize=False,
PASSES = None
def _dump_all_passes():
passes_sep_by_line = _core.LLVMDumpPasses()
strip = lambda S : S.strip()
for line in passes_sep_by_line.splitlines():
passarg, passname = map(strip, line.split('\t', 1))
if passarg:
yield passarg, passname
passreg = api.llvm.PassRegistry.getPassRegistry()
for name, desc in passreg.enumerate():
yield name, desc
def _initialize_passes():
global PASSES
_core.LLVMInitializePasses()
passreg = api.llvm.PassRegistry.getPassRegistry()
api.llvm.initializeCore(passreg)
api.llvm.initializeScalarOpts(passreg)
api.llvm.initializeVectorization(passreg)
api.llvm.initializeIPO(passreg)
api.llvm.initializeAnalysis(passreg)
api.llvm.initializeIPA(passreg)
api.llvm.initializeTransformUtils(passreg)
api.llvm.initializeInstCombine(passreg)
api.llvm.initializeInstrumentation(passreg)
api.llvm.initializeTarget(passreg)
PASSES = dict(_dump_all_passes())
# build globals

View file

@ -1,973 +0,0 @@
--- .\setup-win32.py (original)
+++ .\setup-win32.py (refactored)
@@ -145,10 +145,10 @@
# get llvm config
llvm_dir, llvm_build_dir, is_good = get_llvm_config()
- print "Using llvm-dir=" + llvm_dir + " and llvm-build-dir=" + llvm_build_dir
+ print("Using llvm-dir=" + llvm_dir + " and llvm-build-dir=" + llvm_build_dir)
if not is_good:
- print "Cannot find llvm-dir or llvm-build-dir"
- print "Try again with --llvm-dir=/path/to/llvm-top-dir --llvm-build-dir=/path/to/llvm/cmake/dir."
+ print("Cannot find llvm-dir or llvm-build-dir")
+ print("Try again with --llvm-dir=/path/to/llvm-top-dir --llvm-build-dir=/path/to/llvm/cmake/dir.")
return 1
# setup
--- .\setup.py (original)
+++ .\setup.py (refactored)
@@ -120,10 +120,10 @@
# get llvm config
llvm_config, is_good = get_llvm_config()
if is_good:
- print "Using llvm-config=" + llvm_config
+ print("Using llvm-config=" + llvm_config)
else:
- print "Cannot invoke llvm-config (tried '%s')." % llvm_config
- print "Try again with --llvm-config=/path/to/llvm-config."
+ print("Cannot invoke llvm-config (tried '%s')." % llvm_config)
+ print("Try again with --llvm-config=/path/to/llvm-config.")
return 1
# setup
--- .\llvm\__init__.py (original)
+++ .\llvm\__init__.py (refactored)
@@ -68,12 +68,12 @@
def _own(self, owner):
if self.owner:
- raise LLVMException, "object already owned"
+ raise LLVMException("object already owned")
self.owner = owner
def _disown(self):
if not self.owner:
- raise LLVMException, "not owned"
+ raise LLVMException("not owned")
self.owner = None
def __del__(self):
@@ -135,15 +135,13 @@
# Cacheables
#===----------------------------------------------------------------------===
-class Cacheable(object):
+class Cacheable(object, metaclass=_ObjectCache):
"""Objects that can be cached.
Objects that wrap a PyCObject are cached to avoid "aliasing", i.e.,
two Python objects each containing a PyCObject which internally points
to the same C pointer."""
- __metaclass__ = _ObjectCache
-
def forget(self):
_ObjectCache.forget(self)
--- .\llvm\_util.py (original)
+++ .\llvm\_util.py (refactored)
@@ -45,11 +45,11 @@
if not isinstance(obj, typ):
typ_str = typ.__name__
msg = "argument not an instance of llvm.core.%s" % typ_str
- raise TypeError, msg
+ raise TypeError(msg)
def check_is_unowned(ownable):
if ownable.owner:
- raise llvm.LLVMException, "object is already owned"
+ raise llvm.LLVMException("object is already owned")
#===----------------------------------------------------------------------===
--- .\llvm\core.py (original)
+++ .\llvm\core.py (refactored)
@@ -297,7 +297,7 @@
if isinstance(typ, PointerType) and \
isinstance(typ.pointee, FunctionType):
return
- raise TypeError, "argument is neither a function nor a function pointer"
+ raise TypeError("argument is neither a function nor a function pointer")
def _to_int(v):
if v:
@@ -341,9 +341,9 @@
data = fileobj.read()
ret = _core.LLVMGetModuleFromBitcode(data)
if not ret:
- raise llvm.LLVMException, "Unable to create module from bitcode"
+ raise llvm.LLVMException("Unable to create module from bitcode")
elif isinstance(ret, str):
- raise llvm.LLVMException, ret
+ raise llvm.LLVMException(ret)
else:
return Module(ret)
@@ -355,10 +355,9 @@
data = fileobj.read()
ret = _core.LLVMGetModuleFromAssembly(data)
if not ret:
- raise llvm.LLVMException, \
- "Unable to create module from assembly"
+ raise llvm.LLVMException("Unable to create module from assembly")
elif isinstance(ret, str):
- raise llvm.LLVMException, ret
+ raise llvm.LLVMException(ret)
else:
return Module(ret)
@@ -437,7 +436,7 @@
other.forget() # remove it from object cache
ret = _core.LLVMLinkModules(self.ptr, other.ptr)
if isinstance(ret, str):
- raise llvm.LLVMException, ret
+ raise llvm.LLVMException(ret)
# Do not try to destroy the other module's llvm::Module*.
other._own(llvm.DummyOwner())
@@ -506,7 +505,7 @@
error."""
ret = _core.LLVMVerifyModule(self.ptr)
if ret != "":
- raise llvm.LLVMException, ret
+ raise llvm.LLVMException(ret)
def to_bitcode(self, fileobj):
"""Write bitcode representation of module to given file-like
@@ -514,7 +513,7 @@
data = _core.LLVMGetBitcodeFromModule(self.ptr)
if not data:
- raise llvm.LLVMException, "Unable to create bitcode"
+ raise llvm.LLVMException("Unable to create bitcode")
fileobj.write(data)
@@ -1236,7 +1235,7 @@
check_is_module(module)
ptr = _core.LLVMGetNamedGlobal(module.ptr, name)
if not ptr:
- raise llvm.LLVMException, ("no global named `%s`" % name)
+ raise llvm.LLVMException("no global named `%s`" % name)
return _make_value(ptr)
def delete(self):
@@ -1307,7 +1306,7 @@
check_is_module(module)
ptr = _core.LLVMGetNamedFunction(module.ptr, name)
if not ptr:
- raise llvm.LLVMException, ("no function named `%s`" % name)
+ raise llvm.LLVMException("no function named `%s`" % name)
return _make_value(ptr)
@staticmethod
@@ -2006,7 +2005,7 @@
ret = _core.LLVMLoadLibraryPermanently(filename)
if isinstance(ret, str):
- raise llvm.LLVMException, ret
+ raise llvm.LLVMException(ret)
def inline_function(call):
check_is_value(call)
--- .\llvm\ee.py (original)
+++ .\llvm\ee.py (refactored)
@@ -103,12 +103,11 @@
return _core.LLVMPreferredAlignmentOfGlobal(self.ptr,
ty_or_gv.ptr)
else:
- raise core.LLVMException, \
- "argument is neither a type nor a global variable"
+ raise core.LLVMException("argument is neither a type nor a global variable")
def element_at_offset(self, ty, ofs):
core.check_is_type_struct(ty)
- ofs = long(ofs) # ofs is unsigned long long
+ ofs = int(ofs) # ofs is unsigned long long
return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs)
def offset_of_element(self, ty, el):
@@ -185,7 +184,7 @@
_util.check_is_unowned(module)
ret = _core.LLVMCreateExecutionEngine(module.ptr, int(force_interpreter))
if isinstance(ret, str):
- raise llvm.LLVMException, ret
+ raise llvm.LLVMException(ret)
return ExecutionEngine(ret, module)
def __init__(self, ptr, module):
@@ -223,10 +222,10 @@
def remove_module(self, module):
core.check_is_module(module)
if module.owner != self:
- raise llvm.LLVMException, "module is not owned by self"
+ raise llvm.LLVMException("module is not owned by self")
ret = _core.LLVMRemoveModule2(self.ptr, module.ptr)
if isinstance(ret, str):
- raise llvm.LLVMException, ret
+ raise llvm.LLVMException(ret)
return core.Module(ret)
@property
--- .\llvm\passes.py (original)
+++ .\llvm\passes.py (refactored)
@@ -245,8 +245,7 @@
elif tgt_data_or_pass_id in _pass_creator:
self._add_pass(tgt_data_or_pass_id)
else:
- raise llvm.LLVMException, \
- ("invalid pass_id (%s)" % str(tgt_data_or_pass_id))
+ raise llvm.LLVMException("invalid pass_id (%s)" % str(tgt_data_or_pass_id))
def _add_target_data(self, tgt):
_core.LLVMAddTargetData(tgt.ptr, self.ptr)
--- .\test\JITTutorial1.py (original)
+++ .\test\JITTutorial1.py (refactored)
@@ -28,4 +28,4 @@
bldr.ret (tmp_2)
-print module
+print(module)
--- .\test\JITTutorial2.py (original)
+++ .\test\JITTutorial2.py (refactored)
@@ -47,4 +47,4 @@
recur_2 = bldr.call (gcd, (x_sub_y, y,), "tmp")
bldr.ret (recur_2)
-print module
+print(module)
--- .\test\asm.py (original)
+++ .\test\asm.py (refactored)
@@ -9,9 +9,9 @@
# write it's assembly representation to a file
asm = str(m)
-print >> file("/tmp/testasm.ll", "w"), asm
+print(asm, file=file("/tmp/testasm.ll", "w"))
# read it back into a module
m2 = Module.from_assembly(file("/tmp/testasm.ll"))
-print m2
+print(m2)
--- .\test\call-jit-ctypes.py (original)
+++ .\test\call-jit-ctypes.py (refactored)
@@ -42,7 +42,7 @@
if 0:
# print the created module
- print my_module
+ print(my_module)
# compile the function
ee = ExecutionEngine.new(my_module)
--- .\test\example-jit.py (original)
+++ .\test\example-jit.py (refactored)
@@ -29,5 +29,5 @@
retval = ee.run_function(f_sum, [arg1, arg2])
# The return value is also GenericValue. Let's print it.
-print "returned", retval.as_int()
+print("returned", retval.as_int())
--- .\test\example.py (original)
+++ .\test\example.py (refactored)
@@ -41,5 +41,5 @@
# We've completed the definition now! Let's see the LLVM assembly
# language representation of what we've created:
-print my_module
+print(my_module)
--- .\test\intrinsic.py (original)
+++ .\test\intrinsic.py (refactored)
@@ -16,7 +16,7 @@
val = Constant.int(Type.int(), 42)
bswap = Function.intrinsic(mod, INTR_BSWAP, [Type.int()])
b.call(bswap, [val])
-print mod
+print(mod)
# the output is:
#
@@ -50,7 +50,7 @@
onemc2 = b.sub(one, cos2, "onemc2")
sin = b.call(sqrt, [onemc2], "sin")
b.ret(sin)
-print mod
+print(mod)
#
# ; ModuleID = 'test'
--- .\test\objcache.py (original)
+++ .\test\objcache.py (refactored)
@@ -4,17 +4,17 @@
def check(a, b):
if a is b:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
def check_isnot(a, b):
if not (a is b):
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
-print "Testing module aliasing ..",
+print("Testing module aliasing ..", end=' ')
m1 = Module.new('a')
t = Type.int()
ft = Type.function(t, [t])
@@ -22,75 +22,75 @@
m2 = f1.module
check(m1, m2)
-print "Testing global vairable aliasing 1 .. ",
+print("Testing global vairable aliasing 1 .. ", end=' ')
gv1 = GlobalVariable.new(m1, t, "gv")
gv2 = GlobalVariable.get(m1, "gv")
check(gv1, gv2)
-print "Testing global vairable aliasing 2 .. ",
+print("Testing global vairable aliasing 2 .. ", end=' ')
gv3 = m1.global_variables[0]
check(gv1, gv3)
-print "Testing global vairable aliasing 3 .. ",
+print("Testing global vairable aliasing 3 .. ", end=' ')
gv2 = None
gv3 = None
gv1.delete()
gv4 = GlobalVariable.new(m1, t, "gv")
check_isnot(gv1, gv4)
-print "Testing function aliasing 1 ..",
+print("Testing function aliasing 1 ..", end=' ')
b1 = f1.append_basic_block('entry')
f2 = b1.function
check(f1, f2)
-print "Testing function aliasing 2 ..",
+print("Testing function aliasing 2 ..", end=' ')
f3 = m1.get_function_named("func")
check(f1, f3)
-print "Testing function aliasing 3 ..",
+print("Testing function aliasing 3 ..", end=' ')
f4 = Function.get_or_insert(m1, ft, "func")
check(f1, f4)
-print "Testing function aliasing 4 ..",
+print("Testing function aliasing 4 ..", end=' ')
f5 = Function.get(m1, "func")
check(f1, f5)
-print "Testing function aliasing 5 ..",
+print("Testing function aliasing 5 ..", end=' ')
f6 = m1.get_or_insert_function(ft, "func")
check(f1, f6)
-print "Testing function aliasing 6 ..",
+print("Testing function aliasing 6 ..", end=' ')
f7 = m1.functions[0]
check(f1, f7)
-print "Testing argument aliasing .. ",
+print("Testing argument aliasing .. ", end=' ')
a1 = f1.args[0]
a2 = f1.args[0]
check(a1, a2)
-print "Testing basic block aliasing 1 .. ",
+print("Testing basic block aliasing 1 .. ", end=' ')
b2 = f1.basic_blocks[0]
check(b1, b2)
-print "Testing basic block aliasing 2 .. ",
+print("Testing basic block aliasing 2 .. ", end=' ')
b3 = f1.get_entry_basic_block()
check(b1, b3)
-print "Testing basic block aliasing 3 .. ",
+print("Testing basic block aliasing 3 .. ", end=' ')
b31 = f1.entry_basic_block
check(b1, b31)
-print "Testing basic block aliasing 4 .. ",
+print("Testing basic block aliasing 4 .. ", end=' ')
bldr = Builder.new(b1)
b4 = bldr.basic_block
check(b1, b4)
-print "Testing basic block aliasing 5 .. ",
+print("Testing basic block aliasing 5 .. ", end=' ')
i1 = bldr.ret_void()
b5 = i1.basic_block
check(b1, b5)
-print "Testing instruction aliasing 1 .. ",
+print("Testing instruction aliasing 1 .. ", end=' ')
i2 = b5.instructions[0]
check(i1, i2)
@@ -100,9 +100,9 @@
v2 = phi.get_incoming_value(0)
b6 = phi.get_incoming_block(0)
-print "Testing PHI / basic block aliasing 5 .. ",
+print("Testing PHI / basic block aliasing 5 .. ", end=' ')
check(b1, b6)
-print "Testing PHI / value aliasing .. ",
+print("Testing PHI / value aliasing .. ", end=' ')
check(f1.args[0], v2)
--- .\test\operands.py (original)
+++ .\test\operands.py (refactored)
@@ -28,9 +28,9 @@
def __init__(self): pass
def read(self): return test_module
m = Module.from_assembly(strstream())
-print "-"*60
-print m
-print "-"*60
+print("-"*60)
+print(m)
+print("-"*60)
test_func = m.get_function_named("test_func")
prod = m.get_function_named("prod")
@@ -38,16 +38,16 @@
#===----------------------------------------------------------------------===
# test operands
-print
+print()
i1 = test_func.basic_blocks[0].instructions[0]
i2 = test_func.basic_blocks[0].instructions[1]
-print "Testing User.operand_count ..",
+print("Testing User.operand_count ..", end=' ')
if i1.operand_count == 3 and i2.operand_count == 2:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
-print "Testing User.operands ..",
+print("Testing User.operands ..", end=' ')
c1 = i1.operands[0] is prod
c2 = i1.operands[1] is test_func.args[0]
c3 = i1.operands[2] is test_func.args[1]
@@ -56,22 +56,22 @@
c6 = len(i1.operands) == 3
c7 = len(i2.operands) == 2
if c1 and c2 and c3 and c5 and c6 and c7:
- print "OK"
+ print("OK")
else:
- print "FAIL"
-print
+ print("FAIL")
+print()
#===----------------------------------------------------------------------===
# show test_function
-print "Examining test_function `test_test_func':"
+print("Examining test_function `test_test_func':")
idx = 1
for inst in test_func.basic_blocks[0].instructions:
- print "Instruction #%d:" % (idx,)
- print " operand_count =", inst.operand_count
- print " operands:"
+ print("Instruction #%d:" % (idx,))
+ print(" operand_count =", inst.operand_count)
+ print(" operands:")
oidx = 1
for op in inst.operands:
- print " %d: %s" % (oidx, repr(op))
+ print(" %d: %s" % (oidx, repr(op)))
oidx += 1
idx += 1
--- .\test\passes.py (original)
+++ .\test\passes.py (refactored)
@@ -36,8 +36,8 @@
}
"""
m = Module.from_assembly(strstream(asm))
-print "-"*72
-print m
+print("-"*72)
+print(m)
# Let's run a module-level inlining pass. First, create a pass manager.
pm = PassManager.new()
@@ -55,8 +55,8 @@
del pm
# Print the result. Note the change in @test2.
-print "-"*72
-print m
+print("-"*72)
+print(m)
# Let's run a DCE pass on the the function 'test1' now. First create a
@@ -73,5 +73,5 @@
fpm.run( m.get_function_named('test1') )
# Print the result. Note the change in @test1.
-print "-"*72
-print m
+print("-"*72)
+print(m)
--- .\test\test.py (original)
+++ .\test\test.py (refactored)
@@ -69,7 +69,7 @@
# done
if gc.garbage:
- print "garbage = ", gc.garbage
+ print("garbage = ", gc.garbage)
main()
--- .\test\testall.py (original)
+++ .\test\testall.py (refactored)
@@ -15,12 +15,12 @@
def do_llvmexception():
- print " Testing class LLVMException"
+ print(" Testing class LLVMException")
e = LLVMException()
def do_ownable():
- print " Testing class Ownable"
+ print(" Testing class Ownable")
o = Ownable(None, lambda x: None)
try:
o._own(None)
@@ -30,7 +30,7 @@
def do_misc():
- print " Testing miscellaneous functions"
+ print(" Testing miscellaneous functions")
try:
load_library_permanently("/usr/lib/libm.so")
except LLVMException:
@@ -42,14 +42,14 @@
def do_llvm():
- print " Testing module llvm"
+ print(" Testing module llvm")
do_llvmexception()
do_ownable()
do_misc()
def do_module():
- print " Testing class Module"
+ print(" Testing class Module")
m = Module.new('test')
m.target = 'a'
a = m.target
@@ -101,7 +101,7 @@
def do_type():
- print " Testing class Type"
+ print(" Testing class Type")
for i in range(1,100):
Type.int(i)
Type.float()
@@ -151,14 +151,14 @@
def do_typehandle():
- print " Testing class TypeHandle"
+ print(" Testing class TypeHandle")
th = TypeHandle.new(Type.opaque())
ts = Type.struct([ Type.int(), Type.pointer(th.type) ])
th.type.refine(ts)
def do_value():
- print " Testing class Value"
+ print(" Testing class Value")
k = Constant.int(ti, 42)
k.name = 'a'
s = k.name
@@ -186,7 +186,7 @@
def do_constant():
- print " Testing class Constant"
+ print(" Testing class Constant")
Constant.null(ti)
Constant.all_ones(ti)
Constant.undef(ti)
@@ -231,7 +231,7 @@
def do_global_value():
- print " Testing class GlobalValue"
+ print(" Testing class GlobalValue")
m = Module.new('a')
gv = GlobalVariable.new(m, Type.int(), 'b')
s = gv.is_declaration
@@ -247,7 +247,7 @@
def do_global_variable():
- print " Testing class GlobalVariable"
+ print(" Testing class GlobalVariable")
m = Module.new('a')
gv = GlobalVariable.new(m, Type.int(), 'b')
gv = GlobalVariable.get(m, 'b')
@@ -260,7 +260,7 @@
def do_argument():
- print " Testing class Argument"
+ print(" Testing class Argument")
m = Module.new('a')
ft = Type.function(ti, [ti])
f = Function.new(m, ft, 'func')
@@ -272,7 +272,7 @@
def do_function():
- print " Testing class Function"
+ print(" Testing class Function")
ft = Type.function(ti, [ti]*20)
zz = Function.new(Module.new('z'), ft, 'foobar')
del zz
@@ -307,7 +307,7 @@
def do_instruction():
- print " Testing class Instruction"
+ print(" Testing class Instruction")
m = Module.new('a')
ft = Type.function(ti, [ti]*20)
f = Function.new(m, ft, 'func')
@@ -320,7 +320,7 @@
def do_callorinvokeinstruction():
- print " Testing class CallOrInvokeInstruction"
+ print(" Testing class CallOrInvokeInstruction")
m = Module.new('a')
ft = Type.function(ti, [ti])
f = Function.new(m, ft, 'func')
@@ -337,7 +337,7 @@
def do_phinode():
- print " Testing class PhiNode"
+ print(" Testing class PhiNode")
m = Module.new('a')
ft = Type.function(ti, [ti])
f = Function.new(m, ft, 'func')
@@ -354,7 +354,7 @@
def do_switchinstruction():
- print " Testing class SwitchInstruction"
+ print(" Testing class SwitchInstruction")
m = Module.new('a')
ft = Type.function(ti, [ti])
f = Function.new(m, ft, 'func')
@@ -365,7 +365,7 @@
def do_basicblock():
- print " Testing class BasicBlock"
+ print(" Testing class BasicBlock")
m = Module.new('a')
ft = Type.function(ti, [ti])
f = Function.new(m, ft, 'func')
@@ -395,7 +395,7 @@
def do_builder():
- print " Testing class Builder"
+ print(" Testing class Builder")
m = Module.new('a')
ft = Type.function(ti, [ti])
f = Function.new(m, ft, 'func')
@@ -488,7 +488,7 @@
def do_llvm_core():
- print " Testing module llvm.core"
+ print(" Testing module llvm.core")
do_module()
do_type()
do_typehandle()
@@ -508,7 +508,7 @@
def do_targetdata():
- print " Testing class TargetData"
+ print(" Testing class TargetData")
t = TargetData.new('')
v = str(t)
v = t.byte_order
@@ -530,7 +530,7 @@
def do_genericvalue():
- print " Testing class GenericValue"
+ print(" Testing class GenericValue")
v = GenericValue.int(ti, 1)
v = GenericValue.int_signed(ti, 1)
v = GenericValue.real(Type.float(), 3.14)
@@ -540,7 +540,7 @@
def do_executionengine():
- print " Testing class ExecutionEngine"
+ print(" Testing class ExecutionEngine")
m = Module.new('a')
ee = ExecutionEngine.new(m, True)
ft = Type.function(ti, [])
@@ -567,14 +567,14 @@
def do_llvm_ee():
- print " Testing module llvm.ee"
+ print(" Testing module llvm.ee")
do_targetdata()
do_genericvalue()
do_executionengine()
def do_passmanager():
- print " Testing class PassManager"
+ print(" Testing class PassManager")
pm = PassManager.new()
pm.add(TargetData.new(''))
for i in [getattr(llvm.passes, x) for x in \
@@ -586,7 +586,7 @@
def do_functionpassmanager():
- print " Testing class FunctionPassManager"
+ print(" Testing class FunctionPassManager")
m = Module.new('a')
ft = Type.function(ti, [])
f = m.add_function(ft, 'func')
@@ -602,13 +602,13 @@
def do_llvm_passes():
- print " Testing module llvm.passes"
+ print(" Testing module llvm.passes")
do_passmanager()
do_functionpassmanager()
def main():
- print "Testing package llvm"
+ print("Testing package llvm")
do_llvm()
do_llvm_core()
do_llvm_ee()
--- .\test\testattrs.py (original)
+++ .\test\testattrs.py (refactored)
@@ -1,7 +1,7 @@
#!/usr/bin/env python
from llvm.core import *
-from cStringIO import StringIO
+from io import StringIO
def make_module():
--- .\test\typehandle.py (original)
+++ .\test\typehandle.py (refactored)
@@ -16,4 +16,4 @@
m.add_type_name("struct.node", th.type)
# show what we created
-print m
+print(m)
--- .\test\uses.py (original)
+++ .\test\uses.py (refactored)
@@ -13,11 +13,11 @@
tmp3 = bld.add(tmp1, f.args[2], "tmp3")
bld.ret(tmp3)
-print "-"*60
-print m
-print "-"*60
+print("-"*60)
+print(m)
+print("-"*60)
-print "Testing use count ..",
+print("Testing use count ..", end=' ')
c1 = f.args[0].use_count == 1
c2 = f.args[1].use_count == 1
c3 = f.args[2].use_count == 1
@@ -25,11 +25,11 @@
c5 = tmp2.use_count == 0
c6 = tmp3.use_count == 1
if c1 and c2 and c3 and c4 and c5 and c6:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
-print "Testing uses ..",
+print("Testing uses ..", end=' ')
c1 = f.args[0].uses[0] is tmp1
c2 = len(f.args[0].uses) == 1
c3 = f.args[1].uses[0] is tmp2
@@ -40,6 +40,6 @@
c8 = len(tmp2.uses) == 0
c9 = len(tmp3.uses) == 1
if c1 and c2 and c3 and c4 and c5 and c6 and c7 and c8 and c9:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
--- .\tools\intrgen.py (original)
+++ .\tools\intrgen.py (refactored)
@@ -26,7 +26,7 @@
idx = 1
for i in intr:
s = 'INTR_' + i.upper()
- print '%s = %d' % (s.ljust(maxw), idx)
+ print('%s = %d' % (s.ljust(maxw), idx))
idx += 1
gen(sys.argv[1])
--- .\tools\intrs_for_doc.py (original)
+++ .\tools\intrs_for_doc.py (refactored)
@@ -21,5 +21,5 @@
outf = open(OUTF, 'wt')
i = 0
while i < len(intrs):
- print >>outf, "`" + "`,`".join(intrs[i:min(i+NCOLS,len(intrs)+1)]) + "`"
+ print("`" + "`,`".join(intrs[i:min(i+NCOLS,len(intrs)+1)]) + "`", file=outf)
i += NCOLS
--- .\www\makeweb.py (original)
+++ .\www\makeweb.py (refactored)
@@ -52,7 +52,7 @@
def _rmtree_warn(fn, path, excinfo):
- print "** WARNING **: error while doing %s on %s" % (fn, path)
+ print("** WARNING **: error while doing %s on %s" % (fn, path))
def _can_skip(opts, infile, outfile):
@@ -67,14 +67,14 @@
cmd = cmdfn(opts, infile, outfile_actual)
if _can_skip(opts, infile, outfile_actual):
if opts.verbose >= 2:
- print "up to date %s -> %s" % (infile, outfile_actual)
+ print("up to date %s -> %s" % (infile, outfile_actual))
return
if cmd:
# do cmd
if opts.verbose:
- print "process %s -> %s" % (infile, outfile_actual)
+ print("process %s -> %s" % (infile, outfile_actual))
if opts.verbose >= 3:
- print "command is [%s]" % cmd
+ print("command is [%s]" % cmd)
if not opts.dryrun:
os.system(cmd)
# else if cmd is None, do nothing
@@ -83,7 +83,7 @@
# nothing matched, default action is to copy
if not _can_skip(opts, infile, outfile):
if opts.verbose:
- print "copying %s -> %s" % (infile, outfile)
+ print("copying %s -> %s" % (infile, outfile))
if not opts.dryrun:
shutil.copy(infile, outfile)
@@ -95,14 +95,14 @@
# if it exists, it must be a dir!
if odexists and not os.path.isdir(outdir):
- print "** WARNING **: output dir '%s' exists but is " \
- "not a dir, skipping" % outdir
+ print("** WARNING **: output dir '%s' exists but is " \
+ "not a dir, skipping" % outdir)
return
# make outdir if not existing
if not odexists:
if opts.verbose:
- print "creating %s" % outdir
+ print("creating %s" % outdir)
if not opts.dryrun:
os.mkdir(outdir)
@@ -114,8 +114,8 @@
# process files
if os.path.isfile(inp):
if os.path.exists(outp) and not os.path.isfile(outp):
- print "** WARNING **: output '%s' corresponding to " \
- "input '%s' is not a file, skipping" % (outp, inp)
+ print("** WARNING **: output '%s' corresponding to " \
+ "input '%s' is not a file, skipping" % (outp, inp))
else:
process_file(opts, inp, outp)
@@ -124,15 +124,15 @@
# if dir is in skip list, silently ignore
if elem in DIR_SKIP_TBL:
if opts.verbose >= 3:
- print "skipping %s" % inp
+ print("skipping %s" % inp)
continue
# just recurse
make(opts, inp, outp)
# neither a file nor a dir
else:
- print "** WARNING **: input '%s' is neither file nor " \
- "dir, skipping" % inp
+ print("** WARNING **: input '%s' is neither file nor " \
+ "dir, skipping" % inp)
def get_opts():
@@ -173,14 +173,14 @@
def main():
opts, src, dest = get_opts()
if opts.verbose >= 3:
- print ("running with options:\nsrc = [%s]\ndest = [%s]\nverbose = [%d]\n" +\
+ print(("running with options:\nsrc = [%s]\ndest = [%s]\nverbose = [%d]\n" +\
"dry-run = [%d]\nclean-first = [%d]\nforce = [%d]") %\
- (src, dest, opts.verbose, opts.dryrun, opts.clean, opts.force)
+ (src, dest, opts.verbose, opts.dryrun, opts.clean, opts.force))
if opts.dryrun and opts.verbose == 0:
opts.verbose = 1
if opts.clean:
if opts.dryrun or opts.verbose:
- print "removing tree %s" % dest
+ print("removing tree %s" % dest)
if not opts.dryrun:
os.rmtree(dest, True, _rmtree_warn)
make(opts, src, dest)

View file

@ -1,62 +0,0 @@
C:\Users\AndrewBC\src\llvm-py>python "C:\Program Files\Python27\Tools\Scripts\2to3.py" -w -f all -f idioms . > llvm/py3k_update.diff
RefactoringTool: Skipping implicit fixer: buffer
RefactoringTool: Skipping implicit fixer: set_literal
RefactoringTool: Skipping implicit fixer: ws_comma
RefactoringTool: Refactored .\setup-win32.py
RefactoringTool: Refactored .\setup.py
RefactoringTool: Refactored .\llvm\__init__.py
RefactoringTool: Refactored .\llvm\_util.py
RefactoringTool: Refactored .\llvm\core.py
RefactoringTool: Refactored .\llvm\ee.py
RefactoringTool: Refactored .\llvm\passes.py
RefactoringTool: Refactored .\test\JITTutorial1.py
RefactoringTool: Refactored .\test\JITTutorial2.py
RefactoringTool: Refactored .\test\asm.py
RefactoringTool: Refactored .\test\call-jit-ctypes.py
RefactoringTool: Refactored .\test\example-jit.py
RefactoringTool: Refactored .\test\example.py
RefactoringTool: Refactored .\test\intrinsic.py
RefactoringTool: Refactored .\test\objcache.py
RefactoringTool: Refactored .\test\operands.py
RefactoringTool: Refactored .\test\passes.py
RefactoringTool: Refactored .\test\test.py
RefactoringTool: Refactored .\test\testall.py
RefactoringTool: Refactored .\test\testattrs.py
RefactoringTool: Refactored .\test\typehandle.py
RefactoringTool: Refactored .\test\uses.py
RefactoringTool: Refactored .\tools\intrgen.py
RefactoringTool: Refactored .\tools\intrs_for_doc.py
RefactoringTool: Refactored .\www\makeweb.py
RefactoringTool: Can't parse .\www\src\examples\JITTutorial1.py: ParseError: bad input: type=17, value=u'/', context=('', (1, 2))
RefactoringTool: Can't parse .\www\src\examples\JITTutorial2.py: ParseError: bad input: type=17, value=u'/', context=('', (1, 2))
RefactoringTool: Files that need to be modified:
RefactoringTool: .\setup-win32.py
RefactoringTool: .\setup.py
RefactoringTool: .\llvm\__init__.py
RefactoringTool: .\llvm\_util.py
RefactoringTool: .\llvm\core.py
RefactoringTool: .\llvm\ee.py
RefactoringTool: .\llvm\passes.py
RefactoringTool: .\test\JITTutorial1.py
RefactoringTool: .\test\JITTutorial2.py
RefactoringTool: .\test\asm.py
RefactoringTool: .\test\call-jit-ctypes.py
RefactoringTool: .\test\example-jit.py
RefactoringTool: .\test\example.py
RefactoringTool: .\test\intrinsic.py
RefactoringTool: .\test\objcache.py
RefactoringTool: .\test\operands.py
RefactoringTool: .\test\passes.py
RefactoringTool: .\test\test.py
RefactoringTool: .\test\testall.py
RefactoringTool: .\test\testattrs.py
RefactoringTool: .\test\typehandle.py
RefactoringTool: .\test\uses.py
RefactoringTool: .\tools\intrgen.py
RefactoringTool: .\tools\intrs_for_doc.py
RefactoringTool: .\www\makeweb.py
RefactoringTool: There were 2 errors:
RefactoringTool: Can't parse .\www\src\examples\JITTutorial1.py: ParseError: bad input: type=17, value=u'/', context=('', (1, 2))
RefactoringTool: Can't parse .\www\src\examples\JITTutorial2.py: ParseError: bad input: type=17, value=u'/', context=('', (1, 2))
C:\Users\AndrewBC\src\llvm-py>

View file

@ -10,13 +10,12 @@ import subprocess
import tempfile
import contextlib
is_py3k = bool(sys.version_info[0] == 3)
BITS = tuple.__itemsize__ * 8
if is_py3k:
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
else:
from cStringIO import StringIO
import llvm
@ -26,6 +25,7 @@ from llvm.ee import EngineBuilder
import llvm.core as lc
import llvm.passes as lp
import llvm.ee as le
import llvmpy
tests = []
@ -117,13 +117,13 @@ tests.append(TestAsm)
class TestAttr(TestCase):
def make_module(self):
test_module = """
define i32 @sum(i32, i32) {
define void @sum(i32*, i32*) {
entry:
%2 = add i32 %0, %1
ret i32 %2
ret void
}
"""
return Module.from_assembly(StringIO(test_module))
buf = StringIO(test_module)
return Module.from_assembly(buf)
def test_align(self):
m = self.make_module()
@ -394,6 +394,9 @@ entry:
self.assertFalse(pmb.disable_unroll_loops)
self.assertFalse(pmb.disable_simplify_lib_calls)
pmb.disable_unit_at_a_time = True
self.assertTrue(pmb.disable_unit_at_a_time)
# Do function pass
fpm = lp.FunctionPassManager.new(m)
pmb.populate(fpm)
@ -437,29 +440,18 @@ class TestEngineBuilder(TestCase):
def test_enginebuilder_basic(self):
module = self.make_test_module()
self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr))
ee = EngineBuilder.new(module).create()
with self.assertRaises(llvm.LLVMException):
# Ensure the module is owned.
llvm._util.check_is_unowned(module)
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)
with self.assertRaises(llvm.LLVMException):
# Ensure the targetmachine is owned.
llvm._util.check_is_unowned(tm)
with self.assertRaises(llvm.LLVMException):
# Ensure the module is owned.
llvm._util.check_is_unowned(module)
self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr))
self.run_foo(ee, module)
def test_enginebuilder_force_jit(self):
@ -467,12 +459,12 @@ class TestEngineBuilder(TestCase):
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_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()
@ -549,6 +541,7 @@ class TestObjCache(TestCase):
gv3 = None
gv1.delete()
gv4 = GlobalVariable.new(m1, t, "gv")
self.assert_(gv1 is not gv4)
@ -588,7 +581,7 @@ class TestObjCache(TestCase):
self.assert_(b1 is b2)
# Testing basic block aliasing 2
b3 = f1.get_entry_basic_block()
b3 = f1.entry_basic_block
self.assert_(b1 is b3)
# Testing basic block aliasing 3
@ -638,7 +631,7 @@ class TestTargetMachines(TestCase):
self.assertTrue(tm.target_data)
self.assertTrue(tm.target_short_description)
self.assertTrue(tm.triple)
self.assertIn('foo', tm.emit_assembly(m).decode('utf-8'))
self.assertIn('foo', tm.emit_assembly(m))
self.assertTrue(le.get_host_cpu_name())
def test_ptx(self):
@ -648,16 +641,17 @@ class TestTargetMachines(TestCase):
arch = 'nvptx64'
else:
return # skip this test
print(arch)
m, func = self._build_module()
func.calling_convention = lc.CC_PTX_KERNEL # set calling conv
ptxtm = le.TargetMachine.lookup(arch=arch, cpu='compute_20')
ptxtm = le.TargetMachine.lookup(arch=arch, cpu='sm_20')
self.assertTrue(ptxtm.triple)
self.assertTrue(ptxtm.cpu)
ptxasm = ptxtm.emit_assembly(m).decode('utf-8')
ptxasm = ptxtm.emit_assembly(m)
self.assertIn('foo', ptxasm)
if lc.HAS_NVPTX:
self.assertIn('.address_size 64', ptxasm)
self.assertIn('compute_20', ptxasm)
self.assertIn('sm_20', ptxasm)
def _build_module(self):
m = Module.new('TestTargetMachines')
@ -947,31 +941,31 @@ class TestCPUSupport(TestCase):
def test_cpu_support2(self):
features = 'sse3', 'sse41', 'sse42', 'avx'
mattrs = ','.join(map(lambda s: '-%s' % s, features))
print 'disable mattrs', mattrs
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
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
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
print('disable mattrs', mattrs)
self._template(mattrs)
def test_cpu_support6(self):
features = []
mattrs = ','.join(map(lambda s: '-%s' % s, features))
print 'disable mattrs', mattrs
print('disable mattrs', mattrs)
self._template(mattrs)
tests.append(TestCPUSupport)
@ -1246,4 +1240,4 @@ def run(verbosity=1):
if __name__ == '__main__':
run()
unittest.main()

View file

@ -1,70 +0,0 @@
/*
* Copyright (c) 2008-10, Mahadevan R All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of this software, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wrap.h"
const char PYCAP_OBJECT_NAME[] = "llvm.wrap.h";
/*===----------------------------------------------------------------------===*/
/* Type ctor/dtor */
/*===----------------------------------------------------------------------===*/
/*===----------------------------------------------------------------------===*/
/* Helper functions */
/*===----------------------------------------------------------------------===*/
void *get_object_arg(PyObject *args)
{
PyObject *o;
if (!PyArg_ParseTuple(args, "O", &o))
throw py_exception();
return pycap_get<void*>(o);
}
// must delete [] returned array
void **make_array_from_list(PyObject *list, int n)
{
void **arr = new void*[n] ;
int i;
for (i=0; i<n; i++) {
PyObject *e = PyList_GetItem(list, i);
if ( e == Py_None ) { // is None object?
arr[i] = NULL;
} else { // otherwise, it must be a PyCapsule
arr[i] = pycap_get<void*>(e);
}
}
return arr;
}

File diff suppressed because it is too large Load diff

4
llvmpy/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
api.cpp
api/*.py
api/*/*.py

21
llvmpy/Makefile Normal file
View file

@ -0,0 +1,21 @@
PYTHON = python
all: _api.so _capsule.so
_api.so _capsule.so: api.cpp capsule.cpp
$(PYTHON) setup.py build_ext --inplace
api.cpp api/__init__.py: src/*.py include/llvm_binding/*.h gen/gen.py gen/binding.py
$(PYTHON) gen/gen.py api src
clean: cleantemp
rm -f _api.so _capsule.so
rm -rf api
cleantemp:
rm -f api.cpp
check: _api.so api/__init__.py
$(PYTHON) test_binding.py
@PHONY: all clean check

5
llvmpy/README Normal file
View file

@ -0,0 +1,5 @@
# README
This is a reimplementation of the LLVM binding, aiming to provide a more familiar interface to the C++ API whenever possible.
The implementation uses a custom DSL in python to describe the interface (under binding directory). The DSL serves as input to *gen.py* for generation of the .cpp and .py files for the actual binding.

0
llvmpy/__init__.py Normal file
View file

117
llvmpy/capsule.cpp Normal file
View file

@ -0,0 +1,117 @@
#include <Python.h>
#include <python3adapt.h>
#include <capsulethunk.h>
#include <llvm_binding/capsule_context.h>
static
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* 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* 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;
}
}
// ------------------
// PyCapsule Context
// ------------------
static
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.");
return NULL;
}
return static_cast<CapsuleContext*>(context);
}
static
PyObject* getClassName(PyObject* self, PyObject* args) {
CapsuleContext* context = getContext(self, args);
//Assert(context->_magic == 0xdead);
if (!context) {
return NULL;
} else {
return PyString_FromString(context->className);
}
}
static PyMethodDef core_methods[] = {
#define declmethod(func) { #func , ( PyCFunction )func , METH_VARARGS , NULL }
declmethod(getName),
declmethod(getPointer),
declmethod(check),
declmethod(getClassName),
{ NULL },
#undef declmethod
};
// Module main function, hairy because of py3k port
extern "C" {
#if (PY_MAJOR_VERSION >= 3)
struct PyModuleDef module_def = {
PyModuleDef_HEAD_INIT,
"_capsule",
NULL,
-1,
core_methods,
NULL, NULL, NULL, NULL
};
#define INITERROR return NULL
PyObject *
PyInit__capsule(void)
#else
#define INITERROR return
PyMODINIT_FUNC
init_capsule(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
PyObject *module = PyModule_Create( &module_def );
#else
PyObject *module = Py_InitModule("_capsule", core_methods);
#endif
if (module == NULL)
INITERROR;
#if PY_MAJOR_VERSION >= 3
return module;
#endif
}
} // end extern C

213
llvmpy/capsule.py Normal file
View file

@ -0,0 +1,213 @@
from weakref import WeakKeyDictionary, WeakValueDictionary, ref
from collections import defaultdict
import logging
logger = logging.getLogger(__name__)
def set_debug(enabled):
'''
Side-effect: configure logger with it is not configured.
'''
if enabled:
# If no handlers are configured for the root logger,
# build a default handler for debugging.
# Can we do better?
if not logger.root.handlers:
logging.basicConfig()
logger.setLevel(logging.DEBUG)
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
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 Capsule.getClassName(self.capsule)
@property
def name(self):
return Capsule.getName(self.capsule)
@property
def pointer(self):
return Capsule.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 super(Capsule, self).__hash__()
def __ne__(self, other):
return not (self == other)
class WeakRef(ref):
pass
_addr2refct = defaultdict(lambda: 0)
_capsule2weak = WeakKeyDictionary()
_addr2dtor = {}
_pyclasses = {}
# Cache {cls: {addr: obj}}
# NOTE: The same 'addr' may appear in multiple class bins.
_cache = defaultdict(WeakValueDictionary)
def release_ownership(old):
logger.debug('Release %s', old)
addr = Capsule.getPointer(old)
name = Capsule.getName(old)
if _addr2dtor.get((name, addr)) is None:
clsname = Capsule.getClassName(old)
if not _pyclasses[clsname]._has_dtor():
return
# Guard duplicated release
raise Exception("Already released")
_addr2dtor[(name, addr)] = None
def obtain_ownership(cap):
cls = cap.get_class()
if cls._has_dtor():
addr = cap.pointer
name = cap.name
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 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
try: # lookup cached object
return _cache[cls][addr]
except KeyError:
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):
'''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
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
@property
def _capsule(self):
return self.__capsule
@property
def _ptr(self):
return self._capsule.capsule
def __hash__(self):
return super(Wrapper, self).__hash__()
def __eq__(self, other):
return self._capsule == other._capsule
def __ne__(self, other):
return self._capsule != other._capsule
def _downcast(self, newcls):
return downcast(self, newcls)
@classmethod
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('::', '_')
try:
caster = getattr(_api.downcast, fname)
except AttributeError:
fmt = "Downcast from %s to %s is not supported"
raise TypeError(fmt % (fromty, toty))
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

25
llvmpy/extra.py Normal file
View file

@ -0,0 +1,25 @@
'''
Wrapped the extra functions in _api.so
'''
from llvmpy import capsule
from llvmpy import _api
#
# Re-export the native API from the _api.extra and wrap the functions
#
def _wrapper(func):
"Wrap the re-exported functions"
def _core(*args):
unwrapped = list(map(capsule.unwrap, args))
ret = func(*unwrapped)
return capsule.wrap(ret)
return _core
def _init(glob):
for k, v in _api.extra.__dict__.items():
glob[k] = _wrapper(v)
_init(globals())

840
llvmpy/gen/binding.py Normal file
View file

@ -0,0 +1,840 @@
import inspect, textwrap
import functools
import codegen as cg
import os
_rank = 0
namespaces = {}
RESERVED = frozenset(['None'])
def makedir(directory):
if not os.path.exists(directory):
os.makedirs(directory)
class SubModule(object):
def __init__(self):
self.methods = []
self.enums = []
self.classes = []
self.namespaces = []
self.attrs = []
self.includes = set()
def aggregate_includes(self):
includes = set(self.includes)
for unit in self.iter_all():
if isinstance(unit, SubModule):
includes |= unit.aggregate_includes()
else:
includes |= unit.includes
return includes
def aggregate_downcast(self):
dclist = []
for cls in self.classes:
for bcls in cls.downcastables:
from_to = bcls.fullname, cls.fullname
name = 'downcast_%s_to_%s' % tuple(map(cg.mangle, from_to))
fn = Function(namespaces[''], name, ptr(cls), ptr(bcls))
dclist.append((from_to, fn))
for ns in self.namespaces:
dclist.extend(ns.aggregate_downcast())
return dclist
def iter_all(self):
for fn in self.methods:
yield fn
for cls in self.classes:
yield cls
for enum in self.enums:
yield enum
for attr in self.attrs:
yield attr
for ns in self.namespaces:
yield ns
def generate_method_table(self, println):
writer = cg.CppCodeWriter(println)
writer.println('static')
writer.println('PyMethodDef meth_%s[] = {' % cg.mangle(self.fullname))
with writer.indent():
fmt = '{ "%(name)s", (PyCFunction)%(func)s, METH_VARARGS, NULL },'
for meth in self.methods:
name = meth.name
func = meth.c_name
writer.println(fmt % locals())
for enumkind in self.enums:
for enum in enumkind.value_names:
name = enum
func = enumkind.c_name(enum)
writer.println(fmt % locals())
for attr in self.attrs:
# getter
name = attr.getter_name
func = attr.getter_c_name
writer.println(fmt % locals())
# setter
name = attr.setter_name
func = attr.setter_c_name
writer.println(fmt % locals())
writer.println('{ NULL },')
writer.println('};')
writer.println()
# def generate_downcasts(self, println):
# for ((fromty, toty), fn) in self.downcastlist:
# name = fn.name
# fmt = '''
#static
#%(toty)s* %(name)s(%(fromty)s* arg)
#{
# return typecast< %(toty)s >::from(arg);
#}
# '''
# println(fmt % locals())
#
# fn.generate_cpp(println)
def generate_cpp(self, println, extras=()):
for unit in self.iter_all():
unit.generate_cpp(println)
self.generate_method_table(println)
self.generate_submodule_table(println, extras=extras)
def generate_submodule_table(self, println, extras=()):
writer = cg.CppCodeWriter(println)
writer.println('static')
name = cg.mangle(self.fullname)
writer.println('SubModuleEntry submodule_%(name)s[] = {' % locals())
with writer.indent():
for cls in self.classes:
name = cls.name
table = cg.mangle(cls.fullname)
writer.println('{ "%(name)s", meth_%(table)s, NULL },' %
locals())
for ns in self.namespaces:
name = ns.localname
table = cg.mangle(ns.fullname)
fmt = '{ "%(name)s", meth_%(table)s, submodule_%(table)s },'
writer.println(fmt % locals())
for name, table in extras:
writer.println('{ "%(name)s", %(table)s, NULL },' % locals())
writer.println('{ NULL }')
writer.println('};')
writer.println('')
def generate_py(self, rootdir='.', name=''):
name = name or self.localname
if self.namespaces: # should make new directory
path = os.path.join(rootdir, name)
makedir(path)
filepath = os.path.join(path, '__init__.py')
else:
filepath = os.path.join(rootdir, '%s.py' % name)
with open(filepath, 'w') as pyfile:
println = cg.wrap_println_from_file(pyfile)
println('from llvmpy import _api, capsule')
for ns in self.namespaces:
println('from . import %s' % ns.localname)
println()
for unit in self.iter_all():
if not isinstance(unit, Namespace):
writer = cg.PyCodeWriter(println)
unit.compile_py(writer)
for ns in self.namespaces:
ns.generate_py(rootdir=path)
class Namespace(SubModule):
def __init__(self, name):
SubModule.__init__(self)
self.name = name = name.lstrip(':')
namespaces[name] = self
def Class(self, *bases):
cls = Class(self, *bases)
self.classes.append(cls)
return cls
def Function(self, *args):
fn = Function(self, *args)
self.methods.append(fn)
return fn
def CustomFunction(self, *args):
fn = CustomFunction(self, *args)
self.methods.append(fn)
return fn
def Enum(self, name, *value_names):
enum = Enum(*value_names)
enum.parent = self
enum.name = name
self.enums.append(enum)
assert name not in vars(self), 'Duplicated'
setattr(self, name, enum)
return enum
def Namespace(self, name):
ns = Namespace('::'.join([self.name, name]))
self.namespaces.append(ns)
return ns
@property
def fullname(self):
return self.name
@property
def py_name(self):
return self.name.replace('::', '.')
@property
def localname(self):
return self.name.rsplit('::', 1)[-1]
def __str__(self):
return self.name
class _Type(object):
pass
class BuiltinTypes(_Type):
def __init__(self, name):
self.name = name
@property
def fullname(self):
return self.name
def wrap(self, writer, var):
return var
def unwrap(self, writer, var):
return var
Void = BuiltinTypes('void')
Unsigned = BuiltinTypes('unsigned')
UnsignedLongLong = BuiltinTypes('unsigned long long') # used in llvm-3.2
LongLong = BuiltinTypes('long long')
Float = BuiltinTypes('float')
Double = BuiltinTypes('double')
Uint64 = BuiltinTypes('uint64_t')
Int64 = BuiltinTypes('int64_t')
Int = BuiltinTypes('int')
Size_t = BuiltinTypes('size_t')
VoidPtr = BuiltinTypes('void*')
Bool = BuiltinTypes('bool')
StdString = BuiltinTypes('std::string')
ConstStdString = BuiltinTypes('const std::string')
ConstCharPtr = BuiltinTypes('const char*')
PyObjectPtr = BuiltinTypes('PyObject*')
PyObjectPtr.format='O'
class Class(SubModule, _Type):
format = 'O'
def __init__(self, ns, *bases):
SubModule.__init__(self)
self.ns = ns
self.bases = bases
self._is_defined = False
self.pymethods = []
self.downcastables = set()
def __call__(self, defn):
assert not self._is_defined
# process the definition in "defn"
self.name = defn.__name__
for k, v in defn.__dict__.items():
if isinstance(v, Method):
self.methods.append(v)
if isinstance(v, Constructor):
for sig in v.signatures:
sig[0] = ptr(self)
v.name = k
v.parent = self
elif isinstance(v, Enum):
self.enums.append(v)
v.name = k
v.parent = self
assert k not in vars(self), "Duplicated: %s" % k
setattr(self, k, v)
elif isinstance(v, Attr):
self.attrs.append(v)
v.name = k
v.parent = self
elif isinstance(v, CustomPythonMethod):
self.pymethods.append(v)
elif k == '_include_':
if isinstance(v, str):
self.includes.add(v)
else:
for i in v:
self.includes.add(i)
elif k == '_realname_':
self.realname = v
elif k == '_downcast_':
if isinstance(v, Class):
self.downcastables.add(v)
else:
for i in v:
self.downcastables.add(i)
return self
def compile_py(self, writer):
clsname = self.name
bases = 'capsule.Wrapper'
if self.bases:
bases = ', '.join(x.name for x in self.bases)
writer.println('@capsule.register_class("%s")' % self.fullname)
with writer.block('class %(clsname)s(%(bases)s):' % locals()):
writer.println('_llvm_type_ = "%s"' % self.fullname)
for enum in self.enums:
enum.compile_py(writer)
for meth in self.methods:
meth.compile_py(writer)
for meth in self.pymethods:
meth.compile_py(writer)
for attr in self.attrs:
attr.compile_py(writer)
writer.println()
@property
def capsule_name(self):
if self.bases:
return self.bases[-1].capsule_name
else:
return self.fullname
@property
def fullname(self):
try:
name = self.realname
except AttributeError:
name = self.name
return '::'.join([self.ns.fullname, name])
@property
def py_name(self):
ns = self.ns.name.split('::')
return '.'.join(ns + [self.name])
def __str__(self):
return self.fullname
def unwrap(self, writer, val):
fmt = 'PyCapsule_GetPointer(%(val)s, "%(name)s")'
name = self.capsule_name
raw = writer.declare('void*', fmt % locals())
writer.die_if_false(raw, verbose=name)
ptrty = ptr(self).fullname
ty = self.fullname
fmt = 'typecast< %(ty)s >::from(%(raw)s)'
casted = writer.declare(ptrty, fmt % locals())
writer.die_if_false(casted)
return casted
def wrap(self, writer, val):
copy = 'new %s(%s)' % (self.fullname, val)
return writer.pycapsule_new(copy, self.capsule_name, self.fullname)
class Enum(object):
format = 'O'
def __init__(self, *value_names):
self.parent = None
if len(value_names) == 1:
value_names = list(filter(bool, value_names[0].replace(',', ' ').split()))
self.value_names = value_names
self.includes = set()
@property
def fullname(self):
try:
name = self.realname
except AttributeError:
name = self.name
return '::'.join([self.parent.fullname, name])
def __str__(self):
return self.fullname
def wrap(self, writer, val):
ret = writer.declare('PyObject*', 'PyInt_FromLong(%s)' % val)
return ret
def unwrap(self, writer, val):
convert_long_to_enum = '(%s)PyInt_AsLong(%s)' % (self.fullname, val)
ret = writer.declare(self.fullname, convert_long_to_enum)
return ret
def c_name(self, enum):
return cg.mangle("%s_%s_%s" % (self.parent, self.name, enum))
def generate_cpp(self, println):
self.compile_cpp(cg.CppCodeWriter(println))
def compile_cpp(self, writer):
for enum in self.value_names:
with writer.py_function(self.c_name(enum)):
ret = self.wrap(writer, '::'.join([self.parent.fullname, enum]))
writer.return_value(ret)
def compile_py(self, writer):
with writer.block('class %s:' % self.name):
writer.println('_llvm_type_ = "%s"' % self.fullname)
for v in self.value_names:
if v in RESERVED:
k = '%s_' % v
fmt = '%(k)s = getattr(%(p)s, "%(v)s")()'
else:
k = v
fmt = '%(k)s = %(p)s.%(v)s()'
p = '.'.join(['_api'] + self.parent.fullname.split('::'))
writer.println(fmt % locals())
writer.println()
class Method(object):
_kind_ = 'meth'
def __init__(self, return_type=Void, *args):
self.parent = None
self.signatures = []
self.includes = set()
self._add_signature(return_type, *args)
self.disowning = False
def _add_signature(self, return_type, *args):
prev_lens = set(map(len, self.signatures))
cur_len = len(args) + 1
if cur_len in prev_lens:
raise Exception('Only support overloading with different number'
' of arguments')
self.signatures.append([return_type] + list(args))
def __ior__(self, method):
assert type(self) is type(method)
for sig in method.signatures:
self._add_signature(sig[0], *sig[1:])
return self
@property
def fullname(self):
return '::'.join([self.parent.fullname, self.realname]).lstrip(':')
@property
def realname(self):
try:
return self.__realname
except AttributeError:
return self.name
@realname.setter
def realname(self, v):
self.__realname = v
@property
def c_name(self):
return cg.mangle("%s_%s" % (self.parent, self.name))
def __str__(self):
return self.fullname
def generate_cpp(self, println):
self.compile_cpp(cg.CppCodeWriter(println))
def compile_cpp(self, writer):
with writer.py_function(self.c_name):
if len(self.signatures) == 1:
sig = self.signatures[0]
retty = sig[0]
argtys = sig[1:]
self.compile_cpp_body(writer, retty, argtys)
else:
nargs = writer.declare('Py_ssize_t', 'PyTuple_Size(args)')
for sig in self.signatures:
retty = sig[0]
argtys = sig[1:]
expect = len(argtys)
if (not isinstance(self, StaticMethod) and
isinstance(self.parent, Class)):
# Is a instance method, add 1 for "this".
expect += 1
with writer.block('if (%(expect)d == %(nargs)s)' % locals()):
self.compile_cpp_body(writer, retty, argtys)
writer.raises(TypeError, 'Invalid number of args')
def compile_cpp_body(self, writer, retty, argtys):
args = writer.parse_arguments('args', ptr(self.parent), *argtys)
ret = writer.method_call(self.realname, retty.fullname, *args)
writer.return_value(retty.wrap(writer, ret))
def compile_py(self, writer):
decl = writer.function(self.name, args=('self',), varargs='args')
with decl as (this, varargs):
unwrap_this = writer.unwrap(this)
if self.disowning:
writer.release_ownership(unwrap_this)
unwrapped = writer.unwrap_many(varargs)
self.process_ownedptr_args(writer, unwrapped)
func = '.'.join([self.parent.py_name, self.name])
ret = writer.call('_api.%s' % func,
args=(unwrap_this,), varargs=unwrapped)
wrapped = writer.wrap(ret, self.is_return_ownedptr())
writer.return_value(wrapped)
writer.println()
def require_only(self, num):
'''Require only "num" of argument.
'''
assert len(self.signatures) == 1
sig = self.signatures[0]
ret = sig[0]
args = sig[1:]
arg_ct = len(args)
for i in range(num, arg_ct):
self._add_signature(ret, *args[:i])
return self
def is_return_ownedptr(self):
retty = self.signatures[0][0]
return isinstance(retty, ownedptr)
def process_ownedptr_args(self, writer, unwrapped):
argtys = self.signatures[0][1:]
for i, ty in enumerate(argtys):
if isinstance(ty, ownedptr):
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)
self.methodname = methodname
def compile_cpp_body(self, writer, retty, argtys):
args = writer.parse_arguments('args', ptr(self.parent), *argtys)
ret = writer.call(self.methodname, retty.fullname, *args)
writer.return_value(retty.wrap(writer, ret))
class StaticMethod(Method):
def compile_cpp_body(self, writer, retty, argtys):
assert isinstance(self.parent, Class)
args = writer.parse_arguments('args', *argtys)
ret = self.compile_cpp_call(writer, retty, args)
writer.return_value(retty.wrap(writer, ret))
def compile_cpp_call(self, writer, retty, args):
ret = writer.call(self.fullname, retty.fullname, *args)
return ret
def compile_py(self, writer):
writer.println('@staticmethod')
decl = writer.function(self.name, varargs='args')
with decl as varargs:
unwrapped = writer.unwrap_many(varargs)
self.process_ownedptr_args(writer, unwrapped)
func = '.'.join([self.parent.py_name, self.name])
ret = writer.call('_api.%s' % func, varargs=unwrapped)
wrapped = writer.wrap(ret, self.is_return_ownedptr())
writer.return_value(wrapped)
writer.println()
class CustomStaticMethod(StaticMethod):
def __init__(self, methodname, retty, *argtys):
super(CustomStaticMethod, self).__init__(retty, *argtys)
self.methodname = methodname
def compile_cpp_body(self, writer, retty, argtys):
args = writer.parse_arguments('args', *argtys)
ret = writer.call(self.methodname, retty.fullname, *args)
writer.return_value(retty.wrap(writer, ret))
class Function(Method):
_kind_ = 'func'
def __init__(self, parent, name, return_type=Void, *args):
super(Function, self).__init__(return_type, *args)
self.parent = parent
self.name = name
def compile_cpp_body(self, writer, retty, argtys):
args = writer.parse_arguments('args', *argtys)
ret = writer.call(self.fullname, retty.fullname, *args)
writer.return_value(retty.wrap(writer, ret))
def compile_py(self, writer):
with writer.function(self.name, varargs='args') as varargs:
unwrapped = writer.unwrap_many(varargs)
self.process_ownedptr_args(writer, unwrapped)
func = '.'.join([self.parent.py_name, self.name]).lstrip('.')
ret = writer.call('_api.%s' % func, varargs=unwrapped)
wrapped = writer.wrap(ret, self.is_return_ownedptr())
writer.return_value(wrapped)
writer.println()
class CustomFunction(Function):
def __init__(self, parent, name, realname, return_type=Void, *args):
super(CustomFunction, self).__init__(parent, name, return_type, *args)
self.realname = realname
@property
def fullname(self):
return self.realname
class Destructor(Method):
_kind_ = 'dtor'
def __init__(self):
super(Destructor, self).__init__()
def compile_cpp_body(self, writer, retty, argtys):
assert isinstance(self.parent, Class)
assert not argtys
args = writer.parse_arguments('args', ptr(self.parent), *argtys)
writer.println('delete %s;' % args[0])
writer.return_value(None)
def compile_py(self, writer):
func = '.'.join([self.parent.py_name, self.name])
writer.println('_delete_ = _api.%s' % func)
class Constructor(StaticMethod):
_kind_ = 'ctor'
def __init__(self, *args):
super(Constructor, self).__init__(Void, *args)
def compile_cpp_call(self, writer, retty, args):
alloctype = retty.fullname.rstrip(' *')
arglist = ', '.join(args)
stmt = 'new %(alloctype)s(%(arglist)s)' % locals()
ret = writer.declare(retty.fullname, stmt)
return ret
class ref(_Type):
def __init__(self, element):
assert isinstance(element, Class), type(element)
self.element = element
self.const = False
def __str__(self):
return self.fullname
@property
def fullname(self):
if self.const:
return 'const %s&' % self.element.fullname
else:
return '%s&' % self.element.fullname
@property
def capsule_name(self):
return self.element.capsule_name
@property
def format(self):
return self.element.format
def wrap(self, writer, val):
p = writer.declare(const(ptr(self.element)).fullname, '&%s' % val)
return writer.pycapsule_new(p, self.capsule_name, self.element.fullname)
def unwrap(self, writer, val):
p = self.element.unwrap(writer, val)
return writer.declare(self.fullname, '*%s' % p)
class ptr(_Type):
def __init__(self, element):
assert isinstance(element, Class)
self.element = element
self.const = False
@property
def fullname(self):
if self.const:
return 'const %s*' % self.element
else:
return '%s*' % self.element
@property
def format(self):
return self.element.format
def unwrap(self, writer, val):
ret = writer.declare(self.fullname, 'NULL')
with writer.block('if (%(val)s != Py_None)' % locals()):
val = self.element.unwrap(writer, val)
writer.println('%(ret)s = %(val)s;' % locals())
return ret
def wrap(self, writer, val):
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'
def __init__(self, original, target):
self.original = original
self.target = target
@property
def fullname(self):
return self.binding_type.fullname
@property
def python_type(self):
if not isinstance(self.target, _Type):
return self.target
else:
return self.original
@property
def binding_type(self):
if isinstance(self.target, _Type):
return self.target
else:
return self.original
def wrap(self, writer, val):
dst = self.python_type.__name__
if dst == 'int':
unsigned = set([Unsigned, UnsignedLongLong, Uint64,
Size_t, VoidPtr])
signed = set([LongLong, Int64, Int])
assert self.binding_type in unsigned|signed
if self.binding_type in signed:
signflag = 'signed'
else:
signflag = 'unsigned'
fn = 'py_%(dst)s_from_%(signflag)s' % locals()
else:
fn = 'py_%(dst)s_from' % locals()
return writer.call(fn, 'PyObject*', val)
def unwrap(self, writer, val):
src = self.python_type.__name__
dst = self.binding_type.fullname
ret = writer.declare(dst)
fn = 'py_%(src)s_to' % locals()
status = writer.call(fn, 'int', val, ret)
writer.die_if_false(status)
return ret
class CustomPythonMethod(object):
def __init__(self, fn):
src = inspect.getsource(fn)
lines = textwrap.dedent(src).splitlines()
for i, line in enumerate(lines):
if not line.startswith('@'):
break
self.sourcelines = lines[i:]
def compile_py(self, writer):
for line in self.sourcelines:
writer.println(line)
class CustomPythonStaticMethod(CustomPythonMethod):
def compile_py(self, writer):
writer.println('@staticmethod')
super(CustomPythonStaticMethod, self).compile_py(writer)
class Attr(object):
def __init__(self, getter, setter):
self.getter = getter
self.setter = setter
self.includes = set()
@property
def fullname(self):
try:
name = self.realname
except AttributeError:
name = self.name
return '::'.join([self.parent.fullname, name])
def __str__(self):
return self.fullname
@property
def getter_name(self):
return '%s_get' % self.name
@property
def setter_name(self):
return '%s_set' % self.name
@property
def getter_c_name(self):
return cg.mangle('%s_get' % self.fullname)
@property
def setter_c_name(self):
return cg.mangle('%s_set' % self.fullname)
def generate_cpp(self, println):
self.compile_cpp(cg.CppCodeWriter(println))
def compile_cpp(self, writer):
# getter
with writer.py_function(self.getter_c_name):
(this,) = writer.parse_arguments('args', ptr(self.parent))
attr = self.name
ret = writer.declare(self.getter.fullname,
'%(this)s->%(attr)s' % locals())
writer.return_value(self.getter.wrap(writer, ret))
# setter
with writer.py_function(self.setter_c_name):
(this, value) = writer.parse_arguments('args', ptr(self.parent),
self.setter)
attr = self.name
writer.println('%(this)s->%(attr)s = %(value)s;' % locals())
writer.return_value(None)
def compile_py(self, writer):
name = self.name
parent = '.'.join(self.parent.fullname.split('::'))
getter = '.'.join([parent, self.getter_name])
setter = '.'.join([parent, self.setter_name])
writer.println('@property')
with writer.block('def %(name)s(self):' % locals()):
unself = writer.unwrap('self')
ret = writer.new_symbol('ret')
writer.println('%(ret)s = _api.%(getter)s(%(unself)s)' % locals())
is_ownedptr = isinstance(self.getter, ownedptr)
writer.return_value(writer.wrap(ret, is_ownedptr))
writer.println()
writer.println('@%(name)s.setter' % locals())
with writer.block('def %(name)s(self, value):' % locals()):
unself = writer.unwrap('self')
unvalue = writer.unwrap('value')
if isinstance(self.setter, ownedptr):
writer.release_ownership(unvalue)
writer.println('return _api.%(setter)s(%(unself)s, %(unvalue)s)' %
locals())
writer.println()

289
llvmpy/gen/codegen.py Normal file
View file

@ -0,0 +1,289 @@
import re, contextlib
NULL = 'NULL'
_symbols = set()
def wrap_println_from_file(file):
def println(s=''):
file.write(s)
file.write('\n')
return println
def indent(println):
def _println(s=''):
println("%s%s" % (' '* 4, s))
return _println
def quote(txt):
return '"%s"' % txt
def new_symbol(name):
if name in _symbols:
ct = 1
orig = name
while name in _symbols:
name = '%s%d' % (orig, ct)
ct += 1
_symbols.add(name)
return name
def parse_arguments(println, var, *args):
typecodes = []
holders = []
argvals = []
for arg in args:
typecodes.append(arg.format)
val = declare(println, 'PyObject*')
argvals.append(val)
holders.append('&' + val)
items = [var, '"%s"' % (''.join(typecodes))] + holders
println('if(!PyArg_ParseTuple(%s)) return NULL;' % ', '.join(items))
# unwrap
unwrapped = []
for arg, val in zip(args, argvals):
unwrapped.append(arg.unwrap(println, val))
return unwrapped
_re_mangle_pattern = re.compile(r'[ _<>\*&,]')
def mangle(name):
def repl(m):
s = m.group(0)
if s in '<>*&':
return ''
elif s in ' ,':
return '_'
elif s in '_':
return '__'
else:
assert False
name = _re_mangle_pattern.sub(repl, name)
return name.replace('::', '_')
def pycapsule_new(println, ptr, name, clsname):
# build capsule
name_soften = mangle(name)
var = new_symbol('pycap_%s' % name_soften)
fmt = 'PyObject* %(var)s = pycapsule_new(%(ptr)s, "%(name)s", "%(clsname)s");'
println(fmt % locals())
println('if (!%(var)s) return NULL;' % locals())
return var
def declare(println, typ, init=None):
typ_soften = mangle(typ)
var = new_symbol('var_%s' % typ_soften)
if init is None:
println('%(typ)s %(var)s;' % locals())
else:
println('%(typ)s %(var)s = %(init)s;' % locals())
return var
def return_value(println, var):
println('return %(var)s;' % locals())
def return_none(println):
println('Py_RETURN_NONE;')
def die_if_null(println, var):
println('if (!%(var)s) return NULL;' % locals())
class CodeWriterBase(object):
def __init__(self, println):
self.println = println
self.used_symbols = set()
@contextlib.contextmanager
def indent(self):
old = self.println
self.println = indent(self.println)
yield
self.println = old
@contextlib.contextmanager
def py_function(self, name):
self.println('static')
self.println('PyObject*')
with self.block('%(name)s(PyObject* self, PyObject* args)' % locals()):
self.used_symbols.add('self')
self.used_symbols.add('args')
yield
self.println()
def new_symbol(self, name):
if name in self.used_symbols:
ct = 1
orig = name
while name in self.used_symbols:
name = '%s%d' % (orig, ct)
ct += 1
self.used_symbols.add(name)
return name
class CppCodeWriter(CodeWriterBase):
@contextlib.contextmanager
def block(self, lead):
self.println(lead)
self.println('{')
with self.indent():
yield
self.println('}')
def declare(self, typ, init=None):
typ_soften = mangle(typ)
var = self.new_symbol('var_%s' % typ_soften)
if init is None:
self.println('%(typ)s %(var)s;' % locals())
else:
self.println('%(typ)s %(var)s = %(init)s;' % locals())
return var
def return_value(self, val):
if val is None:
self.println('Py_RETURN_NONE;')
else:
self.println('return %s;' % val)
def return_null(self):
self.return_value(NULL)
def parse_arguments(self, var, *args):
typecodes = []
holders = []
argvals = []
for arg in args:
typecodes.append(arg.format)
val = self.declare('PyObject*')
argvals.append(val)
holders.append('&' + val)
items = [var, '"%s"' % (''.join(typecodes))] + holders
with self.block('if(!PyArg_ParseTuple(%s))' % ', '.join(items)):
self.return_null()
# unwrap
unwrapped = []
for arg, val in zip(args, argvals):
unwrapped.append(arg.unwrap(self, val))
return unwrapped
def call(self, func, retty, *args):
arglist = ', '.join(args)
stmt = '%(func)s(%(arglist)s)' % locals()
if retty == 'void':
self.println(stmt + ';')
else:
return self.declare(retty, stmt)
def method_call(self, func, retty, *args):
this = args[0]
arglist = ', '.join(args[1:])
if func == 'delete':
assert not arglist
stmt = 'delete %(this)s' % locals()
elif func == 'new':
alloctype = retty.rstrip(' *')
stmt = 'new %(alloctype)s(%(arglist)s)' % locals()
else:
stmt = '%(this)s->%(func)s(%(arglist)s)' % locals()
if retty == 'void':
self.println('%s;' % stmt)
else:
return self.declare(retty, stmt)
def pycapsule_new(self, ptr, name, clsname):
name_soften = mangle(name)
ret = self.call('pycapsule_new', 'PyObject*', ptr, quote(name),
quote(clsname))
with self.block('if (!%(ret)s)' % locals()):
self.return_null()
return ret
def die_if_false(self, val, verbose=None):
with self.block('if(!%(val)s)' % locals()):
if verbose:
self.println('puts("Error: %s");' % verbose)
self.return_null()
def raises(self, exccls, msg):
exc = 'PyExc_%s' % exccls.__name__
self.println('PyErr_SetString(%s, "%s");' % (exc, msg))
self.return_null()
class PyCodeWriter(CodeWriterBase):
@contextlib.contextmanager
def block(self, lead):
self.println(lead)
with self.indent():
yield
@contextlib.contextmanager
def function(self, func, args=(), varargs=None):
with self.scope():
arguments = []
for arg in args:
arguments.append(self.new_symbol(arg))
if varargs:
varargs = self.new_symbol(varargs)
arguments.append('*%s' % varargs)
arglist = ', '.join(arguments)
with self.block('def %(func)s(%(arglist)s):' % locals()):
if arguments:
arguments[-1] = arguments[-1].lstrip('*')
if len(arguments) > 1:
yield arguments
else:
yield arguments[0]
else:
yield
@contextlib.contextmanager
def scope(self):
self.old = self.used_symbols
self.used_symbols = set()
yield
self.used_symbols = self.old
def release_ownership(self, val):
self.println('capsule.release_ownership(%(val)s)' % locals())
def unwrap_many(self, args):
unwrapped = self.new_symbol('unwrapped')
self.println('%(unwrapped)s = list(map(capsule.unwrap, %(args)s))' % locals())
return unwrapped
def unwrap(self, val):
return self.call('capsule.unwrap', args=(val,), ret='unwrapped')
def wrap(self, val, owned):
wrapped = self.new_symbol('wrapped')
self.println('%(wrapped)s = capsule.wrap(%(val)s, %(owned)s)' % locals())
return wrapped
def call(self, func, args=(), varargs=None, ret='ret'):
arguments = []
for arg in args:
arguments.append(arg)
if varargs:
arguments.append('*%s' % varargs)
arglist = ', '.join(arguments)
ret = self.new_symbol(ret)
self.println('%(ret)s = %(func)s(%(arglist)s)' % locals())
return ret
def return_value(self, val=None):
if val is None:
val = ''
self.println('return %s' % val)

107
llvmpy/gen/gen.py Normal file
View file

@ -0,0 +1,107 @@
import sys, os
from binding import *
import codegen
extension_entry = '''
extern "C" {
#if (PY_MAJOR_VERSION >= 3)
PyObject *
PyInit_%(module)s(void)
{
PyObject *module = create_python_module("%(module)s", meth_%(ns)s);
if (module) {
if (populate_submodules(module, submodule_%(ns)s))
return module;
}
return NULL;
}
#else
PyMODINIT_FUNC
init%(module)s(void)
{
PyObject *module = create_python_module("%(module)s", meth_%(ns)s);
if (module) {
populate_submodules(module, submodule_%(ns)s);
}
}
#endif
} // end extern C
'''
def populate_headers(println):
includes = [
'cstring',
'Python.h',
'python3adapt.h',
'capsulethunk.h',
'llvm_binding/conversion.h',
'llvm_binding/binding.h',
'llvm_binding/capsule_context.h',
'llvm_binding/extra.h', # extra submodule to add
]
for inc in includes:
println('#include "%s"' % inc)
println()
def main():
outputfilename = sys.argv[1]
entry_modname = sys.argv[2]
sys.path += [os.path.dirname(os.curdir)]
entry_module = __import__(entry_modname)
rootns = namespaces['']
# Generate C++ source
with open('%s.cpp' % outputfilename, 'w') as cppfile:
println = codegen.wrap_println_from_file(cppfile)
populate_headers(println) # extra headers
# print all includes
for inc in rootns.aggregate_includes():
println('#include "%s"' % inc)
println()
# print all downcast
downcast_fns = rootns.aggregate_downcast()
for ((fromty, toty), fn) in downcast_fns:
name = fn.name
fmt = '''
static
%(toty)s* %(name)s(%(fromty)s* arg)
{
return typecast< %(toty)s >::from(arg);
}
'''
println(fmt % locals())
fn.generate_cpp(println)
println('static')
println('PyMethodDef downcast_methodtable[] = {')
fmt = '{ "%(name)s", (PyCFunction)%(func)s, METH_VARARGS, NULL },'
for _, fn in downcast_fns:
name = fn.name
func = fn.c_name
println(fmt % locals())
println('{ NULL }')
println('};')
println()
# generate submodule
rootns.generate_cpp(println, extras=[('extra', 'extra_methodtable'),
('downcast', 'downcast_methodtable')])
println(extension_entry % {'module' : '_api',
'ns' : ''})
# Generate Python source
rootns.generate_py(rootdir='.', name='api')
if __name__ == '__main__':
main()

View file

@ -0,0 +1,108 @@
/**
This is a modified version of capsulethunk.h for use in llvmpy
**/
#ifndef __CAPSULETHUNK_H
#define __CAPSULETHUNK_H
//#define Assert(X) do_assert(!!(X), #X, __FILE__, __LINE__)
#define Assert(X)
static
void do_assert(int cond, const char * msg, const char *file, unsigned line){
if (not cond) {
fprintf(stderr, "Assertion failed %s:%d\n%s\n", file, line, msg);
exit(1);
}
}
#if ( (PY_VERSION_HEX < 0x02070000) \
|| ((PY_VERSION_HEX >= 0x03000000) \
&& (PY_VERSION_HEX < 0x03010000)) )
typedef void (*PyCapsule_Destructor)(PyObject *);
struct FakePyCapsule_Desc {
const char *name;
void *context;
PyCapsule_Destructor dtor;
PyObject *parent;
FakePyCapsule_Desc() : name(0), context(0), dtor(0) {}
};
static
FakePyCapsule_Desc* get_pycobj_desc(PyObject *p){
void *desc = ((PyCObject*)p)->desc;
Assert(desc && "No desc in PyCObject");
return static_cast<FakePyCapsule_Desc*>(desc);
}
static
void pycobject_pycapsule_dtor(void *p, void *desc){
Assert(desc);
Assert(p);
FakePyCapsule_Desc *fpc_desc = static_cast<FakePyCapsule_Desc*>(desc);
Assert(fpc_desc->parent);
Assert(PyCObject_Check(fpc_desc->parent));
fpc_desc->dtor(static_cast<PyObject*>(fpc_desc->parent));
delete fpc_desc;
}
static
PyObject* PyCapsule_New(void* ptr, const char *name, PyCapsule_Destructor dtor)
{
FakePyCapsule_Desc *desc = new FakePyCapsule_Desc;
desc->name = name;
desc->context = NULL;
desc->dtor = dtor;
PyObject *p = PyCObject_FromVoidPtrAndDesc(ptr, desc,
pycobject_pycapsule_dtor);
desc->parent = p;
return p;
}
static
int PyCapsule_CheckExact(PyObject *p)
{
return PyCObject_Check(p);
}
static
void* PyCapsule_GetPointer(PyObject *p, const char *name)
{
Assert(PyCapsule_CheckExact(p));
if (strcmp(get_pycobj_desc(p)->name, name) != 0) {
PyErr_SetString(PyExc_ValueError, "Invalid PyCapsule object");
}
return PyCObject_AsVoidPtr(p);
}
static
void* PyCapsule_GetContext(PyObject *p)
{
Assert(p);
Assert(PyCapsule_CheckExact(p));
return get_pycobj_desc(p)->context;
}
static
int PyCapsule_SetContext(PyObject *p, void *context)
{
Assert(PyCapsule_CheckExact(p));
get_pycobj_desc(p)->context = context;
return 0;
}
static
const char * PyCapsule_GetName(PyObject *p)
{
// Assert(PyCapsule_CheckExact(p));
return get_pycobj_desc(p)->name;
}
#endif /* #if PY_VERSION_HEX < 0x02070000 */
#endif /* __CAPSULETHUNK_H */

View file

@ -0,0 +1,37 @@
#ifndef AUTO_PYOBJECT_H_
#define AUTO_PYOBJECT_H_
#include <Python.h>
class auto_pyobject{
mutable PyObject* PO;
public:
auto_pyobject(): PO(NULL) { }
auto_pyobject(PyObject* po) : PO(po) { }
auto_pyobject(const auto_pyobject& other) : PO(*other){
other.PO = NULL;
}
~auto_pyobject() {
Py_XDECREF(PO);
}
bool operator ! () const {
return !PO;
}
PyObject* operator * () const {
return PO;
}
PyObject* get() const {
return PO;
}
private:
// disable assign
void operator = (const auto_pyobject&);
};
#endif // AUTO_PYOBJECT_H_

View file

@ -0,0 +1,87 @@
#include <Python.h>
#include <cstring>
#if (PY_MAJOR_VERSION >= 3)
static
PyObject*
create_python_module(const char *name, PyMethodDef* methtable){
PyModuleDef module_def_tmp = {
PyModuleDef_HEAD_INIT,
name,
NULL,
-1,
methtable,
NULL, NULL, NULL, NULL
};
PyModuleDef* module_def = new PyModuleDef(module_def_tmp); // will leak??
PyObject* module = PyModule_Create(module_def);
if (module == NULL){
delete module_def;
return NULL;
}
return module;
}
#else
static
PyObject*
create_python_module(const char *name, PyMethodDef* methtable){
PyObject* module = Py_InitModule(name, methtable);
if (module == NULL) return NULL;
return module;
}
#endif
static
PyObject*
create_python_submodule(PyObject* parent, const char* name,
PyMethodDef* methtable)
{
const char* parentname = PyModule_GetName(parent);
const unsigned len_parent = strlen(parentname);
const unsigned len_sub = strlen(name);
const unsigned len = len_parent + 1 + len_sub;
char* fullname = new char[len + 1];
strcpy(fullname, parentname);
fullname[len_parent] = '.';
strcpy(fullname + len_parent + 1, name);
PyObject* submod = create_python_module(fullname, methtable);
delete [] fullname;
if (!submod){
return NULL;
}
if (-1 == PyModule_AddObject(parent, name, submod)) {
return NULL;
}
Py_INCREF(submod); // otherwise, it would segfault on exit
return submod;
}
struct SubModuleEntry{
const char* name;
PyMethodDef* methtable;
SubModuleEntry* submodule;
};
static
int populate_submodules(PyObject* parent, SubModuleEntry* entries){
for(SubModuleEntry* iter = entries; iter->name; ++iter){
PyObject* submodule = create_python_submodule(parent,
iter->name,
iter->methtable);
if (!submodule){
return 0;
} else if (iter->submodule){
// Recursively populate submodules
if (!populate_submodules(submodule, iter->submodule)) {
return 0;
}
}
}
return 1;
}

View file

@ -0,0 +1,66 @@
#ifndef LLVMPY_CAPSULE_CONTEXT_H_
#define LLVMPY_CAPSULE_CONTEXT_H_
#include <iostream>
#include <ctime>
#include "capsulethunk.h"
struct CapsuleContext {
//const unsigned _magic;
const char* className;
CapsuleContext(const char* cn)
: className(cn)
{ }
};
static
void pycapsule_dtor_free_context(PyObject *pycap)
{
void * context = PyCapsule_GetContext(pycap);
Assert(context);
CapsuleContext* cc = static_cast<CapsuleContext*>(context);
//Assert(cc->_magic == 0xdead);
delete cc;
}
static
PyObject* pycapsule_new(void* ptr,
const char* basename,
const char* classname=NULL)
{
if (!classname) {
classname = basename;
}
if (!ptr) {
Py_RETURN_NONE;
}
PyObject* cap = PyCapsule_New(ptr, basename, pycapsule_dtor_free_context);
if (!cap) {
PyErr_SetString(PyExc_TypeError, "Error creating new PyCapsule");
return NULL;
}
CapsuleContext* context = new CapsuleContext(classname);
if (0 != PyCapsule_SetContext(cap, context)) {
return NULL;
}
//Assert(context->_magic == 0xdead);
return cap;
}
static
PyObject* pycapsule_new(const void* ptr,
const char* basename,
const char* classname=NULL)
{
// Use const_cast to strip the constantness.
// Let the user take the responsibility.
return pycapsule_new(const_cast<void*>(ptr), basename, classname);
}
#endif //LLVMPY_CAPSULE_CONTEXT_H_

View file

@ -0,0 +1,261 @@
#include <Python.h>
#include <llvm/Support/Casting.h>
#include <llvm/ADT/StringRef.h>
// python object unwrapper
static
int py_bytes_to(PyObject *bytesobj, llvm::StringRef &strref){
// type check
if (!PyBytes_Check(bytesobj)) {
// raises TypeError
PyErr_SetString(PyExc_TypeError, "Expecting a bytes");
return 0;
}
// get len and buffer
const Py_ssize_t len = PyBytes_Size(bytesobj);
const char * buf = PyBytes_AsString(bytesobj);
if (!buf) {
// raises TypeError
return 0;
}
// set output
strref = llvm::StringRef(buf, len);
// success
return 1;
}
static
int py_str_to(PyObject *strobj, llvm::StringRef &strref){
// type check
if (!PyString_Check(strobj)) {
// raises TypeError
PyErr_SetString(PyExc_TypeError, "Expecting a str");
return 0;
}
// get len and buffer
const Py_ssize_t len = PyString_Size(strobj);
const char * buf = PyString_AsString(strobj);
if (!buf) {
// raises TypeError
return 0;
}
// set output
strref = llvm::StringRef(buf, len);
// success
return 1;
}
static
int py_str_to(PyObject *strobj, std::string &strref){
// type check
if (!PyString_Check(strobj)) {
// raises TypeError
PyErr_SetString(PyExc_TypeError, "Expecting a str");
return 0;
}
// get len and buffer
const char * buf = PyString_AsString(strobj);
if (!buf) {
// raises TypeError
return 0;
}
// set output
strref = std::string(buf);
// success
return 1;
}
static
int py_str_to(PyObject *strobj, const char* &strref){
// type check
if (!PyString_Check(strobj)) {
// raises TypeError
PyErr_SetString(PyExc_TypeError, "Expecting a str");
return 0;
}
// get buffer
strref = PyString_AsString(strobj);
if (!strref) {
// raises TypeError
return 0;
}
// success
return 1;
}
static
int py_int_to(PyObject *intobj, int64_t & val){
if (!PyInt_Check(intobj) and !PyLong_Check(intobj)) {
// raise TypeError
PyErr_SetString(PyExc_TypeError, "Expecting an int");
return 0;
}
if (PyLong_Check(intobj)) {
val = PyLong_AsLongLong(intobj);
} else {
val = PyInt_AsLong(intobj);
}
if (PyErr_Occurred()){
return NULL;
}
// success
return 1;
}
static
int py_int_to(PyObject *intobj, unsigned & val){
if (!PyInt_Check(intobj) and !PyLong_Check(intobj)) {
// raise TypeError
PyErr_SetString(PyExc_TypeError, "Expecting an int");
return 0;
}
val = PyInt_AsUnsignedLongMask(intobj);
// success
return 1;
}
static
int py_int_to(PyObject *intobj, unsigned long long & val){
if (!PyInt_Check(intobj) and !PyLong_Check(intobj)) {
// raise TypeError;
PyErr_SetString(PyExc_TypeError, "Expecting an int");
return 0;
}
val = PyInt_AsUnsignedLongLongMask(intobj);
// success
return 1;
}
static
int py_int_to(PyObject *intobj, size_t & val){
unsigned long long ull;
if (py_int_to(intobj, ull)) {
val = (size_t)ull;
return 1;
} else {
return 0;
}
}
static
int py_int_to(PyObject *intobj, void* & val){
if (!PyInt_Check(intobj) and !PyLong_Check(intobj)) {
// raise TypeError
PyErr_SetString(PyExc_TypeError, "Expecting an int");
return 0;
}
val = PyLong_AsVoidPtr(intobj);
// success
return 1;
}
static
int py_float_to(PyObject *floatobj, double & val){
if (!PyFloat_Check(floatobj)) {
// raise TypeError
PyErr_SetString(PyExc_TypeError, "Expecting a float");
return 0;
}
val = PyFloat_AsDouble(floatobj);
if (PyErr_Occurred()){
return 0;
}
// success
return 1;
}
static
int py_float_to(PyObject *floatobj, float & val){
double db;
int status = py_float_to(floatobj, db);
if (status)
val = db;
return status;
}
static
int py_bool_to(PyObject *boolobj, bool & val){
if (!PyBool_Check(boolobj)) {
// raise TypeError
PyErr_SetString(PyExc_TypeError, "Expecting a bool");
return 0;
}
if (boolobj == Py_True) {
val = true;
} else if (boolobj == Py_False) {
val = false;
} else {
PyErr_SetString(PyExc_TypeError, "Invalid boolean object");
return 0;
}
// success
return 1;
}
// python object wrapper
static
PyObject* py_str_from(const std::string &str){
return PyString_FromStringAndSize(str.c_str(), str.size());
}
//
//static
//PyObject* py_str_from(const llvm::StringRef *str){
// return py_str_from(str->str());
//}
static
PyObject* py_bool_from(bool val){
if (val) {
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
}
}
static
PyObject* py_int_from_signed(const long long & val){
return PyLong_FromLongLong(val);
}
static
PyObject* py_int_from_unsigned(const unsigned long long & val){
return PyLong_FromUnsignedLongLong(val);
}
static
PyObject* py_int_from_unsigned(void * addr){
return PyLong_FromVoidPtr(addr);
}
static
PyObject* py_float_from(const double& val) {
return PyFloat_FromDouble(val);
}
// casting
template<class Td>
struct typecast {
template<class Ts> static
Td* from(Ts* src) {
return llvm::dyn_cast<Td>(src);
}
static
Td* from(void* src) {
return static_cast<Td*>(src);
}
};

View file

@ -0,0 +1,904 @@
#include <Python.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/Value.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Function.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/DynamicLibrary.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/Linker.h>
#include <llvm/Module.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Constants.h>
#include <llvm/Intrinsics.h>
#include <llvm/IRBuilder.h>
#include <llvm/PassRegistry.h>
#include <llvm/Support/Host.h>
#include "auto_pyobject.h"
namespace extra{
using namespace llvm;
class raw_svector_ostream_helper: public raw_svector_ostream {
SmallVectorImpl<char> *SV;
public:
static
raw_svector_ostream_helper* create()
{
SmallVectorImpl<char>* sv = new SmallVector<char, 16>();
return new raw_svector_ostream_helper(sv);
}
~raw_svector_ostream_helper()
{
delete SV;
}
protected:
explicit
raw_svector_ostream_helper(SmallVectorImpl<char>* sv)
: raw_svector_ostream(*sv), SV(sv) {}
private:
// no copy
raw_svector_ostream_helper(const raw_svector_ostream_helper&);
// no assign
void operator = (const raw_svector_ostream_helper&);
};
}
static
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;
}
raw_svector_ostream* RSOH = raw_svector_ostream_helper::create();
return pycapsule_new(RSOH, "llvm::raw_ostream",
"llvm::raw_svector_ostream");
}
static
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) {
PyObject* cap = PyTuple_GetItem(args, i);
if (!cap) {
return NULL;
}
Type* type = (Type*)PyCapsule_GetPointer(cap, "llvm::Type");
if (!type) {
return NULL;
}
SV->push_back(type);
}
return pycapsule_new(SV, "llvm::SmallVector<llvm::Type*,8>");
}
static
PyObject* make_small_vector_from_values(PyObject* self, PyObject* args)
{
using llvm::Value;
typedef llvm::SmallVector<llvm::Value*, 8> SmallVector_Value;
SmallVector_Value* SV = new SmallVector_Value;
Py_ssize_t size = PyTuple_Size(args);
for (Py_ssize_t i = 0; i < size; ++i) {
PyObject* cap = PyTuple_GetItem(args, i);
if (!cap) {
return NULL;
}
Value* value = (Value*)PyCapsule_GetPointer(cap, "llvm::Value");
if (!value) {
return NULL;
}
SV->push_back(value);
}
return pycapsule_new(SV, "llvm::SmallVector<llvm::Value*,8>");
}
static
PyObject* make_small_vector_from_unsigned(PyObject* self, PyObject* args)
{
using llvm::Value;
typedef llvm::SmallVector<unsigned, 8> SmallVector_Unsigned;
SmallVector_Unsigned* SV = new SmallVector_Unsigned;
Py_ssize_t size = PyTuple_Size(args);
for (Py_ssize_t i = 0; i < size; ++i) {
PyObject* item = PyTuple_GetItem(args, i);
if (!item) {
return NULL;
}
unsigned value = PyLong_AsUnsignedLong(item);
if (PyErr_Occurred()){
return NULL;
}
SV->push_back(value);
}
return pycapsule_new(SV, "llvm::SmallVector<unsigned,8>");
}
static
PyObject* get_llvm_version(PyObject* self, PyObject* args)
{
return Py_BuildValue("(ii)", LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR);
}
static PyMethodDef extra_methodtable[] = {
#define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL }
method( make_raw_ostream_for_printing ),
method( make_small_vector_from_types ),
method( make_small_vector_from_values ),
method( make_small_vector_from_unsigned ),
method( get_llvm_version ),
#undef method
{ NULL }
};
////////////
template<class iterator>
PyObject* iterator_to_pylist_deref(iterator begin, iterator end,
const char *capsuleName, const char *className)
{
PyObject* list = PyList_New(0);
for(; begin != end; ++begin) {
PyObject* cap = pycapsule_new(&*begin, capsuleName, className);
PyList_Append(list, cap);
}
return list;
}
template<class iterator>
PyObject* iterator_to_pylist(iterator begin, iterator end,
const char *capsuleName, const char *className)
{
PyObject* list = PyList_New(0);
for(; begin != end; ++begin) {
PyObject* cap = pycapsule_new(*begin, capsuleName, className);
PyList_Append(list, cap);
}
return list;
}
template<class iplist>
PyObject* iplist_to_pylist(iplist &IPL, const char * capsuleName,
const char* className){
return iterator_to_pylist_deref(IPL.begin(), IPL.end(), capsuleName,
className);
}
template<class ElemTy>
struct extract {
template<class VecTy>
static
bool from_py_sequence(VecTy& vec, PyObject* seq, const char *capsuleName,
bool accept_null=false)
{
Py_ssize_t N = PySequence_Size(seq);
for (Py_ssize_t i = 0; i < N; ++i) {
auto_pyobject item = PySequence_GetItem(seq, i);
if (!item) {
return false;
}
if (accept_null and Py_None == *item) {
vec.push_back(NULL);
} else {
auto_pyobject capsule = PyObject_GetAttrString(*item, "_ptr");
if (!capsule) {
return false;
}
void* ptr = PyCapsule_GetPointer(*capsule, capsuleName);
if (!ptr) {
return false;
}
ElemTy* res = typecast<ElemTy>::from(ptr);
if (!res) {
return false;
}
vec.push_back(res);
}
}
return true;
}
};
//static
//bool string_equal(const char *A, const char *B){
// for (; *A and *B; ++A, ++B) {
// if (*A != *B) return false;
// }
// return true;
//}
////////////
static
PyObject* Value_use_iterator_to_list(llvm::Value* val)
{
return iterator_to_pylist(val->use_begin(), val->use_end(),
"llvm::Value", "llvm::User");
}
static
PyObject* Function_getArgumentList(llvm::Function* fn)
{
return iplist_to_pylist(fn->getArgumentList(), "llvm::Value",
"llvm::Argument");
}
static
PyObject* Function_getBasicBlockList(llvm::Function* fn)
{
return iplist_to_pylist(fn->getBasicBlockList(), "llvm::Value",
"llvm::BasicBlock");
}
/*
* errout --- can be any file object
*
*/
static
llvm::ExecutionEngine* ExecutionEngine_create(
llvm::Module* M,
bool ForceInterpreter = false,
PyObject* errout = 0,
llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default,
bool GVsWithCode = true)
{
using namespace llvm;
std::string ErrorStr;
ExecutionEngine *ee = ExecutionEngine::create(M, ForceInterpreter,
&ErrorStr, OptLevel,
GVsWithCode);
PyFile_WriteString(ErrorStr.c_str(), errout);
return ee;
}
/*
* errout --- can be any file object
*
*/
static
llvm::ExecutionEngine* ExecutionEngine_createJIT(
llvm::Module* M,
PyObject* errout = 0,
llvm::JITMemoryManager* JMM = 0,
llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default,
bool GCsWithCode = true,
llvm::Reloc::Model RM = llvm::Reloc::Default,
llvm::CodeModel::Model CMM = llvm::CodeModel::JITDefault)
{
using namespace llvm;
std::string ErrorStr;
ExecutionEngine *ee = ExecutionEngine::createJIT(M, &ErrorStr, JMM, OL,
GCsWithCode, RM, CMM);
PyFile_WriteString(ErrorStr.c_str(), errout);
return ee;
}
static
llvm::GenericValue* GenericValue_CreateInt(llvm::Type* Ty, unsigned long long N,
bool IsSigned)
{
// Shamelessly copied from LLVM
llvm::GenericValue *GenVal = new llvm::GenericValue();
GenVal->IntVal = llvm::APInt(Ty->getIntegerBitWidth(), N, IsSigned);
return GenVal;
}
static
llvm::GenericValue* GenericValue_CreateFloat(float Val)
{
llvm::GenericValue *GenVal = new llvm::GenericValue();
GenVal->FloatVal = Val;
return GenVal;
}
static
llvm::GenericValue* GenericValue_CreateDouble(double Val)
{
llvm::GenericValue *GenVal = new llvm::GenericValue();
GenVal->DoubleVal = Val;
return GenVal;
}
static
llvm::GenericValue* GenericValue_CreatePointer(void * Ptr)
{
llvm::GenericValue *GenVal = new llvm::GenericValue();
GenVal->PointerVal = Ptr;
return GenVal;
}
static
unsigned GenericValue_ValueIntWidth(llvm::GenericValue *GenValRef)
{
return GenValRef->IntVal.getBitWidth();
}
static
unsigned long long GenericValue_ToUnsignedInt(llvm::GenericValue* GenVal)
{
return GenVal->IntVal.getZExtValue();
}
static
long long GenericValue_ToSignedInt(llvm::GenericValue* GenVal)
{
return GenVal->IntVal.getSExtValue();
}
static
void* GenericValue_ToPointer(llvm::GenericValue* GenVal)
{
return GenVal->PointerVal;
}
static
double GenericValue_ToFloat(llvm::GenericValue* GenVal, llvm::Type* Ty)
{
switch (Ty->getTypeID()) {
case llvm::Type::FloatTyID:
return GenVal->FloatVal;
default:
// Behavior undefined if type is not a float or a double
return GenVal->DoubleVal;
}
}
static
PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE,
llvm::Function* Fn, PyObject* Args)
{
using namespace llvm;
const char * GVN = "llvm::GenericValue";
if (!PyTuple_Check(Args)) {
PyErr_SetString(PyExc_TypeError, "Expect a tuple of args.");
return NULL;
}
std::vector<GenericValue> vec_args;
Py_ssize_t nargs = PyTuple_Size(Args);
vec_args.reserve(nargs);
for (Py_ssize_t i = 0; i < nargs; ++i) {
PyObject* obj = PyTuple_GetItem(Args, i);
if (!obj) {
PyErr_SetString(PyExc_RuntimeError, "Failed to index into args?");
return NULL;
}
GenericValue* gv = static_cast<GenericValue*>(
PyCapsule_GetPointer(obj, GVN));
if (!gv) {
return NULL;
}
vec_args.push_back(*gv);
}
GenericValue ret = EE->runFunction(Fn, vec_args);
return pycapsule_new(new GenericValue(ret), GVN);
}
static
PyObject* EngineBuilder_setErrorStr(llvm::EngineBuilder* eb, PyObject* fileobj)
{
if (!PyFile_Check(fileobj)) {
PyErr_SetString(PyExc_TypeError, "Expecting a file object.");
return NULL;
}
std::string buffer;
eb->setErrorStr(&buffer);
if (-1 == PyFile_WriteString(buffer.c_str(), fileobj)) {
return NULL;
}
return pycapsule_new(eb, "llvm::EngineBuilder");
}
static
PyObject* EngineBuilder_setMAttrs(llvm::EngineBuilder* eb,
PyObject* strlist)
{
if (!PyList_Check(strlist)) {
PyErr_SetString(PyExc_TypeError, "Expecting a list of string.");
return NULL;
}
std::vector<const char*> tmp;
const Py_ssize_t N = PyList_Size(strlist);
tmp.reserve(N);
for (Py_ssize_t i = 0; i < N; ++i) {
const char * elem = PyString_AsString(PyList_GetItem(strlist, i));
if (!elem) {
return NULL;
}
tmp.push_back(elem);
}
eb->setMAttrs(tmp);
return pycapsule_new(eb, "llvm::EngineBuilder");
}
static
PyObject* EngineBuilder_selectTarget(llvm::EngineBuilder* eb,
const llvm::Triple& TargetTriple,
llvm::StringRef MArch,
llvm::StringRef MCPU,
PyObject* strlist)
{
const Py_ssize_t N = PySequence_Size(strlist);
llvm::SmallVector<std::string, 8> MAttrs;
MAttrs.reserve(N);
for (Py_ssize_t i = 0; i < N; ++i) {
PyObject* str = PySequence_GetItem(strlist, i);
const char * cp = PyString_AsString(str);
if (!cp) {
Py_DECREF(str);
return NULL;
}
MAttrs.push_back(cp);
Py_DECREF(str);
}
eb->selectTarget(TargetTriple, MArch, MCPU, MAttrs);
return pycapsule_new(eb, "llvm::EngineBuilder");
}
static
PyObject* llvm_ParseBitCodeFile(llvm::StringRef Buf, llvm::LLVMContext& Ctx,
PyObject* FObj=NULL)
{
using namespace llvm;
MemoryBuffer* MB = MemoryBuffer::getMemBuffer(Buf);
Module* M;
if (FObj) {
std::string ErrStr;
M = ParseBitcodeFile(MB, Ctx, &ErrStr);
auto_pyobject buf = PyBytes_FromString(ErrStr.c_str());
if (NULL == PyObject_CallMethod(FObj, "write", "O", *buf)){
return NULL;
}
// if (-1 == PyFile_WriteString(ErrStr.c_str(), FObj)) {
// return NULL;
// }
} else {
M = ParseBitcodeFile(MB, Ctx);
}
delete MB;
return pycapsule_new(M, "llvm::Module");
}
static
PyObject* llvm_WriteBitcodeToFile(const llvm::Module *M, PyObject* FObj)
{
using namespace llvm;
llvm::SmallVector<char, 32> sv;
llvm::raw_svector_ostream rso(sv);
llvm::WriteBitcodeToFile(M, rso);
rso.flush();
StringRef ref = rso.str();
auto_pyobject buf = PyBytes_FromStringAndSize(ref.data(), ref.size());
return PyObject_CallMethod(FObj, "write", "O", *buf);
}
static
PyObject* llvm_getBitcodeTargetTriple(llvm::StringRef Buf,
llvm::LLVMContext& Ctx,
PyObject* FObj = NULL)
{
using namespace llvm;
MemoryBuffer* MB = MemoryBuffer::getMemBuffer(Buf);
std::string Triple;
if (FObj) {
std::string ErrStr;
Triple = getBitcodeTargetTriple(MB, Ctx, &ErrStr);
if (-1 == PyFile_WriteString(ErrStr.c_str(), FObj)) {
return NULL;
}
} else {
Triple = getBitcodeTargetTriple(MB, Ctx);
}
delete MB;
return PyString_FromString(Triple.c_str());
}
static
PyObject* TargetMachine_addPassesToEmitFile(
llvm::TargetMachine *TM,
llvm::PassManagerBase & PM,
PyObject* Out,
llvm::TargetMachine::CodeGenFileType FTy,
bool disableVerify=true)
{
using namespace llvm;
llvm::SmallVector<char, 32> sv;
raw_svector_ostream rso(sv);
formatted_raw_ostream fso(rso);
fso.flush();
bool status = TM->addPassesToEmitFile(PM, fso, FTy, disableVerify);
if (status) {
StringRef sr = rso.str();
PyObject* buf = PyString_FromStringAndSize(sr.data(), sr.size());
if (!buf) {
return NULL;
}
if (-1 == PyFile_WriteObject(buf, Out, Py_PRINT_RAW)){
return NULL;
}
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
}
}
static
PyObject* Constant_getIntegerValue(llvm::Type* Ty, PyObject* pyint)
{
using namespace llvm;
if (!Ty->isIntegerTy()) {
PyErr_SetString(PyExc_ValueError, "Type should be of integer type.");
return NULL;
}
unsigned width = Ty->getIntegerBitWidth();
if (width > sizeof(unsigned long long)*8) {
PyErr_SetString(PyExc_ValueError, "Integer value is too large.");
}
Constant* K;
if (PyLong_Check(pyint)){
APInt apint(width, PyLong_AsLongLong(pyint), true);
K = Constant::getIntegerValue(Ty, apint);
} else {
APInt apint(width, PyInt_AsLong(pyint), true);
K = Constant::getIntegerValue(Ty, apint);
}
return pycapsule_new(K, "llvm::Value", "llvm::Constant");
}
static
PyObject* Linker_LinkInModule(llvm::Linker* Linker,
llvm::Module* Mod,
PyObject* ErrMsg)
{
std::string errmsg;
bool failed = Linker->LinkInModule(Mod, &errmsg);
if (not failed) {
Py_RETURN_FALSE;
} else {
if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) {
return NULL;
}
Py_RETURN_TRUE;
}
}
static
PyObject* Linker_LinkModules(llvm::Module* Dest,
llvm::Module* Src,
unsigned Mode,
PyObject* ErrMsg)
{
std::string errmsg;
bool failed = llvm::Linker::LinkModules(Dest, Src, Mode, &errmsg);
if (not failed) {
Py_RETURN_FALSE;
} else {
if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) {
return NULL;
}
Py_RETURN_TRUE;
}
}
static
PyObject* StructType_setBody(llvm::StructType* Self,
PyObject* Elems,
bool isPacked=false)
{
using namespace llvm;
std::vector<Type*> elements;
extract<Type>::from_py_sequence(elements, Elems, "llvm::Type");
Self->setBody(elements, isPacked);
Py_RETURN_NONE;
}
static
PyObject* StructType_get(llvm::LLVMContext& Cxt,
PyObject* Elems,
bool isPacked=false)
{
using namespace llvm;
std::vector<Type*> elements;
extract<Type>::from_py_sequence(elements, Elems, "llvm::Type");
StructType *sty = StructType::get(Cxt, elements, isPacked);
return pycapsule_new(sty, "llvm::Type", "llvm::StructType");
}
static
PyObject* Module_list_globals(llvm::Module* Mod)
{
return iplist_to_pylist(Mod->getGlobalList(),
"llvm::Value", "llvm::GlobalVariable");
}
static
PyObject* Module_list_functions(llvm::Module* Mod)
{
return iplist_to_pylist(Mod->getFunctionList(),
"llvm::Value", "llvm::Function");
}
static
PyObject* Module_list_named_metadata(llvm::Module* Mod)
{
return iplist_to_pylist(Mod->getFunctionList(),
"llvm::NamedMDNode", "llvm::NamedMDNode");
}
static
PyObject* llvm_verifyModule(const llvm::Module& Fn,
llvm::VerifierFailureAction Action,
PyObject* ErrMsg)
{
std::string errmsg;
bool failed = llvm::verifyModule(Fn, Action, &errmsg);
if (failed) {
if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) {
return NULL;
}
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
}
}
static
PyObject* ConstantArray_get(llvm::ArrayType* Ty, PyObject* Consts)
{
using namespace llvm;
std::vector<Constant*> vec_consts;
bool ok = extract<Constant>::from_py_sequence(vec_consts, Consts,
"llvm::Value");
if (not ok) return NULL;
Constant* ary = ConstantArray::get(Ty, vec_consts);
return pycapsule_new(ary, "llvm::Value", "llvm::Constant");
}
static
PyObject* ConstantStruct_get(llvm::StructType* Ty, PyObject* Elems)
{
using namespace llvm;
std::vector<Constant*> vec_consts;
bool ok = extract<Constant>::from_py_sequence(vec_consts, Elems,
"llvm::Value");
if (not ok) return NULL;
Constant* ary = ConstantStruct::get(Ty, vec_consts);
return pycapsule_new(ary, "llvm::Value", "llvm::Constant");
}
static
PyObject* ConstantStruct_getAnon(PyObject* Elems,
bool isPacked=false)
{
using namespace llvm;
std::vector<Constant*> vec_consts;
bool ok = extract<Constant>::from_py_sequence(vec_consts, Elems,
"llvm::Value");
if (not ok) return NULL;
Constant* ary = ConstantStruct::getAnon(vec_consts, isPacked);
return pycapsule_new(ary, "llvm::Value", "llvm::Constant");
}
static
PyObject* ConstantVector_get(PyObject* Elems)
{
using namespace llvm;
std::vector<Constant*> vec_consts;
bool ok = extract<Constant>::from_py_sequence(vec_consts, Elems,
"llvm::Value");
if (not ok) return NULL;
Constant* ary = ConstantVector::get(vec_consts);
return pycapsule_new(ary, "llvm::Value", "llvm::Constant");
}
static
PyObject* Intrinsic_getDeclaration(llvm::Module* Mod,
unsigned ID,
PyObject* Types=NULL)
{
using namespace llvm;
Function* Fn = NULL;
if (Types) {
std::vector<Type*> types;
bool ok = extract<Type>::from_py_sequence(types, Types, "llvm::Type");
if (!ok) return NULL;
Fn = Intrinsic::getDeclaration(Mod, (Intrinsic::ID)ID, types);
} else {
Fn = Intrinsic::getDeclaration(Mod, (Intrinsic::ID)ID);
}
return pycapsule_new(Fn, "llvm::Value", "llvm::Function");
}
static
PyObject* MDNode_get(llvm::LLVMContext &Cxt, PyObject* Vals)
{
std::vector<llvm::Value*> vals;
bool accept_null = true;
bool ok = extract<llvm::Value>::from_py_sequence(vals, Vals, "llvm::Value",
accept_null);
if (not ok) return NULL;
llvm::MDNode* md = llvm::MDNode::get(Cxt, vals);
return pycapsule_new(md, "llvm::Value", "llvm::MDNode");
}
static
PyObject* BasicBlock_getInstList(llvm::BasicBlock* BB)
{
return iplist_to_pylist(BB->getInstList(),
"llvm::Value",
"llvm::Instruction");
}
static
PyObject* IRBuilder_CreateAggregateRet(llvm::IRBuilder<>* builder,
PyObject* Vals,
unsigned N)
{
using namespace llvm;
std::vector<Value*> vec_values;
bool ok = extract<Value>::from_py_sequence(vec_values, Vals, "llvm::Value");
if (not ok) return NULL;
Value** ptr_values = &vec_values[0];
ReturnInst* inst = builder->CreateAggregateRet(ptr_values, N);
return pycapsule_new(inst, "llvm::Value", "llvm::ReturnInst");
}
static
PyObject* DynamicLibrary_LoadLibraryPermanently(const char * Filename,
PyObject* ErrMsg = 0)
{
using namespace llvm::sys;
bool failed;
if (ErrMsg) {
std::string errmsg;
failed = DynamicLibrary::LoadLibraryPermanently(Filename, &errmsg);
if (failed) {
if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) {
return NULL;
}
}
} else {
failed = DynamicLibrary::LoadLibraryPermanently(Filename);
}
if (failed) {
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
}
}
class PassRegistryEnumerator : public llvm::PassRegistrationListener{
public:
PyObject* List;
public:
PassRegistryEnumerator(PyObject* list) : List(list) { }
inline virtual void passEnumerate(const llvm::PassInfo * pass_info){
PyObject* passArg = PyString_FromString(pass_info->getPassArgument());
PyObject* passName = PyString_FromString(pass_info->getPassName());
PyList_Append(List, Py_BuildValue("(OO)", passArg, passName));
}
};
static
PyObject* PassRegistry_enumerate(llvm::PassRegistry* PR)
{
using namespace llvm;
PassRegistryEnumerator PRE(PyList_New(0));
PR->enumerateWith(&PRE);
return PRE.List;
}
static
PyObject* TargetRegistry_lookupTarget(const std::string &Triple,
PyObject* Error)
{
using namespace llvm;
std::string error;
const Target* target = TargetRegistry::lookupTarget(Triple, error);
if (!target) {
PyFile_WriteString(error.c_str(), Error);
Py_RETURN_NONE;
} else {
return pycapsule_new(const_cast<Target*>(target), "llvm::Target");
}
}
static
PyObject* TargetRegistry_lookupTarget(const std::string &Arch,
llvm::Triple &Triple,
PyObject* Error)
{
using namespace llvm;
std::string error;
const Target* target = TargetRegistry::lookupTarget(Arch, Triple, error);
if (!target) {
PyFile_WriteString(error.c_str(), Error);
Py_RETURN_NONE;
} else {
return pycapsule_new(const_cast<Target*>(target), "llvm::Target");
}
}
static
PyObject* TargetRegistry_getClosestTargetForJIT(PyObject* Error)
{
using namespace llvm;
std::string error;
const Target* target = TargetRegistry::getClosestTargetForJIT(error);
if (!target) {
PyFile_WriteString(error.c_str(), Error);
Py_RETURN_NONE;
} else {
return pycapsule_new(const_cast<Target*>(target), "llvm::Target");
}
}
static
PyObject* llvm_sys_getHostCPUFeatures(PyObject* Features)
{
using namespace llvm::sys;
using namespace llvm;
typedef StringMap<bool>::iterator iterator;
StringMap<bool> features;
bool ok = getHostCPUFeatures(features);
if (ok) {
for (iterator it = features.begin(); it != features.end(); ++it) {
const char *key = it->getKey().data();
PyObject *val = it->getValue() ? Py_True : Py_False;
Py_INCREF(val);
if (-1 == PyDict_SetItemString(Features, key, val)) {
return NULL;
}
}
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
}
}

View file

@ -0,0 +1,32 @@
#ifndef PYTHON3ADAPT_H
#define PYTHON3ADAPT_H
#if (PY_VERSION_HEX < 0x03000000)
#define PyBytes_Check PyString_Check
#define PyBytes_Size PyString_Size
#define PyBytes_AsString PyString_AsString
#define PyBytes_FromStringAndSize PyString_FromStringAndSize
#define PyBytes_FromString PyString_FromString
#endif
#if (PY_VERSION_HEX >= 0x03000000)
#define PyString_Check PyUnicode_Check
#define PyString_Size PyUnicode_GET_SIZE
#define PyString_AsString PyUnicode_AsUTF8
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
#define PyString_FromString PyUnicode_FromString
#define PyInt_Check PyLong_Check
#define PyInt_FromLong PyLong_FromLong
#define PyInt_AsLong PyLong_AsLong
#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
#define PyFile_Check(x) (1)
#endif
#endif //PYTHON3ADAPT_H

64
llvmpy/setup.py Normal file
View file

@ -0,0 +1,64 @@
import sys, os
from distutils.core import setup, Extension
llvm_config = os.environ.get('LLVM_CONFIG_PATH')
def run_llvm_config(args):
cmd = llvm_config + ' ' + ' '.join(args)
return os.popen(cmd).read().rstrip()
def get_libs_and_objs(components):
parts = run_llvm_config(['--libs'] + components).split()
libs = []
objs = []
for part in parts:
if part.startswith('-l'):
libs.append(part[2:])
elif part.endswith('.o'):
objs.append(part)
return libs, objs
incdir = run_llvm_config(['--includedir'])
libdir = run_llvm_config(['--libdir'])
ldflags = run_llvm_config(['--ldflags'])
macros = [('__STDC_CONSTANT_MACROS', None),
('__STDC_LIMIT_MACROS', None)]
extra_link_args = ldflags.split()
components = ['core', 'analysis', 'scalaropts',
'executionengine', 'jit', 'native',
'interpreter', 'bitreader',
'bitwriter', 'instrumentation', 'ipa',
'ipo', 'transformutils', 'asmparser',
'linker', 'support', 'vectorize',
]
nvptx = ['nvptx',
'nvptxasmprinter',
'nvptxcodegen',
'nvptxdesc',
'nvptxinfo']
libs_core, objs_core = get_libs_and_objs(components + nvptx)
ext_modules = [Extension(name='_api',
sources=['api.cpp'],
include_dirs = ['include', incdir],
library_dirs = [libdir],
libraries = libs_core,
define_macros = macros,
extra_objects = objs_core,
extra_link_args = extra_link_args),
Extension(name='_capsule',
sources=['capsule.cpp'],
include_dirs = ['include'],),
]
setup(name = 'llvmpy2',
description = 'Python bindings for LLVM',
author = 'Siu Kwan Lam',
ext_modules = ext_modules,
license = "BSD")

View file

@ -0,0 +1,17 @@
from binding import *
from ..namespace import llvm
@llvm.Class()
class SmallVector_Type:
_realname_ = 'SmallVector<llvm::Type*,8>'
delete = Destructor()
@llvm.Class()
class SmallVector_Value:
_realname_ = 'SmallVector<llvm::Value*,8>'
delete = Destructor()
@llvm.Class()
class SmallVector_Unsigned:
_realname_ = 'SmallVector<unsigned,8>'
delete = Destructor()

View file

@ -0,0 +1,7 @@
from binding import *
from ..namespace import llvm
@llvm.Class()
class StringRef:
_include_ = "llvm/ADT/StringRef.h"

55
llvmpy/src/ADT/Triple.py Normal file
View file

@ -0,0 +1,55 @@
from binding import *
from ..namespace import llvm
from .StringRef import StringRef
Triple = llvm.Class()
@Triple
class Triple:
_include_ = 'llvm/ADT/Triple.h'
new = Constructor()
new |= Constructor(cast(str, StringRef))
new |= Constructor(cast(str, StringRef),
cast(str, StringRef), cast(str, StringRef))
def _return_str():
return Method(cast(StringRef, str))
getTriple = _return_str()
getArchName = _return_str()
getVendorName = _return_str()
getOSName = _return_str()
getEnvironmentName = _return_str()
getOSAndEnvironmentName = _return_str()
@CustomPythonMethod
def __str__(self):
return self.getTriple()
def _return_bool(*args):
return Method(cast(bool, Bool), *args)
isArch64Bit = _return_bool()
isArch32Bit = _return_bool()
isArch16Bit = _return_bool()
isOSVersionLT = _return_bool(cast(int, Unsigned),
cast(int, Unsigned),
cast(int, Unsigned)).require_only(1)
isMacOSXVersionLT = _return_bool(cast(int, Unsigned),
cast(int, Unsigned),
cast(int, Unsigned)).require_only(1)
isMacOSX = _return_bool()
isOSDarwin = _return_bool()
isOSCygMing = _return_bool()
isOSWindows = _return_bool()
# isOSNaCl = _return_bool()
isOSBinFormatELF = _return_bool()
isOSBinFormatCOFF = _return_bool()
isEnvironmentMachO = _return_bool()
get32BitArchVariant = Method(Triple)
get64BitArchVariant = Method(Triple)

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

View file

@ -0,0 +1,25 @@
from binding import *
from ..namespace import llvm
from ..Module import Module
from ..Value import Function
llvm.includes.add('llvm/Analysis/Verifier.h')
VerifierFailureAction = llvm.Enum('VerifierFailureAction',
'''AbortProcessAction
PrintMessageAction
ReturnStatusAction''')
verifyModule = llvm.CustomFunction('verifyModule',
'llvm_verifyModule',
PyObjectPtr, # boolean -- failed?
ref(Module),
VerifierFailureAction,
PyObjectPtr, # errmsg
)
verifyFunction = llvm.Function('verifyFunction',
cast(Bool, bool), # failed?
ref(Function),
VerifierFailureAction)

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

15
llvmpy/src/Argument.py Normal file
View file

@ -0,0 +1,15 @@
from binding import *
from .namespace import llvm
from .Value import Argument, Value
from .Attributes import Attributes
@Argument
class Argument:
_include_ = 'llvm/Argument.h'
_downcast_ = Value
addAttr = Method(Void, ref(Attributes))
removeAttr = Method(Void, ref(Attributes))
getParamAlignment = Method(cast(Unsigned, int))

View file

@ -0,0 +1,7 @@
from binding import *
from ..namespace import llvm
@llvm.Class()
class AssemblyAnnotationWriter:
_include_ = "llvm/Assembly/AssemblyAnnotationWriter.h"

View file

@ -0,0 +1,14 @@
from binding import *
from ..namespace import llvm
from ..Module import Module
from ..LLVMContext import LLVMContext
from ..Support.SourceMgr import SMDiagnostic
llvm.includes.add('llvm/Assembly/Parser.h')
ParseAssemblyString = llvm.Function('ParseAssemblyString',
ptr(Module),
cast(str, ConstCharPtr),
ptr(Module), # can be None
ref(SMDiagnostic),
ref(LLVMContext))

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

39
llvmpy/src/Attributes.py Normal file
View file

@ -0,0 +1,39 @@
from binding import *
from .namespace import llvm
from .LLVMContext import LLVMContext
llvm.includes.add('llvm/Attributes.h')
Attributes = llvm.Class()
AttrBuilder = llvm.Class()
@Attributes
class Attributes:
AttrVal = Enum('''None, AddressSafety, Alignment, AlwaysInline,
ByVal, InlineHint, InReg, MinSize,
Naked, Nest, NoAlias, NoCapture,
NoImplicitFloat, NoInline, NonLazyBind, NoRedZone,
NoReturn, NoUnwind, OptimizeForSize, ReadNone,
ReadOnly, ReturnsTwice, SExt, StackAlignment,
StackProtect, StackProtectReq, StructRet, UWTable, ZExt''')
delete = Destructor()
get = StaticMethod(Attributes, ref(LLVMContext), ref(AttrBuilder))
@AttrBuilder
class AttrBuilder:
new = Constructor()
delete = Destructor()
clear = Method()
addAttribute = Method(ref(AttrBuilder), Attributes.AttrVal)
removeAttribute = Method(ref(AttrBuilder), Attributes.AttrVal)
addAlignmentAttr = Method(ref(AttrBuilder), cast(int, Unsigned))

26
llvmpy/src/BasicBlock.py Normal file
View file

@ -0,0 +1,26 @@
from binding import *
from .namespace import llvm
from .Value import Function, BasicBlock
from .Instruction import Instruction, TerminatorInst
from .LLVMContext import LLVMContext
from .ADT.StringRef import StringRef
@BasicBlock
class BasicBlock:
Create = StaticMethod(ptr(BasicBlock), ref(LLVMContext),
cast(str, StringRef),
ptr(Function),
ptr(BasicBlock))
getParent = Method(ptr(Function))
getTerminator = Method(ptr(TerminatorInst))
empty = Method(cast(Bool, bool))
dropAllReferences = Method()
isLandingPad = Method(cast(Bool, bool))
removePredecessor = Method(Void, ptr(BasicBlock), cast(bool, Bool))
removePredecessor |= Method(Void, ptr(BasicBlock))
getInstList = CustomMethod('BasicBlock_getInstList', PyObjectPtr)
eraseFromParent = Method()

View file

@ -0,0 +1,30 @@
from binding import *
from ..namespace import llvm
from ..ADT.StringRef import StringRef
from ..Module import Module
from ..LLVMContext import LLVMContext
llvm.includes.add('llvm/Bitcode/ReaderWriter.h')
ParseBitCodeFile = llvm.CustomFunction('ParseBitCodeFile',
'llvm_ParseBitCodeFile',
PyObjectPtr, # returns Module*
cast(bytes, StringRef),
ref(LLVMContext),
PyObjectPtr, # file-like object
).require_only(2)
WriteBitcodeToFile = llvm.CustomFunction('WriteBitcodeToFile',
'llvm_WriteBitcodeToFile',
PyObjectPtr, # return None
ptr(Module),
PyObjectPtr, # file-like object
)
getBitcodeTargetTriple = llvm.CustomFunction('getBitcodeTargetTriple',
'llvm_getBitcodeTargetTriple',
PyObjectPtr, # return str
cast(str, StringRef),
ref(LLVMContext),
PyObjectPtr, # file-like object
).require_only(2)

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

10
llvmpy/src/CallingConv.py Normal file
View file

@ -0,0 +1,10 @@
from binding import *
from .namespace import llvm
CallingConv = llvm.Namespace('CallingConv')
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

@ -0,0 +1,13 @@
from binding import *
from ..namespace import llvm
MachineCodeInfo = llvm.Class()
@MachineCodeInfo
class MachineCodeInfo:
_include_ = 'llvm/CodeGen/MachineCodeInfo.h'
setSize = Method(Void, cast(int, Size_t))
setAddress = Method(Void, cast(int, VoidPtr))
size = Method(cast(Size_t, int))
address = Method(cast(VoidPtr, int))

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

274
llvmpy/src/Constant.py Normal file
View file

@ -0,0 +1,274 @@
from binding import *
from .namespace import llvm
from .Value import Value
from .Value import Constant, UndefValue, ConstantInt, ConstantFP, ConstantArray
from .Value import ConstantStruct, ConstantVector, ConstantVector
from .Value import ConstantDataSequential, ConstantDataArray, ConstantExpr
from .LLVMContext import LLVMContext
from .ADT.StringRef import StringRef
from .ADT.SmallVector import SmallVector_Value, SmallVector_Unsigned
from .Type import Type, IntegerType, ArrayType, StructType
from .Instruction import CmpInst
@Constant
class Constant:
_downcast_ = Value
isNullValue = Method(cast(bool, Bool))
isAllOnesValue = Method(cast(bool, Bool))
isNegativeZeroValue = Method(cast(bool, Bool))
#isZeroValue = Method(cast(bool, Bool))
canTrap = Method(cast(bool, Bool))
isThreadDependent = Method(cast(bool, Bool))
isConstantUsed = Method(cast(bool, Bool))
_getAggregateElement_by_int = Method(ptr(Constant), cast(int, Unsigned))
_getAggregateElement_by_int.realname = 'getAggregateElement'
_getAggregateElement_by_const = Method(ptr(Constant), ptr(Constant))
_getAggregateElement_by_const.realname = 'getAggregateElement'
@CustomPythonMethod
def getAggregateElement(self, elt):
if isinstance(elt, Constant):
return self._getAggregateElement_by_const(elt)
else:
return self._getAggregateElement_by_int(elt)
removeDeadConstantUsers = Method()
getNullValue = StaticMethod(ptr(Constant), ptr(Type))
getAllOnesValue = StaticMethod(ptr(Constant), ptr(Type))
getIntegerValue = CustomStaticMethod('Constant_getIntegerValue',
PyObjectPtr, # ptr(Constant),
ptr(Type),
PyObjectPtr)
@UndefValue
class UndefValue:
getSequentialElement = Method(ptr(UndefValue))
getStructElement = Method(ptr(UndefValue), cast(int, Unsigned))
_getElementValue_by_const = Method(ptr(UndefValue), ptr(Constant))
_getElementValue_by_const.realname = 'getElementValue'
_getElementValue_by_int = Method(ptr(UndefValue), cast(int, Unsigned))
_getElementValue_by_int.realname = 'getElementValue'
@CustomPythonMethod
def getElementValue(self, idx):
if isinstance(idx, Constant):
return self._getElementValue_by_const(idx)
else:
return self._getElementValue_by_int(idx)
destroyConstant = Method()
get = StaticMethod(ptr(UndefValue), ptr(Type))
@ConstantInt
class ConstantInt:
_downcast_ = Constant, Value
get = StaticMethod(ptr(ConstantInt),
ptr(IntegerType),
cast(int, Uint64),
cast(bool, Bool),
).require_only(2)
isValueValidForType = StaticMethod(cast(Bool, bool),
ptr(Type),
cast(int, Int64))
getZExtValue = Method(cast(Uint64, int))
getSExtValue = Method(cast(Int64, int))
@ConstantFP
class ConstantFP:
_downcast_ = Constant, Value
get = StaticMethod(ptr(Constant), ptr(Type), cast(float, Double))
getNegativeZero = StaticMethod(ptr(ConstantFP), ptr(Type))
getInfinity = StaticMethod(ptr(ConstantFP), ptr(Type), cast(bool, Bool))
isZero = Method(cast(Bool, bool))
isNegative = Method(cast(Bool, bool))
isNaN = Method(cast(Bool, bool))
@ConstantArray
class ConstantArray:
_downcast_ = Constant, Value
get = CustomStaticMethod('ConstantArray_get',
PyObjectPtr, # ptr(Constant),
ptr(ArrayType),
PyObjectPtr, # Constants
)
@ConstantStruct
class ConstantStruct:
_downcast_ = Constant, Value
get = CustomStaticMethod('ConstantStruct_get',
PyObjectPtr, # ptr(Constant)
ptr(StructType),
PyObjectPtr, # Constants
)
getAnon = CustomStaticMethod('ConstantStruct_getAnon',
PyObjectPtr, # ptr(Constant)
PyObjectPtr, # constants
cast(bool, Bool), # packed
).require_only(1)
@ConstantVector
class ConstantVector:
_downcast_ = Constant, Value
get = CustomStaticMethod('ConstantVector_get',
PyObjectPtr, # ptr(Constant)
PyObjectPtr, # constants
)
@ConstantDataSequential
class ConstantDataSequential:
_downcast_ = Constant, Value
@ConstantDataArray
class ConstantDataArray:
_downcast_ = Constant, Value
getString = StaticMethod(ptr(Constant),
ref(LLVMContext),
cast(str, StringRef),
cast(bool, Bool)
).require_only(2)
def _factory(*args):
return StaticMethod(ptr(Constant), *args)
def _factory_const(*args):
return _factory(ptr(Constant), *args)
def _factory_const2(*args):
return _factory(ptr(Constant), ptr(Constant), *args)
def _factory_const_nuw_nsw():
return _factory_const(cast(bool, Bool), cast(bool, Bool)).require_only(1)
def _factory_const2_nuw_nsw():
return _factory_const2(cast(bool, Bool), cast(bool, Bool)).require_only(2)
def _factory_const2_exact():
return _factory_const2(cast(bool, Bool)).require_only(2)
def _factory_const_type():
return _factory_const(ptr(Type))
@ConstantExpr
class ConstantExpr:
_downcast_ = Constant, Value
getAlignOf = _factory(ptr(Type))
getSizeOf = _factory(ptr(Type))
getOffsetOf = _factory(ptr(Type), ptr(Constant))
getNeg = _factory_const_nuw_nsw()
getFNeg = _factory_const()
getNot = _factory_const()
getAdd = _factory_const2_nuw_nsw()
getFAdd = _factory_const2()
getSub = _factory_const2_nuw_nsw()
getFSub = _factory_const2()
getMul = _factory_const2_nuw_nsw()
getFMul = _factory_const2()
getUDiv = _factory_const2_exact()
getSDiv = _factory_const2_exact()
getFDiv = _factory_const2()
getURem = _factory_const2()
getSRem = _factory_const2()
getFRem = _factory_const2()
getAnd = _factory_const2()
getOr = _factory_const2()
getXor = _factory_const2()
getShl = _factory_const2_nuw_nsw()
getLShr = _factory_const2_exact()
getAShr = _factory_const2_exact()
getTrunc = _factory_const_type()
getSExt = _factory_const_type()
getZExt = _factory_const_type()
getFPTrunc = _factory_const_type()
getFPExtend = _factory_const_type()
getUIToFP = _factory_const_type()
getSIToFP = _factory_const_type()
getFPToUI = _factory_const_type()
getFPToSI = _factory_const_type()
getPtrToInt = _factory_const_type()
getIntToPtr = _factory_const_type()
getBitCast = _factory_const_type()
getCompare = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant))
getICmp = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant))
getFCmp = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant))
getPointerCast = _factory_const_type()
getIntegerCast = _factory_const(ptr(Type), cast(bool, Bool))
getFPCast = _factory_const_type()
getSelect = _factory(ptr(Constant), ptr(Constant), ptr(Constant))
_getGEP = _factory(ptr(Constant), ref(SmallVector_Value), cast(bool, Bool))
_getGEP.require_only(2)
_getGEP.realname = 'getGetElementPtr'
@CustomPythonStaticMethod
def getGetElementPtr(*args):
from llvmpy import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_values(*valuelist)
return ConstantExpr._getGEP(*args)
getExtractElement = _factory_const2()
getInsertElement = _factory_const2(ptr(Constant))
getShuffleVector = _factory_const2(ptr(Constant))
_getExtractValue = _factory(ptr(Constant), ref(SmallVector_Unsigned))
_getExtractValue.realname = 'getExtractValue'
@CustomPythonStaticMethod
def getExtractValue(*args):
from llvmpy import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_unsigned(*valuelist)
return ConstantExpr._getExtractValue(*args)
_getInsertValue = _factory(ptr(Constant), ptr(Constant),
ref(SmallVector_Unsigned))
_getInsertValue.realname = 'getInsertValue'
@CustomPythonStaticMethod
def getInsertValue(*args):
from llvmpy import extra
args = list(args)
valuelist = args[2]
args[1] = extra.make_small_vector_from_unsigned(*valuelist)
return ConstantExpr._getInsertValue(*args)
getOpcode = Method(cast(Unsigned, int))
getOpcodeName = Method(cast(ConstCharPtr, str))
isCast = Method(cast(Bool, bool))
isCompare = Method(cast(Bool, bool))
hasIndices = Method(cast(Bool, bool))
isGEPWithNoNotionalOverIndexing = Method(cast(Bool, bool))

103
llvmpy/src/DataLayout.py Normal file
View file

@ -0,0 +1,103 @@
from binding import *
from .namespace import llvm
from .Pass import ImmutablePass
DataLayout = llvm.Class(ImmutablePass)
StructLayout = llvm.Class()
from .LLVMContext import LLVMContext
from .ADT.StringRef import StringRef
from .Module import Module
from .Type import Type, IntegerType, StructType
from .ADT.SmallVector import SmallVector_Value
from .GlobalVariable import GlobalVariable
@DataLayout
class DataLayout:
_include_ = 'llvm/DataLayout.h'
_new_string = Constructor(cast(str, StringRef))
_new_module = Constructor(ptr(Module))
@CustomPythonStaticMethod
def new(arg):
if isinstance(arg, Module):
return DataLayout._new_module(arg)
else:
return DataLayout._new_string(arg)
isLittleEndian = Method(cast(Bool, bool))
isBigEndian = Method(cast(Bool, bool))
getStringRepresentation = Method(cast(StringRef, str))
@CustomPythonMethod
def __str__(self):
return self.getStringRepresentation()
isLegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
isIllegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
exceedsNaturalStackAlignment = Method(cast(Bool, bool), cast(int, Unsigned))
fitsInLegalInteger = Method(cast(Bool, bool), cast(int, Unsigned))
getPointerABIAlignment = Method(cast(Unsigned, int),
cast(int, Unsigned)).require_only(0)
getPointerPrefAlignment = Method(cast(Unsigned, int),
cast(int, Unsigned)).require_only(0)
getPointerSize = Method(cast(Unsigned, int),
cast(int, Unsigned)).require_only(0)
getPointerSizeInBits = Method(cast(Unsigned, int),
cast(int, Unsigned)).require_only(0)
getTypeSizeInBits = Method(cast(Uint64, int), ptr(Type))
getTypeStoreSize = Method(cast(Uint64, int), ptr(Type))
getTypeStoreSizeInBits = Method(cast(Uint64, int), ptr(Type))
getTypeAllocSize = Method(cast(Uint64, int), ptr(Type))
getTypeAllocSizeInBits = Method(cast(Uint64, int), ptr(Type))
getABITypeAlignment = Method(cast(Unsigned, int), ptr(Type))
getABIIntegerTypeAlignment = Method(cast(Unsigned, int), cast(int, Unsigned))
getCallFrameTypeAlignment = Method(cast(Unsigned, int), ptr(Type))
getPrefTypeAlignment = Method(cast(Unsigned, int), ptr(Type))
getPreferredTypeAlignmentShift = Method(cast(Unsigned, int), ptr(Type))
_getIntPtrType = Method(ptr(IntegerType),
ref(LLVMContext), cast(int, Unsigned))
_getIntPtrType.require_only(1)
_getIntPtrType.realname = 'getIntPtrType'
_getIntPtrType2 = Method(ptr(Type), ptr(Type))
_getIntPtrType2.realname = 'getIntPtrType'
@CustomPythonMethod
def getIntPtrType(self, *args):
if isinstance(args[0], LLVMContext):
return self._getIntPtrType(*args)
else:
return self._getIntPtrType(*args)
_getIndexedOffset = Method(cast(Uint64, int), ptr(Type),
ref(SmallVector_Value))
_getIndexedOffset.realname = 'getIndexedOffset'
@CustomPythonMethod
def getIndexedOffset(self, *args):
from llvmpy import extra
args = list(args)
args[1] = extra.make_small_vector_from_values(args[1])
return self.getIndexedOffset(*args)
getStructLayout = Method(const(ptr(StructLayout)), ptr(StructType))
getPreferredAlignment = Method(cast(Unsigned, int), ptr(GlobalVariable))
getPreferredAlignmentLog = Method(cast(Unsigned, int), ptr(GlobalVariable))
@StructLayout
class StructLayout:
getSizeInBytes = Method(cast(Uint64, int))
getSizeInBits = Method(cast(Uint64, int))
getAlignment = Method(cast(Unsigned, int))
getElementContainingOffset = Method(cast(Unsigned, int), cast(int, Uint64))
getElementOffset = Method(cast(Uint64, int), cast(int, Unsigned))
getElementOffsetInBits = Method(cast(Uint64, int), cast(int, Unsigned))

View file

@ -0,0 +1,33 @@
from binding import *
from .namespace import llvm
from .LLVMContext import LLVMContext
from .Type import Type
from .ADT.SmallVector import SmallVector_Type
FunctionType = llvm.Class(Type)
@FunctionType
class FunctionType:
_include_ = 'llvm/DerivedTypes.h'
_downcast_ = Type
_get = StaticMethod(ptr(FunctionType), ptr(Type), cast(bool, Bool))
_get |= StaticMethod(ptr(FunctionType), ptr(Type), ref(SmallVector_Type),
cast(bool, Bool))
_get.realname = 'get'
@CustomPythonStaticMethod
def get(*args):
from llvmpy import extra
if len(args) == 3:
typelist = args[1]
sv = extra.make_small_vector_from_types(*typelist)
return FunctionType._get(args[0], sv, args[2])
else:
return FunctionType._get(*args)
isVarArg = Method(cast(Bool, bool))
getReturnType = Method(ptr(Type))
getParamType = Method(ptr(Type), cast(int, Unsigned))
getNumParams = Method(cast(Unsigned, int))

View file

@ -0,0 +1,62 @@
from binding import *
from .namespace import llvm
from .Module import Module
from .JITMemoryManager import JITMemoryManager
from .Support.CodeGen import CodeGenOpt, Reloc, CodeModel
from .ADT.StringRef import StringRef
from .ExecutionEngine.ExecutionEngine import ExecutionEngine
from .Target.TargetMachine import TargetMachine
from .ADT.Triple import Triple
EngineBuilder = llvm.Class()
EngineKind = llvm.Namespace('EngineKind')
Kind = EngineKind.Enum('Kind', 'JIT', 'Interpreter')
@EngineBuilder
class EngineBuilder:
new = Constructor(ownedptr(Module))
delete = Destructor()
def _setter(*args):
return Method(ref(EngineBuilder), *args)
setEngineKind = _setter(Kind)
setJITMemoryManager = _setter(ptr(JITMemoryManager))
setErrorStr = CustomMethod('EngineBuilder_setErrorStr',
PyObjectPtr, PyObjectPtr)
setOptLevel = _setter(CodeGenOpt.Level)
#setTargetOptions =
setRelocationModel = _setter(Reloc.Model)
setCodeModel = _setter(CodeModel.Model)
setAllocateGVsWithCode = _setter(cast(bool, Bool))
setMArch = _setter(cast(str, StringRef))
setMCPU = _setter(cast(str, StringRef))
setUseMCJIT = _setter(cast(bool, Bool))
_setMAttrs = CustomMethod('EngineBuilder_setMAttrs',
PyObjectPtr, PyObjectPtr)
@CustomPythonMethod
def setMAttrs(self, attrs):
attrlist = list(str(a) for a in attrs)
return self._setMAttrs(attrlist)
create = Method(ptr(ExecutionEngine),
ownedptr(TargetMachine)).require_only(0)
_selectTarget0 = Method(ptr(TargetMachine))
_selectTarget0.realname = 'selectTarget'
_selectTarget1 = CustomMethod('EngineBuilder_selectTarget',
PyObjectPtr,
const(ref(Triple)), cast(str, StringRef),
cast(str, StringRef), PyObjectPtr)
@CustomPythonMethod
def selectTarget(self, *args):
if not args:
return self._selectTarget0()
else:
return self._selectTarget1(*args)

View file

@ -0,0 +1,103 @@
from binding import *
from ..namespace import llvm
from ..Module import Module
from ..JITMemoryManager import JITMemoryManager
from ..Support.CodeGen import CodeGenOpt, Reloc, CodeModel
from ..DataLayout import DataLayout
from ..Value import Function, GlobalValue, BasicBlock, Constant
from ..GlobalVariable import GlobalVariable
from ..CodeGen.MachineCodeInfo import MachineCodeInfo
from ..GenericValue import GenericValue
from ..Type import Type
ExecutionEngine = llvm.Class()
@ExecutionEngine
class ExecutionEngine:
_include_ = ('llvm/ExecutionEngine/ExecutionEngine.h',
'llvm/ExecutionEngine/JIT.h') # force linking of jit
delete = Destructor()
create = CustomStaticMethod('ExecutionEngine_create',
ptr(ExecutionEngine),
ownedptr(Module), cast(bool, Bool),
PyObjectPtr, CodeGenOpt.Level,
cast(bool, Bool)).require_only(1)
createJIT = CustomStaticMethod('ExecutionEngine_createJIT',
ptr(ExecutionEngine),
ownedptr(Module), PyObjectPtr,
ptr(JITMemoryManager),
CodeGenOpt.Level,
cast(bool, Bool),
Reloc.Model,
CodeModel.Model).require_only(1)
addModule = Method(Void, ownedptr(Module))
getDataLayout = Method(const(ownedptr(DataLayout)))
_removeModule = Method(cast(Bool, bool), ptr(Module))
_removeModule.realname = 'removeModule'
@CustomPythonMethod
def removeModule(self, module):
if self._removeModule(module):
capsule.obtain_ownership(module._capsule)
return True
return False
FindFunctionNamed = Method(ptr(Function), cast(str, ConstCharPtr))
getPointerToNamedFunction = Method(cast(VoidPtr, int),
cast(str, StdString),
cast(bool, Bool)).require_only(1)
runStaticConstructorsDestructors = Method(Void,
cast(Bool, bool), # is dtor
)
runStaticConstructorsDestructors |= Method(Void, ptr(Module),
cast(Bool, bool))
addGlobalMapping = Method(Void, ptr(GlobalValue), cast(int, VoidPtr))
clearAllGlobalMappings = Method()
clearGlobalMappingsFromModule = Method(Void, ptr(Module))
updateGlobalMapping = Method(cast(VoidPtr, int),
ptr(GlobalValue), cast(int, VoidPtr))
getPointerToGlobalIfAvailable = Method(cast(VoidPtr, int), ptr(GlobalValue))
getPointerToGlobal = Method(cast(VoidPtr, int), ptr(GlobalValue))
getPointerToFunction = Method(cast(VoidPtr, int), ptr(Function))
getPointerToBasicBlock = Method(cast(VoidPtr, int), ptr(BasicBlock))
getPointerToFunctionOrStub = Method(cast(VoidPtr, int), ptr(Function))
runJITOnFunction = Method(Void, ptr(Function), ptr(MachineCodeInfo))
runJITOnFunction.require_only(1)
getGlobalValueAtAddress = Method(const(ptr(GlobalValue)), cast(int, VoidPtr))
StoreValueToMemory = Method(Void, ref(GenericValue), ptr(GenericValue),
ptr(Type))
InitializeMemory = Method(Void, ptr(Constant), cast(int, VoidPtr))
recompileAndRelinkFunction = Method(cast(int, VoidPtr), ptr(Function))
freeMachineCodeForFunction = Method(Void, ptr(Function))
getOrEmitGlobalVariable = Method(cast(int, VoidPtr), ptr(GlobalVariable))
DisableLazyCompilation = Method(Void, cast(bool, Bool))
isCompilingLazily = Method(cast(Bool, bool))
isLazyCompilationDisabled = Method(cast(Bool, bool))
DisableGVCompilation = Method(Void, cast(bool, Bool))
isSymbolSearchingDisabled = Method(cast(Bool, bool))
RegisterTable = Method(Void, ptr(Function), cast(int, VoidPtr))
DeregisterTable = Method(Void, ptr(Function))
DeregisterAllTables = Method()
_runFunction = CustomMethod('ExecutionEngine_RunFunction',
PyObjectPtr, ptr(Function), PyObjectPtr)
@CustomPythonMethod
def runFunction(self, fn, args):
from llvmpy import capsule
unwrapped = list(map(capsule.unwrap, args))
return self._runFunction(fn, tuple(unwrapped))

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

55
llvmpy/src/Function.py Normal file
View file

@ -0,0 +1,55 @@
from binding import *
from .namespace import llvm
from .Value import GlobalValue, Constant, Function, Argument, Value
from .BasicBlock import BasicBlock
from .Attributes import Attributes
from .Type import Type
from .DerivedTypes import FunctionType
from .LLVMContext import LLVMContext
from .CallingConv import CallingConv
@Function
class Function:
_include_ = 'llvm/Function.h'
_downcast_ = GlobalValue, Constant, Value
getReturnType = Method(ptr(Type))
getFunctionType = Method(ptr(FunctionType))
getContext = Method(ref(LLVMContext))
isVarArg = Method(cast(Bool, bool))
getIntrinsicID = Method(cast(Unsigned, int))
isIntrinsic = Method(cast(Bool, bool))
getCallingConv = Method(CallingConv.ID)
setCallingConv = Method(Void, CallingConv.ID)
hasGC = Method(cast(bool, Bool))
getGC = Method(cast(ConstCharPtr, str))
setGC = Method(Void, cast(str, ConstCharPtr))
getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr)
getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr)
getEntryBlock = Method(ref(BasicBlock))
copyAttributesFrom = Method(Void, ptr(GlobalValue))
setDoesNotThrow = Method()
doesNotThrow = Method(cast(Bool, bool))
setDoesNotReturn = Method()
doesNotReturn = Method(cast(Bool, bool))
setOnlyReadsMemory = Method()
onlyReadsMemory = Method(cast(Bool, bool))
setDoesNotAccessMemory = Method()
doesNotAccessMemory = Method(cast(Bool, bool))
deleteBody = Method()
viewCFG = Method()
viewCFGOnly = Method()
addFnAttr = Method(Void, Attributes.AttrVal)
removeFnAttr = Method(Void, ref(Attributes))
eraseFromParent = Method()
eraseFromParent.disowning = True

View file

@ -0,0 +1,34 @@
from binding import *
from .namespace import llvm
from .Type import Type
GenericValue = llvm.Class()
@GenericValue
class GenericValue:
delete = Destructor()
def _factory(name, *argtys):
return CustomStaticMethod('GenericValue_' + name,
ptr(GenericValue), *argtys)
CreateFloat = _factory('CreateFloat', cast(float, Float))
CreateDouble = _factory('CreateDouble', cast(float, Float))
CreateInt = _factory('CreateInt', ptr(Type),
cast(int, UnsignedLongLong), cast(bool, Bool))
CreatePointer = _factory('CreatePointer', cast(int, VoidPtr))
def _accessor(name, *argtys):
return CustomMethod('GenericValue_' + name, *argtys)
valueIntWidth = _accessor('ValueIntWidth', cast(Unsigned, int))
toSignedInt = _accessor('ToSignedInt', cast(LongLong, int))
toUnsignedInt = _accessor('ToUnsignedInt', cast(UnsignedLongLong, int))
toFloat = _accessor('ToFloat', cast(Double, float), ptr(Type))
toPointer = _accessor('ToPointer', cast(VoidPtr, int))

49
llvmpy/src/GlobalValue.py Normal file
View file

@ -0,0 +1,49 @@
from binding import *
from .namespace import llvm
from .Value import GlobalValue
from .Module import Module
from .ADT.StringRef import StringRef
@GlobalValue
class GlobalValue:
_include_ = 'llvm/GlobalValue.h'
LinkageTypes = Enum('''
ExternalLinkage, AvailableExternallyLinkage, LinkOnceAnyLinkage,
LinkOnceODRLinkage, LinkOnceODRAutoHideLinkage, WeakAnyLinkage,
WeakODRLinkage, AppendingLinkage, InternalLinkage, PrivateLinkage,
LinkerPrivateLinkage, LinkerPrivateWeakLinkage, DLLImportLinkage,
DLLExportLinkage, ExternalWeakLinkage, CommonLinkage
''')
VisibilityTypes = Enum('''DefaultVisibility,
HiddenVisibility,
ProtectedVisibility''')
setLinkage = Method(Void, LinkageTypes)
getLinkage = Method(LinkageTypes)
setVisibility = Method(Void, VisibilityTypes)
getVisibility = Method(VisibilityTypes)
setLinkage = Method(Void, LinkageTypes)
getLinkage = Method(LinkageTypes)
getAlignment = Method(cast(Unsigned, int))
setAlignment = Method(Void, cast(int, Unsigned))
hasSection = Method(cast(Bool, bool))
getSection = Method(cast(ConstStdString, str))
setSection = Method(Void, cast(str, StringRef))
isDiscardableIfUnused = Method(cast(Bool, bool))
mayBeOverridden = Method(cast(Bool, bool))
isWeakForLinker = Method(cast(Bool, bool))
copyAttributesFrom = Method(Void, ptr(GlobalValue))
destroyConstant = Method()
isDeclaration = Method(cast(Bool, bool))
removeFromParent = Method()
eraseFromParent = Method()
eraseFromParent.disowning = True
getParent = Method(ptr(Module))

View file

@ -0,0 +1,49 @@
from binding import *
from .namespace import llvm
from .GlobalValue import GlobalValue
GlobalVariable = llvm.Class(GlobalValue)
from .Module import Module
from .Type import Type
from .ADT.StringRef import StringRef
from .Value import Constant
@GlobalVariable
class GlobalVariable:
ThreadLocalMode = Enum('''NotThreadLocal, GeneralDynamicTLSModel,
LocalDynamicTLSModel, InitialExecTLSModel,
LocalExecTLSModel
''')
new = Constructor(ref(Module),
ptr(Type),
cast(bool, Bool), # is constant
GlobalValue.LinkageTypes,
ptr(Constant), # initializer -- can be None
cast(str, StringRef), # name
ptr(GlobalVariable), # insert before
ThreadLocalMode,
cast(int, Unsigned), # address-space
# cast(bool, Bool), # externally initialized
).require_only(5)
setThreadLocal = Method(Void, cast(bool, Bool))
setThreadLocalMode = Method(Void, ThreadLocalMode)
isThreadLocal = Method(cast(Bool, bool))
isConstant = Method(cast(Bool, bool))
setConstant = Method(Void, cast(bool, Bool))
setInitializer = Method(Void, ptr(Constant))
getInitializer = Method(ptr(Constant))
hasInitializer = Method(cast(Bool, bool))
hasUniqueInitializer = Method(cast(Bool, bool))
hasDefinitiveInitializer = Method(cast(Bool, bool))
# isExternallyInitialized = Method(cast(Bool, bool))
# setExternallyinitialized = Method(Void, cast(bool, Bool))

326
llvmpy/src/IRBuilder.py Normal file
View file

@ -0,0 +1,326 @@
from binding import *
from .namespace import llvm
from .LLVMContext import LLVMContext
from .BasicBlock import BasicBlock
from .Instruction import Instruction
from .Instruction import ReturnInst, CallInst, BranchInst, SwitchInst
from .Instruction import IndirectBrInst, InvokeInst, ResumeInst, PHINode
from .Instruction import UnreachableInst, AllocaInst, LoadInst, StoreInst
from .Instruction import FenceInst, AtomicCmpXchgInst, AtomicRMWInst, CmpInst
from .Instruction import LandingPadInst, VAArgInst
from .Instruction import AtomicOrdering, SynchronizationScope
from .ADT.SmallVector import SmallVector_Value, SmallVector_Unsigned
from .ADT.StringRef import StringRef
from .Value import Value, MDNode
from .Type import Type, IntegerType
IRBuilder = llvm.Class()
@IRBuilder
class IRBuilder:
_include_ = 'llvm/IRBuilder.h'
_realname_ = 'IRBuilder<>'
new = Constructor(ref(LLVMContext))
delete = Destructor()
GetInsertBlock = Method(ptr(BasicBlock))
_SetInsertPoint_end_of_bb = Method(Void, ptr(BasicBlock))
_SetInsertPoint_end_of_bb.realname = 'SetInsertPoint'
_SetInsertPoint_before_instr = Method(Void, ptr(Instruction))
_SetInsertPoint_before_instr.realname = 'SetInsertPoint'
@CustomPythonMethod
def SetInsertPoint(self, pt):
if isinstance(pt, Instruction):
return self._SetInsertPoint_before_instr(pt)
elif isinstance(pt, BasicBlock):
return self._SetInsertPoint_end_of_bb(pt)
else:
raise ValueError("Expected either an Instruction or a BasicBlock")
isNamePreserving = Method(cast(Bool, bool))
CreateRetVoid = Method(ptr(ReturnInst))
CreateRet = Method(ptr(ReturnInst), ptr(Value))
CreateAggregateRet = CustomMethod('IRBuilder_CreateAggregateRet',
PyObjectPtr, # ptr(ReturnInst),
PyObjectPtr, # list of Value
cast(int, Unsigned))
CreateBr = Method(ptr(BranchInst), ptr(BasicBlock))
CreateCondBr = Method(ptr(BranchInst), ptr(Value), ptr(BasicBlock),
ptr(BasicBlock), ptr(MDNode)).require_only(3)
CreateSwitch = Method(ptr(SwitchInst), ptr(Value), ptr(BasicBlock),
cast(int, Unsigned), ptr(MDNode)).require_only(2)
CreateIndirectBr = Method(ptr(IndirectBrInst), ptr(Value),
cast(int, Unsigned)).require_only(1)
_CreateInvoke = Method(ptr(InvokeInst), ptr(Value), ptr(BasicBlock),
ptr(BasicBlock), ref(SmallVector_Value),
cast(str, StringRef)).require_only(4)
_CreateInvoke.realname = 'CreateInvoke'
@CustomPythonMethod
def CreateInvoke(self, *args):
from llvmpy import extra
args = list(args)
valuelist = args[3]
args[3] = extra.make_small_vector_from_values(*valuelist)
return self._CreateInvoke(*args)
CreateResume = Method(ptr(ResumeInst), ptr(Value))
CreateUnreachable = Method(ptr(UnreachableInst))
def _binop_has_nsw_nuw():
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
cast(bool, Bool), cast(bool, Bool)]
op = Method(*sig).require_only(2)
return op
CreateAdd = _binop_has_nsw_nuw()
CreateSub = _binop_has_nsw_nuw()
CreateMul = _binop_has_nsw_nuw()
CreateShl = _binop_has_nsw_nuw()
def _binop_is_exact():
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
cast(bool, Bool)]
op = Method(*sig).require_only(2)
return op
CreateUDiv = _binop_is_exact()
CreateSDiv = _binop_is_exact()
CreateLShr = _binop_is_exact()
CreateAShr = _binop_is_exact()
def _binop_basic():
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef)]
op = Method(*sig).require_only(2)
return op
CreateURem = _binop_basic()
CreateSRem = _binop_basic()
CreateAnd = _binop_basic()
CreateOr = _binop_basic()
CreateXor = _binop_basic()
def _float_binop():
sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef),
ptr(MDNode)]
op = Method(*sig).require_only(2)
return op
CreateFAdd = _float_binop()
CreateFSub = _float_binop()
CreateFMul = _float_binop()
CreateFDiv = _float_binop()
CreateFRem = _float_binop()
def _unop_has_nsw_nuw():
sig = [ptr(Value), ptr(Value), cast(str, StringRef),
cast(bool, Bool), cast(bool, Bool)]
op = Method(*sig).require_only(1)
return op
CreateNeg = _unop_has_nsw_nuw()
def _float_unop():
sig = [ptr(Value), ptr(Value), cast(str, StringRef), ptr(MDNode)]
op = Method(*sig).require_only(1)
return op
CreateFNeg = _float_unop()
CreateNot = Method(ptr(Value),
ptr(Value), cast(str, StringRef)).require_only(1)
CreateAlloca = Method(ptr(AllocaInst),
ptr(Type), # ty
ptr(Value), # arysize = 0
cast(str, StringRef), # name = ''
).require_only(1)
CreateLoad = Method(ptr(LoadInst),
ptr(Value), cast(str, StringRef)).require_only(1)
CreateStore = Method(ptr(StoreInst), ptr(Value), ptr(Value),
cast(bool, Bool)).require_only(2)
CreateAlignedLoad = Method(ptr(LoadInst), ptr(Value), cast(int, Unsigned),
cast(bool, Bool), cast(str, StringRef))
CreateAlignedLoad.require_only(2)
CreateAlignedStore = Method(ptr(StoreInst), ptr(Value), ptr(Value),
cast(int, Unsigned), cast(bool, Bool))
CreateAlignedStore.require_only(3)
CreateFence = Method(ptr(FenceInst),
AtomicOrdering, SynchronizationScope).require_only(1)
CreateAtomicCmpXchg = Method(ptr(AtomicCmpXchgInst), ptr(Value), ptr(Value),
ptr(Value), AtomicOrdering, SynchronizationScope)
CreateAtomicCmpXchg.require_only(4)
CreateAtomicRMW = Method(ptr(AtomicRMWInst), AtomicRMWInst.BinOp,
ptr(Value), ptr(Value), AtomicOrdering,
SynchronizationScope)
CreateAtomicRMW.require_only(4)
_CreateGEP = Method(ptr(Value), ptr(Value), ref(SmallVector_Value),
cast(str, StringRef))
_CreateGEP.require_only(2)
_CreateGEP.realname = 'CreateGEP'
@CustomPythonMethod
def CreateGEP(self, *args):
from llvmpy import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_values(*valuelist)
return self._CreateGEP(*args)
_CreateInBoundsGEP = Method(ptr(Value), ptr(Value), ref(SmallVector_Value),
cast(str, StringRef))
_CreateInBoundsGEP.require_only(2)
_CreateInBoundsGEP.realname = 'CreateInBoundsGEP'
@CustomPythonMethod
def CreateInBoundsGEP(self, *args):
from llvmpy import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_values(*valuelist)
return self._CreateInBoundsGEP(*args)
CreateStructGEP = Method(ptr(Value), ptr(Value), cast(int, Unsigned),
cast(str, StringRef)).require_only(2)
CreateGlobalStringPtr = Method(ptr(Value), cast(str, StringRef),
cast(str, StringRef)).require_only(1)
def _value_type():
sig = [ptr(Value), ptr(Value), ptr(Type), cast(str, StringRef)]
op = Method(*sig).require_only(2)
return op
CreateTrunc = _value_type()
CreateZExt = _value_type()
CreateSExt = _value_type()
CreateZExtOrTrunc = Method(ptr(Value), ptr(Value), ptr(IntegerType),
cast(str, StringRef)).require_only(2)
CreateSExtOrTrunc = Method(ptr(Value), ptr(Value), ptr(IntegerType),
cast(str, StringRef)).require_only(2)
CreateFPToUI = _value_type()
CreateFPToSI = _value_type()
CreateUIToFP = _value_type()
CreateSIToFP = _value_type()
CreateFPTrunc = _value_type()
CreateFPExt = _value_type()
CreatePtrToInt = _value_type()
CreateIntToPtr = _value_type()
CreateBitCast = _value_type()
CreateZExtOrBitCast = _value_type()
CreateSExtOrBitCast = _value_type()
# Skip CreateCast
CreateTruncOrBitCast = _value_type()
CreateIntCast = Method(ptr(Value), ptr(Value), ptr(Type), cast(bool, Bool),
cast(str, StringRef)).require_only(3)
CreateFPCast = _value_type()
_CreateCall = Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value),
cast(str, StringRef)).require_only(2)
_CreateCall.realname = 'CreateCall'
@CustomPythonMethod
def CreateCall(self, *args):
from llvmpy import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_values(*valuelist)
return self._CreateCall(*args)
# Skip specialized CreateICmp* and CreateFCmp*
CreateICmp = Method(ptr(Value), CmpInst.Predicate, ptr(Value), ptr(Value),
cast(str, StringRef)).require_only(3)
CreateFCmp = Method(ptr(Value), CmpInst.Predicate, ptr(Value), ptr(Value),
cast(str, StringRef)).require_only(3)
CreatePHI = Method(ptr(PHINode), ptr(Type), cast(int, Unsigned),
cast(str, StringRef)).require_only(2)
CreateSelect = Method(ptr(Value), ptr(Value), ptr(Value), ptr(Value),
cast(str, StringRef)).require_only(3)
CreateVAArg = Method(ptr(VAArgInst), ptr(Value), ptr(Type),
cast(str, StringRef)).require_only(2)
CreateExtractElement = _binop_basic()
CreateInsertElement = Method(ptr(Value), ptr(Value), ptr(Value), ptr(Value),
cast(str, StringRef)).require_only(3)
CreateShuffleVector = Method(ptr(Value), ptr(Value), ptr(Value),
ptr(Value), cast(str, StringRef))
CreateShuffleVector.require_only(3)
_CreateExtractValue = Method(ptr(Value), ptr(Value),
ref(SmallVector_Unsigned),
cast(str, StringRef))
_CreateExtractValue.require_only(2)
_CreateExtractValue.realname = 'CreateExtractValue'
@CustomPythonMethod
def CreateExtractValue(self, *args):
from llvmpy import extra
args = list(args)
valuelist = args[1]
args[1] = extra.make_small_vector_from_unsigned(*valuelist)
return self._CreateExtractValue(*args)
_CreateInsertValue = Method(ptr(Value),
ptr(Value), # Agg
ptr(Value), # Val
ref(SmallVector_Unsigned), # ArrayRef<unsigned>
cast(str, StringRef), # name
).require_only(3)
_CreateInsertValue.realname = 'CreateInsertValue'
@CustomPythonMethod
def CreateInsertValue(self, *args):
from llvmpy import extra
args = list(args)
valuelist = args[2]
args[2] = extra.make_small_vector_from_unsigned(*valuelist)
return self._CreateInsertValue(*args)
CreateLandingPad = Method(ptr(LandingPadInst), ptr(Type), ptr(Value),
cast(int, Unsigned), cast(str, StringRef))
CreateLandingPad.require_only(3)
CreateIsNull = Method(ptr(Value), ptr(Value), cast(str, StringRef))
CreateIsNull.require_only(1)
CreateIsNotNull = Method(ptr(Value), ptr(Value), cast(str, StringRef))
CreateIsNotNull.require_only(1)
CreatePtrDiff = _binop_basic()
# New in llvm 3.3
#CreateVectorSplat = Method(ptr(Value), cast(int, Unsigned), ptr(Value),
# cast(str, StringRef))
Insert = Method(ptr(Instruction),
ptr(Instruction),
cast(str, StringRef)).require_only(1)

24
llvmpy/src/InlineAsm.py Normal file
View file

@ -0,0 +1,24 @@
from binding import *
from .namespace import llvm
from .Value import Value
from .DerivedTypes import FunctionType
from .ADT.StringRef import StringRef
llvm.includes.add('llvm/InlineAsm.h')
InlineAsm = llvm.Class(Value)
@InlineAsm
class InlineAsm:
AsmDialect = Enum('AD_ATT', 'AD_Intel')
ConstraintPrefix = Enum('''isInput, isOutput, isClobber''')
get = StaticMethod(ptr(InlineAsm),
ptr(FunctionType),
cast(str, StringRef), # AsmString
cast(str, StringRef), # Constrains
cast(bool, Bool), # hasSideEffects
cast(bool, Bool), # isAlignStack
AsmDialect, # default = AD_ATT
).require_only(4)

390
llvmpy/src/Instruction.py Normal file
View file

@ -0,0 +1,390 @@
from binding import *
from .namespace import llvm
from .Value import Value, MDNode, User, BasicBlock, Function, ConstantInt
Instruction = llvm.Class(User)
AtomicCmpXchgInst = llvm.Class(Instruction)
AtomicRMWInst = llvm.Class(Instruction)
BinaryOperator = llvm.Class(Instruction)
CallInst = llvm.Class(Instruction)
CmpInst = llvm.Class(Instruction)
ExtractElementInst = llvm.Class(Instruction)
FenceInst = llvm.Class(Instruction)
GetElementPtrInst = llvm.Class(Instruction)
InsertElementInst = llvm.Class(Instruction)
InsertValueInst = llvm.Class(Instruction)
LandingPadInst = llvm.Class(Instruction)
PHINode = llvm.Class(Instruction)
SelectInst = llvm.Class(Instruction)
ShuffleVectorInst = llvm.Class(Instruction)
StoreInst = llvm.Class(Instruction)
TerminatorInst = llvm.Class(Instruction)
UnaryInstruction = llvm.Class(Instruction)
IntrinsicInst = llvm.Class(CallInst)
FCmpInst = llvm.Class(CmpInst)
ICmpInst = llvm.Class(CmpInst)
BranchInst = llvm.Class(TerminatorInst)
IndirectBrInst = llvm.Class(TerminatorInst)
InvokeInst = llvm.Class(TerminatorInst)
ResumeInst = llvm.Class(TerminatorInst)
ReturnInst = llvm.Class(TerminatorInst)
SwitchInst = llvm.Class(TerminatorInst)
UnreachableInst = llvm.Class(TerminatorInst)
AllocaInst = llvm.Class(UnaryInstruction)
CastInst = llvm.Class(UnaryInstruction)
ExtractValueInst = llvm.Class(UnaryInstruction)
LoadInst = llvm.Class(UnaryInstruction)
VAArgInst = llvm.Class(UnaryInstruction)
DbgInfoIntrinsic = llvm.Class(IntrinsicInst)
MemIntrinsic = llvm.Class(IntrinsicInst)
VACopyInst = llvm.Class(IntrinsicInst)
VAEndInst = llvm.Class(IntrinsicInst)
VAStartInst = llvm.Class(IntrinsicInst)
BitCastInst = llvm.Class(CastInst)
FPExtInst = llvm.Class(CastInst)
FPToSIInst = llvm.Class(CastInst)
FPToUIInst = llvm.Class(CastInst)
FPTruncInst = llvm.Class(CastInst)
AtomicOrdering = llvm.Enum('AtomicOrdering',
'NotAtomic', 'Unordered', 'Monotonic', 'Acquire',
'Release', 'AcquireRelease',
'SequentiallyConsistent')
SynchronizationScope = llvm.Enum('SynchronizationScope',
'SingleThread', 'CrossThread')
from .ADT.StringRef import StringRef
from .CallingConv import CallingConv
from .Attributes import Attributes
from .Type import Type
@Instruction
class Instruction:
_downcast_ = Value, User
removeFromParent = Method()
eraseFromParent = Method()
eraseFromParent.disowning = True
getParent = Method(ptr(BasicBlock))
getOpcode = Method(cast(Unsigned, int))
getOpcodeName = Method(cast(ConstCharPtr, str))
insertBefore = Method(Void, ptr(Instruction))
insertAfter = Method(Void, ptr(Instruction))
moveBefore = Method(Void, ptr(Instruction))
isTerminator = Method(cast(Bool, bool))
isBinaryOp = Method(cast(Bool, bool))
isShift = Method(cast(Bool, bool))
isCast = Method(cast(Bool, bool))
isLogicalShift = Method(cast(Bool, bool))
isArithmeticShift = Method(cast(Bool, bool))
hasMetadata = Method(cast(Bool, bool))
hasMetadataOtherThanDebugLoc = Method(cast(Bool, bool))
isAssociative = Method(cast(Bool, bool))
isCommutative = Method(cast(Bool, bool))
isIdempotent = Method(cast(Bool, bool))
isNilpotent = Method(cast(Bool, bool))
mayWriteToMemory = Method(cast(Bool, bool))
mayReadFromMemory = Method(cast(Bool, bool))
mayReadOrWriteMemory = Method(cast(Bool, bool))
mayThrow = Method(cast(Bool, bool))
mayHaveSideEffects = Method(cast(Bool, bool))
hasMetadata = Method(cast(Bool, bool))
getMetadata = Method(ptr(MDNode), cast(str, StringRef))
setMetadata = Method(Void, cast(str, StringRef), ptr(MDNode))
clone = Method(ptr(Instruction))
# LLVM 3.3
# hasUnsafeAlgebra = Method(cast(Bool, bool))
# hasNoNans = Method(cast(Bool, bool))
# hasNoInfs = Method(cast(Bool, bool))
# hasNoSignedZeros = Method(cast(Bool, bool))
# hasAllowReciprocal = Method(cast(Bool, bool))
@AtomicCmpXchgInst
class AtomicCmpXchgInst:
_downcast_ = Value, Instruction
@AtomicRMWInst
class AtomicRMWInst:
_downcast_ = Value, Instruction
BinOp = Enum('Xchg', 'Add', 'Sub', 'And', 'Nand', 'Or', 'Xor', 'Max', 'Min',
'UMax', 'UMin', 'FIRST_BINOP', 'LAST_BINOP', 'BAD_BINOP')
@BinaryOperator
class BinaryOperator:
_downcast_ = Value, Instruction
@CallInst
class CallInst:
_downcast_ = Value, User, Instruction
getCallingConv = Method(CallingConv.ID)
setCallingConv = Method(Void, CallingConv.ID)
getParamAlignment = Method(cast(Unsigned, int), cast(int, Unsigned))
addAttribute = Method(Void, cast(int, Unsigned), ref(Attributes))
removeAttribute = Method(Void, cast(int, Unsigned), ref(Attributes))
getCalledFunction = Method(ptr(Function))
getCalledValue = Method(ptr(Value))
setCalledFunction = Method(Void, ptr(Function))
isInlineAsm = Method(cast(Bool, bool))
CreateMalloc = StaticMethod(ptr(Instruction),
ptr(BasicBlock), # insertAtEnd
ptr(Type), # intptrty
ptr(Type), # allocty
ptr(Value), # allocsz
ptr(Value), # array size = 0
ptr(Function), # malloc fn = 0
cast(str, StringRef), # name
).require_only(4)
CreateFree = StaticMethod(ptr(Instruction), ptr(Value), ptr(BasicBlock))
@CmpInst
class CmpInst:
_downcast_ = Value, Instruction
Predicate = Enum('FCMP_FALSE', 'FCMP_OEQ', 'FCMP_OGT', 'FCMP_OGE',
'FCMP_OLT', 'FCMP_OLE', 'FCMP_ONE', 'FCMP_ORD', 'FCMP_UNO',
'FCMP_UEQ', 'FCMP_UGT', 'FCMP_UGE', 'FCMP_ULT', 'FCMP_ULE',
'FCMP_UNE', 'FCMP_TRUE', 'FIRST_FCMP_PREDICATE',
'LAST_FCMP_PREDICATE',
'BAD_FCMP_PREDICATE',
'ICMP_EQ', 'ICMP_NE', 'ICMP_UGT', 'ICMP_UGE', 'ICMP_ULT',
'ICMP_ULE', 'ICMP_SGT', 'ICMP_SGE', 'ICMP_SLT', 'ICMP_SLE',
'FIRST_ICMP_PREDICATE',
'LAST_ICMP_PREDICATE',
'BAD_ICMP_PREDICATE',)
getPredicate = Method(Predicate)
@ExtractElementInst
class ExtractElementInst:
_downcast_ = Value, Instruction
@FenceInst
class FenceInst:
_downcast_ = Value, Instruction
@GetElementPtrInst
class GetElementPtrInst:
_downcast_ = Value, Instruction
@InsertElementInst
class InsertElementInst:
_downcast_ = Value, Instruction
@InsertValueInst
class InsertValueInst:
_downcast_ = Value, Instruction
@LandingPadInst
class LandingPadInst:
_downcast_ = Value, Instruction
@PHINode
class PHINode:
_downcast_ = Value, Instruction
getNumIncomingValues = Method(cast(Unsigned, int))
getIncomingValue = Method(ptr(Value), cast(int, Unsigned))
setIncomingValue = Method(Void, cast(int, Unsigned), ptr(Value))
getIncomingBlock = Method(ptr(BasicBlock), cast(int, Unsigned))
setIncomingBlock = Method(Void, cast(int, Unsigned), ptr(BasicBlock))
addIncoming = Method(Void, ptr(Value), ptr(BasicBlock))
hasConstantValue = Method(ptr(Value))
getBasicBlockIndex = Method(cast(Int, int), ptr(BasicBlock))
@SelectInst
class SelectInst:
_downcast_ = Value, Instruction
@ShuffleVectorInst
class ShuffleVectorInst:
_downcast_ = Value, Instruction
@StoreInst
class StoreInst:
_downcast_ = Value, Instruction
isVolatile = Method(cast(Bool, bool))
isSimple = Method(cast(Bool, bool))
isUnordered = Method(cast(Bool, bool))
isAtomic = Method(cast(Bool, bool))
setVolatile = Method(Void, cast(Bool, bool))
getAlignment = Method(cast(Unsigned, int))
setAlignment = Method(Void, cast(int, Unsigned))
setAtomic = Method(Void,
AtomicOrdering,
SynchronizationScope).require_only(1)
classof = StaticMethod(cast(Bool, bool), ptr(Value))
@TerminatorInst
class TerminatorInst:
_downcast_ = Value, Instruction
getNumSuccessors = Method(cast(Unsigned, int))
getSuccessor = Method(ptr(BasicBlock), cast(int, Unsigned))
setSuccessor = Method(Void, cast(int, Unsigned), ptr(BasicBlock))
@UnaryInstruction
class UnaryInstruction:
_downcast_ = Value, Instruction
#call
@IntrinsicInst
class IntrinsicInst:
_include_ = 'llvm/IntrinsicInst.h'
_downcast_ = Value, Instruction
#compare
@FCmpInst
class FCmpInst:
_downcast_ = Value, Instruction
@ICmpInst
class ICmpInst:
_downcast_ = Value, Instruction
# terminator
@BranchInst
class BranchInst:
_downcast_ = Value, Instruction
@IndirectBrInst
class IndirectBrInst:
_downcast_ = Value, Instruction
@InvokeInst
class InvokeInst:
_downcast_ = Value, User, Instruction
getCallingConv = Method(CallingConv.ID)
setCallingConv = Method(Void, CallingConv.ID)
getParamAlignment = Method(cast(Unsigned, int), cast(int, Unsigned))
addAttribute = Method(Void, cast(int, Unsigned), ref(Attributes))
removeAttribute = Method(Void, cast(int, Unsigned), ref(Attributes))
getCalledFunction = Method(ptr(Function))
getCalledValue = Method(ptr(Value))
setCalledFunction = Method(Void, ptr(Function))
@ResumeInst
class ResumeInst:
_downcast_ = Value, Instruction
@ReturnInst
class ReturnInst:
_downcast_ = Value, Instruction
@SwitchInst
class SwitchInst:
_downcast_ = Value, Instruction
getCondition = Method(ptr(Value))
setCondition = Method(Void, ptr(Value))
getDefaultDest = Method(ptr(BasicBlock))
setDefaultDest = Method(Void, ptr(BasicBlock))
getNumCases = Method(cast(int, Unsigned))
addCase = Method(Void, ptr(ConstantInt), ptr(BasicBlock))
@UnreachableInst
class UnreachableInst:
_downcast_ = Value, Instruction
# unary
@AllocaInst
class AllocaInst:
_downcast_ = Value, Instruction
@CastInst
class CastInst:
_downcast_ = Value, Instruction
@ExtractValueInst
class ExtractValueInst:
_downcast_ = Value, Instruction
@LoadInst
class LoadInst:
_downcast_ = Value, Instruction
isVolatile = Method(cast(Bool, bool))
isSimple = Method(cast(Bool, bool))
isUnordered = Method(cast(Bool, bool))
isAtomic = Method(cast(Bool, bool))
setVolatile = Method(Void, cast(Bool, bool))
getAlignment = Method(cast(Unsigned, int))
setAlignment = Method(Void, cast(int, Unsigned))
setAtomic = Method(Void,
AtomicOrdering,
SynchronizationScope).require_only(1)
classof = StaticMethod(cast(Bool, bool), ptr(Value))
@VAArgInst
class VAArgInst:
_downcast_ = Value, Instruction
# intrinsic
@DbgInfoIntrinsic
class DbgInfoIntrinsic:
_downcast_ = Value, Instruction
@MemIntrinsic
class MemIntrinsic:
_downcast_ = Value, Instruction
@VACopyInst
class VACopyInst:
_downcast_ = Value, Instruction
@VAEndInst
class VAEndInst:
_downcast_ = Value, Instruction
@VAStartInst
class VAStartInst:
_downcast_ = Value, Instruction
@BitCastInst
class BitCastInst:
_downcast_ = Value, Instruction
@FPExtInst
class FPExtInst:
_downcast_ = Value, Instruction
@FPToSIInst
class FPToSIInst:
_downcast_ = Value, Instruction
@FPToUIInst
class FPToUIInst:
_downcast_ = Value, Instruction
@FPTruncInst
class FPTruncInst:
_downcast_ = Value, Instruction

16
llvmpy/src/Intrinsics.py Normal file
View file

@ -0,0 +1,16 @@
from binding import *
from .namespace import llvm
from .Module import Module
from .Function import Function
Intrinsic = llvm.Namespace('Intrinsic')
getDeclaration = Intrinsic.CustomFunction('getDeclaration',
'Intrinsic_getDeclaration',
PyObjectPtr, # Function*
ptr(Module),
cast(int, Unsigned), # intrinsic id
PyObjectPtr, # list of Type
).require_only(2)

View file

@ -0,0 +1,7 @@
from binding import *
from .namespace import llvm
@llvm.Class()
class JITMemoryManager:
pass

View file

@ -0,0 +1,8 @@
from binding import *
from .namespace import llvm
@llvm.Class()
class LLVMContext:
_include_ = "llvm/LLVMContext.h"
llvm.Function('getGlobalContext', ref(LLVMContext))

58
llvmpy/src/Linker.py Normal file
View file

@ -0,0 +1,58 @@
from binding import *
from .namespace import llvm
from .ADT.StringRef import StringRef
from .Module import Module
from .LLVMContext import LLVMContext
llvm.includes.add('llvm/Linker.h')
Linker = llvm.Class()
@Linker
class Linker:
ControlFlags = Enum('Verbose, QuietWarnings, QuietErrors')
LinkerMode = Enum('DestroySource, PreserveSource')
_new_w_empty = Constructor(cast(str, StringRef),
cast(str, StringRef),
ref(LLVMContext),
cast(int, Unsigned)).require_only(3)
_new_w_existing = Constructor(cast(str, StringRef),
ptr(Module),
cast(int, Unsigned)).require_only(2)
@CustomPythonStaticMethod
def new(progname, module_or_name, *args):
if isinstance(module_or_name, Module):
return _new_w_existing(progname, module_or_name, *args)
else:
return _new_w_empty(progname, module_or_name, *args)
delete = Destructor()
getModule = Method(ptr(Module))
releaseModule = Method(ptr(Module))
getLastError = Method(cast(ConstStdString, str))
LinkInModule = CustomMethod('Linker_LinkInModule',
PyObjectPtr, # boolean
ptr(Module),
PyObjectPtr, # errmsg
)
_LinkModules = CustomStaticMethod('Linker_LinkModules',
PyObjectPtr, # boolean
ptr(Module),
ptr(Module),
LinkerMode,
PyObjectPtr, # errsg
)
@CustomPythonStaticMethod
def LinkModules(module, other, mode, errmsg):
failed = Linker._LinkModules(module, other, mode, errmsg)
if not failed and mode != Linker.LinkerMode.PreserveSource:
capsule.release_ownership(other._ptr)
return failed

54
llvmpy/src/Metadata.py Normal file
View file

@ -0,0 +1,54 @@
from binding import *
from .namespace import llvm
from .Value import Value, MDNode, MDString
from .LLVMContext import LLVMContext
from .ADT.StringRef import StringRef
from .Module import Module
from .Function import Function
from .Support.raw_ostream import raw_ostream
from .Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter
@MDNode
class MDNode:
_downcast_ = Value
replaceOperandWith = Method(Void, cast(int, Unsigned), ptr(Value))
getOperand = Method(ptr(Value), cast(int, Unsigned))
getNumOperands = Method(cast(Unsigned, int))
isFunctionLocal = Method(cast(Bool, bool))
getFunction = Method(const(ptr(Function)))
get = CustomStaticMethod('MDNode_get',
PyObjectPtr, # MDNode*
ref(LLVMContext),
PyObjectPtr, # ArrayRef<Value*>
)
@MDString
class MDString:
_downcast_ = Value
get = StaticMethod(ptr(MDString), ref(LLVMContext), cast(str, StringRef))
getString = Method(cast(StringRef, str))
getLength = Method(cast(int, Unsigned))
@llvm.Class()
class NamedMDNode:
eraseFromParent = Method()
eraseFromParent.disowning = True
dropAllReferences = Method()
getParent = Method(ptr(Module))
getOperand = Method(ptr(MDNode), cast(int, Unsigned))
getNumOperands = Method(cast(Unsigned, int))
getName = Method(cast(StringRef, str))
addOperand = Method(Void, ptr(MDNode))
print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter))
print_.realname = "print"
dump = Method()
@CustomPythonMethod
def __str__(self):
from llvmpy import extra
os = extra.make_raw_ostream_for_printing()
self.print_(os, None)
return os.str()

87
llvmpy/src/Module.py Normal file
View file

@ -0,0 +1,87 @@
from binding import *
from .namespace import llvm
Module = llvm.Class()
from .LLVMContext import LLVMContext
from .ADT.StringRef import StringRef
from .Constant import Constant
from .GlobalVariable import GlobalVariable
from .Function import Function
from .DerivedTypes import FunctionType
from .Support.raw_ostream import raw_ostream
from .Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter
from .Type import Type, StructType
from .Metadata import NamedMDNode
@Module
class Module:
_include_ = "llvm/Module.h"
# Enumerators
Endianness = Enum('AnyEndianness', 'LittleEndian', 'BigEndian')
PointerSize = Enum('AnyPointerSize', 'Pointer32', 'Pointer64')
# Constructors & Destructors
new = Constructor(cast(str, StringRef), ref(LLVMContext))
delete = Destructor()
# Module Level Accessor
getModuleIdentifier = Method(cast(ConstStdString, str))
getDataLayout = Method(cast(ConstStdString, str))
getTargetTriple = Method(cast(ConstStdString, str))
getEndianness = Method(Endianness)
getPointerSize = Method(PointerSize)
getContext = Method(ref(LLVMContext))
getModuleInlineAsm = Method(cast(ConstStdString, str))
# Module Level Mutators
setModuleIdentifier = Method(Void, cast(str, StringRef))
setDataLayout = Method(Void, cast(str, StringRef))
setTargetTriple = Method(Void, cast(str, StringRef))
setModuleInlineAsm = Method(Void, cast(str, StringRef))
appendModuleInlineAsm = Method(Void, cast(str, StringRef))
# Function Accessors
getOrInsertFunction = Method(ptr(Constant), cast(str, StringRef),
ptr(FunctionType))
getFunction = Method(ptr(Function), cast(str, StringRef))
# Function Iteration
list_functions = CustomMethod('Module_list_functions', PyObjectPtr)
# GlobalVariabe Accessors
getGlobalVariable = Method(ptr(GlobalVariable),
cast(str, StringRef),
cast(bool, Bool),
).require_only(1)
getNamedGlobal = Method(ptr(GlobalVariable), cast(str, StringRef))
getOrInsertGlobal = Method(ptr(Constant), cast(str, StringRef), ptr(Type))
# GlobalVariable Iteration
list_globals = CustomMethod('Module_list_globals', PyObjectPtr)
# Named MetaData Accessors
getNamedMetadata = Method(ptr(NamedMDNode), cast(str, StringRef))
getOrInsertNamedMetadata = Method(ptr(NamedMDNode), cast(str, StringRef))
eraseNamedMetadata = Method(Void, ptr(NamedMDNode))
# Named MetaData Iteration
list_named_metadata = CustomMethod('Module_list_named_metadata',
PyObjectPtr)
# Utilities
dump = Method(Void)
print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter))
print_.realname = 'print'
@CustomPythonMethod
def __str__(self):
from llvmpy import extra
os = extra.make_raw_ostream_for_printing()
self.print_(os, None)
return os.str()
dropAllReferences = Method()
getTypeByName = Method(ptr(StructType), cast(str, StringRef))

35
llvmpy/src/Pass.py Normal file
View file

@ -0,0 +1,35 @@
from binding import *
from .namespace import llvm
Pass = llvm.Class()
ModulePass = llvm.Class(Pass)
FunctionPass = llvm.Class(Pass)
ImmutablePass = llvm.Class(ModulePass)
from .ADT.StringRef import StringRef
from .Module import Module
from .Value import Function
@Pass
class Pass:
_include_ = 'llvm/Pass.h'
delete = Destructor()
getPassName = Method(cast(StringRef, str))
dump = Method()
@ModulePass
class ModulePass:
runOnModule = Method(cast(Bool, bool), ref(Module))
@FunctionPass
class FunctionPass:
doInitialization = Method(cast(Bool, bool), ref(Module))
doFinalization = Method(cast(Bool, bool), ref(Module))
@ImmutablePass
class ImmutablePass:
pass

36
llvmpy/src/PassManager.py Normal file
View file

@ -0,0 +1,36 @@
from binding import *
from .namespace import llvm
PassManagerBase = llvm.Class()
PassManager = llvm.Class(PassManagerBase)
FunctionPassManager = llvm.Class(PassManagerBase)
from .Pass import Pass
from .Module import Module
from .Value import Function
@PassManagerBase
class PassManagerBase:
_include_ = 'llvm/PassManager.h'
delete = Destructor()
add = Method(Void, ownedptr(Pass))
@PassManager
class PassManager:
new = Constructor()
run = Method(cast(Bool, bool), ref(Module))
@FunctionPassManager
class FunctionPassManager:
new = Constructor(ptr(Module))
run = Method(cast(Bool, bool), ref(Function))
doInitialization = Method(cast(Bool, bool))
doFinalization = Method(cast(Bool, bool))

View file

@ -0,0 +1,21 @@
from binding import *
from .namespace import llvm
from src.ADT.StringRef import StringRef
PassRegistry = llvm.Class()
from src.PassSupport import PassInfo
@PassRegistry
class PassRegistry:
_include_ = 'llvm/PassRegistry.h'
delete = Destructor()
getPassRegistry = StaticMethod(ownedptr(PassRegistry))
getPassInfo = Method(const(ptr(PassInfo)), cast(str, StringRef))
# This is a custom method that wraps enumerateWith
# Returns list of tuples of (pass-arg, pass-name)
enumerate = CustomMethod('PassRegistry_enumerate', PyObjectPtr)

24
llvmpy/src/PassSupport.py Normal file
View file

@ -0,0 +1,24 @@
from binding import *
from .namespace import llvm
PassInfo = llvm.Class()
from src.Pass import Pass
from src.PassRegistry import PassRegistry
@PassInfo
class PassInfo:
_include_ = 'llvm/PassSupport.h'
createPass = Method(ptr(Pass))
llvm.Function('initializeCore', Void, ref(PassRegistry))
llvm.Function('initializeScalarOpts', Void, ref(PassRegistry))
llvm.Function('initializeVectorization', Void, ref(PassRegistry))
llvm.Function('initializeIPO', Void, ref(PassRegistry))
llvm.Function('initializeAnalysis', Void, ref(PassRegistry))
llvm.Function('initializeIPA', Void, ref(PassRegistry))
llvm.Function('initializeTransformUtils', Void, ref(PassRegistry))
llvm.Function('initializeInstCombine', Void, ref(PassRegistry))
llvm.Function('initializeInstrumentation', Void, ref(PassRegistry))
llvm.Function('initializeTarget', Void, ref(PassRegistry))

View file

@ -0,0 +1,20 @@
from binding import *
from ..namespace import llvm
Reloc = llvm.Namespace('Reloc')
Reloc.Enum('Model',
'Default', 'Static', 'PIC_', 'DynamicNoPIC')
CodeModel = llvm.Namespace('CodeModel')
CodeModel.Enum('Model',
'Default', 'JITDefault', 'Small', 'Kernel', 'Medium', 'Large')
TLSModel = llvm.Namespace('TLSModel')
TLSModel.Enum('Model',
'GeneralDynamic', 'LocalDynamic', 'InitialExec', 'LocalExec')
CodeGenOpt = llvm.Namespace('CodeGenOpt')
CodeGenOpt.Enum('Level',
'None', 'Less', 'Default', 'Aggressive')

View file

@ -0,0 +1,12 @@
from binding import *
from src.namespace import cl
cl.includes.add('llvm/Support/CommandLine.h')
ParseEnvironmentOptions = cl.Function('ParseEnvironmentOptions',
Void,
cast(str, ConstCharPtr), # progName
cast(str, ConstCharPtr), # envvar
cast(str, ConstCharPtr), # overiew = 0
).require_only(2)

View file

@ -0,0 +1,28 @@
from binding import *
from ..namespace import sys
from ..ADT.StringRef import StringRef
DynamicLibrary = sys.Class()
@DynamicLibrary
class DynamicLibrary:
_include_ = 'llvm/Support/DynamicLibrary.h'
isValid = Method(cast(Bool, bool))
getAddressOfSymbol = Method(cast(VoidPtr, int), cast(str, ConstCharPtr))
LoadPermanentLibrary = CustomStaticMethod(
'DynamicLibrary_LoadLibraryPermanently',
PyObjectPtr, # bool --- failed?
cast(str, ConstCharPtr), # filename
PyObjectPtr, # std::string * errmsg = 0
).require_only(1)
SearchForAddressOfSymbol = StaticMethod(cast(VoidPtr, int), # address
cast(str, ConstCharPtr), # symName
)
AddSymbol = StaticMethod(Void,
cast(str, StringRef), # symbolName
cast(int, VoidPtr), # address
)

View file

@ -0,0 +1,15 @@
from binding import *
from ..namespace import llvm
from .raw_ostream import raw_ostream
@llvm.Class(raw_ostream)
class formatted_raw_ostream:
_include_ = 'llvm/Support/FormattedStream.h'
_new = Constructor(ref(raw_ostream), cast(bool, Bool))
@CustomPythonStaticMethod
def new(stream, destroy=False):
inst = formatted_raw_ostream._new(stream, destroy)
inst.__underlying_stream = stream # to prevent it being freed first
return inst

View file

@ -0,0 +1,25 @@
from binding import *
from src.namespace import sys
isLittleEndianHost = sys.Function('isLittleEndianHost',
cast(Bool, bool))
isBigEndianHost = sys.Function('isBigEndianHost',
cast(Bool, bool))
getDefaultTargetTriple = sys.Function('getDefaultTargetTriple',
cast(ConstStdString, str))
# llvm 3.3
#getProcessTriple = sys.Function('getProcessTriple',
# cast(ConstStdString, str))
getHostCPUName = sys.Function('getHostCPUName',
cast(ConstStdString, str))
getHostCPUFeatures = sys.CustomFunction('getHostCPUFeatures',
'llvm_sys_getHostCPUFeatures',
PyObjectPtr, # bool: success?
PyObjectPtr, # dict: store feature map
)

View file

@ -0,0 +1,10 @@
from binding import *
from ..namespace import llvm
llvm.includes.add('llvm/Support/SourceMgr.h')
@llvm.Class()
class SMDiagnostic:
new = Constructor()
delete = Destructor()

View file

@ -0,0 +1,68 @@
from binding import *
from src.namespace import llvm
llvm.includes.add('llvm/Support/TargetRegistry.h')
Target = llvm.Class()
TargetRegistry = llvm.Class()
from src.ADT.Triple import Triple
from src.ADT.StringRef import StringRef
from src.Target.TargetMachine import TargetMachine
from src.Target.TargetOptions import TargetOptions
from src.Support.CodeGen import Reloc, CodeModel, CodeGenOpt
@Target
class Target:
getNext = Method(const(ptr(Target)))
getName = Method(cast(StringRef, str))
getShortDescription = Method(cast(StringRef, str))
def _has():
return Method(cast(Bool, bool))
hasJIT = _has()
hasTargetMachine = _has()
hasMCAsmBackend = _has()
hasMCAsmParser = _has()
hasAsmPrinter = _has()
hasMCDisassembler = _has()
hasMCInstPrinter = _has()
hasMCCodeEmitter = _has()
hasMCObjectStreamer = _has()
hasAsmStreamer = _has()
createTargetMachine = Method(ptr(TargetMachine),
cast(str, StringRef), # triple
cast(str, StringRef), # cpu
cast(str, StringRef), # features
ref(TargetOptions),
Reloc.Model, # = Reloc::Default
CodeModel.Model, # = CodeModel.Default
CodeGenOpt.Level, # = CodeGenOpt.Default
).require_only(4)
@TargetRegistry
class TargetRegistry:
printRegisteredTargetsForVersion = StaticMethod()
lookupTarget = CustomStaticMethod('TargetRegistry_lookupTarget',
PyObjectPtr, # const Target*
cast(str, ConstCharPtr), # triple
PyObjectPtr, # std::string &Error
)
lookupTarget |= CustomStaticMethod('TargetRegistry_lookupTarget',
PyObjectPtr, # const Target*
cast(str, ConstCharPtr), # arch
ref(Triple), # triple
PyObjectPtr, # std::string &Error
)
getClosestTargetForJIT = CustomStaticMethod(
'TargetRegistry_getClosestTargetForJIT',
PyObjectPtr, # const Target*
PyObjectPtr, # std::string &Error
)

View file

@ -0,0 +1,28 @@
from binding import *
from ..namespace import llvm, default
llvm.includes.add('llvm/Support/TargetSelect.h')
InitializeNativeTarget = llvm.Function('InitializeNativeTarget')
InitializeNativeTargetAsmPrinter = llvm.Function(
'InitializeNativeTargetAsmPrinter', cast(Bool, bool))
InitializeNativeTargetAsmParser = llvm.Function(
'InitializeNativeTargetAsmParser', cast(Bool, bool))
InitializeNativeTargetDisassembler = llvm.Function(
'InitializeNativeTargetDisassembler', cast(Bool, bool))
#InitializeAllTargets = llvm.Function('InitializeAllTargets')
#InitializeAllTargetInfos = llvm.Function('InitializeAllTargetInfos')
#InitializeAllTargetMCs = llvm.Function('InitializeAllTargetMCs')
#InitializeAllAsmPrinters = llvm.Function('InitializeAllAsmPrinters')
#LLVMInitializePTXTarget = default.Function('LLVMInitializePTXTarget')
#LLVMInitializePTXTargetInfo = default.Function('LLVMInitializePTXTargetInfo')
#LLVMInitializePTXTargetMC = default.Function('LLVMInitializePTXTargetMC')
#LLVMInitializePTXAsmPrinter = default.Function('LLVMInitializePTXAsmPrinter')
LLVMInitializeNVPTXTarget = default.Function('LLVMInitializeNVPTXTarget')
LLVMInitializeNVPTXTargetInfo = default.Function('LLVMInitializeNVPTXTargetInfo')
LLVMInitializeNVPTXTargetMC = default.Function('LLVMInitializeNVPTXTargetMC')
LLVMInitializeNVPTXAsmPrinter = default.Function('LLVMInitializeNVPTXAsmPrinter')

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

View file

@ -0,0 +1,18 @@
from binding import *
from ..namespace import llvm
from ..LLVMContext import LLVMContext
from ..ADT.StringRef import StringRef
@llvm.Class()
class raw_ostream:
_include_ = "llvm/Support/raw_ostream.h"
delete = Destructor()
flush = Method()
@llvm.Class(raw_ostream)
class raw_svector_ostream:
_include_ = "llvm/Support/raw_os_ostream.h"
_base_ = raw_ostream
str = Method(cast(str, StringRef))

View file

@ -0,0 +1,78 @@
from binding import *
from ..namespace import llvm
from src.Pass import ImmutablePass
TargetLibraryInfo = llvm.Class(ImmutablePass)
LibFunc = llvm.Namespace('LibFunc')
LibFunc.Enum('Func', '''
ZdaPv, ZdlPv, Znaj, ZnajRKSt9nothrow_t,
Znam, ZnamRKSt9nothrow_t, Znwj, ZnwjRKSt9nothrow_t,
Znwm, ZnwmRKSt9nothrow_t, cxa_atexit, cxa_guard_abort,
cxa_guard_acquire, cxa_guard_release, memcpy_chk,
acos, acosf, acosh, acoshf,
acoshl, acosl, asin, asinf,
asinh, asinhf, asinhl, asinl,
atan, atan2, atan2f, atan2l,
atanf, atanh, atanhf, atanhl,
atanl, calloc, cbrt, cbrtf,
cbrtl, ceil, ceilf, ceill,
copysign, copysignf, copysignl, cos,
cosf, cosh, coshf, coshl,
cosl, exp, exp10, exp10f,
exp10l, exp2, exp2f, exp2l,
expf, expl, expm1, expm1f,
expm1l, fabs, fabsf, fabsl,
fiprintf,
floor, floorf, floorl, fmod,
fmodf, fmodl, fputc,
fputs, free, fwrite, iprintf,
log, log10, log10f, log10l,
log1p, log1pf, log1pl, log2,
log2f, log2l, logb, logbf,
logbl, logf, logl, malloc,
memchr, memcmp, memcpy, memmove,
memset, memset_pattern16, nearbyint, nearbyintf,
nearbyintl, posix_memalign, pow, powf,
powl, putchar, puts,
realloc, reallocf, rint, rintf,
rintl, round, roundf, roundl,
sin, sinf, sinh, sinhf,
sinhl, sinl, siprintf,
sqrt, sqrtf, sqrtl, stpcpy,
strcat, strchr, strcmp, strcpy,
strcspn, strdup, strlen, strncat,
strncmp, strncpy, strndup, strnlen,
strpbrk, strrchr, strspn, strstr,
strtod, strtof, strtol, strtold,
strtoll, strtoul, strtoull, tan,
tanf, tanh, tanhf, tanhl,
tanl, trunc, truncf,
truncl, valloc, NumLibFuncs''')
# not in llvm-3.2 abs, ffs, ffsl, ffsll, fprintf, isascii,
# isdigit, labs, llabs, printf, sprintf, toascii
from src.ADT.Triple import Triple
from src.ADT.StringRef import StringRef
@TargetLibraryInfo
class TargetLibraryInfo:
_include_ = 'llvm/Target/TargetLibraryInfo.h'
new = Constructor()
new |= Constructor(ref(Triple))
delete = Destructor()
has = Method(cast(bool, Bool), LibFunc.Func)
hasOptimizedCodeGen = Method(cast(bool, Bool), LibFunc.Func)
getName = Method(cast(str, StringRef), LibFunc.Func)
setUnavailable = Method(Void, LibFunc.Func)
setAvailable = Method(Void, LibFunc.Func)
setAvailableWithName = Method(Void, LibFunc.Func, cast(str, StringRef))
disableAllFunctions = Method()

View file

@ -0,0 +1,54 @@
from binding import *
from src.namespace import llvm
TargetMachine = llvm.Class()
from src.Support.TargetRegistry import Target
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
from src.TargetTransformInfo import (ScalarTargetTransformInfo,
VectorTargetTransformInfo)
from src.PassManager import PassManagerBase
from src.Support.FormattedStream import formatted_raw_ostream
@TargetMachine
class TargetMachine:
_include_ = 'llvm/Target/TargetMachine.h'
CodeGenFileType = Enum('''
CGFT_AssemblyFile
CGFT_ObjectFile
CGFT_Null''')
delete = Destructor()
getTarget = Method(const(ref(Target)))
getTargetTriple = Method(cast(StringRef, str))
getTargetCPU = Method(cast(StringRef, str))
getTargetFeatureString = Method(cast(StringRef, str))
getRelocationModel = Method(Reloc.Model)
getCodeModel = Method(CodeModel.Model)
getTLSModel = Method(TLSModel.Model, ptr(GlobalValue))
getOptLevel = Method(CodeGenOpt.Level)
hasMCUseDwarfDirectory = Method(cast(Bool, bool))
setMCUseDwarfDirectory = Method(Void, cast(bool, Bool))
getDataLayout = Method(const(ownedptr(DataLayout)))
getScalarTargetTransformInfo = Method(const(
ownedptr(ScalarTargetTransformInfo)))
getVectorTargetTransformInfo = Method(const(
ownedptr(VectorTargetTransformInfo)))
addPassesToEmitFile = Method(cast(bool, Bool),
ref(PassManagerBase),
ref(formatted_raw_ostream),
CodeGenFileType,
cast(bool, Bool)
).require_only(3)

View file

@ -0,0 +1,12 @@
from binding import *
from src.namespace import llvm
llvm.includes.add('llvm/Target/TargetOptions.h')
TargetOptions = llvm.Class()
@TargetOptions
class TargetOptions:
new = Constructor()
delete = Destructor()

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

View file

@ -0,0 +1,24 @@
from binding import *
from src.namespace import llvm
from src.Pass import ImmutablePass
llvm.includes.add('llvm/TargetTransformInfo.h')
TargetTransformInfo = llvm.Class(ImmutablePass)
ScalarTargetTransformInfo = llvm.Class()
VectorTargetTransformInfo = llvm.Class()
@ScalarTargetTransformInfo
class ScalarTargetTransformInfo:
delete = Destructor()
@VectorTargetTransformInfo
class VectorTargetTransformInfo:
delete = Destructor()
@TargetTransformInfo
class TargetTransformInfo:
new = Constructor(ptr(ScalarTargetTransformInfo),
ptr(VectorTargetTransformInfo))

View file

@ -0,0 +1,9 @@
from binding import *
from ..namespace import llvm
from ..Pass import Pass
llvm.includes.add('llvm/Transforms/IPO.h')
createFunctionInliningPass = llvm.Function('createFunctionInliningPass',
ptr(Pass),
cast(int, Unsigned)).require_only(0)

View file

@ -0,0 +1,46 @@
from binding import *
from ..namespace import llvm
PassManagerBuilder = llvm.Class()
from src.PassManager import PassManagerBase, FunctionPassManager
from src.Target.TargetLibraryInfo import TargetLibraryInfo
from src.Pass import Pass
@PassManagerBuilder
class PassManagerBuilder:
_include_ = 'llvm/Transforms/IPO/PassManagerBuilder.h'
new = Constructor()
delete = Destructor()
populateFunctionPassManager = Method(Void, ref(FunctionPassManager))
populateModulePassManager = Method(Void, ref(PassManagerBase))
populateLTOPassManager = Method(Void,
ref(PassManagerBase),
cast(bool, Bool),
cast(bool, Bool),
cast(bool, Bool)).require_only(3)
def _attr_int():
return Attr(getter=cast(Unsigned, int),
setter=cast(int, Unsigned))
OptLevel = _attr_int()
SizeLevel = _attr_int()
def _attr_bool():
return Attr(getter=cast(Bool, bool),
setter=cast(bool, Bool))
DisableSimplifyLibCalls = _attr_bool()
DisableUnitAtATime = _attr_bool()
DisableUnrollLoops = _attr_bool()
Vectorize = _attr_bool()
LoopVectorize = _attr_bool()
LibraryInfo = Attr(getter=ownedptr(TargetLibraryInfo),
setter=ownedptr(TargetLibraryInfo))
Inliner = Attr(getter=ownedptr(Pass),
setter=ownedptr(Pass))

View file

@ -0,0 +1,25 @@
from binding import *
from src.namespace import llvm
llvm.includes.add('llvm/Transforms/Utils/Cloning.h')
InlineFunctionInfo = llvm.Class()
from src.Module import Module
from src.Instruction import CallInst
@InlineFunctionInfo
class InlineFunctionInfo:
new = Constructor()
delete = Destructor()
CloneModule = llvm.Function('CloneModule', ptr(Module), ptr(Module))
InlineFunction = llvm.Function('InlineFunction',
cast(Bool, bool), # bool --- failed
ptr(CallInst),
ref(InlineFunctionInfo),
cast(bool, Bool), # insert lifetime = true
).require_only(2)

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

View file

@ -0,0 +1,2 @@
from src import _init
_init(__name__, __file__)

219
llvmpy/src/Type.py Normal file
View file

@ -0,0 +1,219 @@
from binding import *
from .namespace import llvm
from .LLVMContext import LLVMContext
from .Support.raw_ostream import raw_ostream
from .ADT.StringRef import StringRef
Type = llvm.Class()
IntegerType = llvm.Class(Type)
CompositeType = llvm.Class(Type)
StructType = llvm.Class(CompositeType)
SequentialType = llvm.Class(CompositeType)
ArrayType = llvm.Class(SequentialType)
PointerType = llvm.Class(SequentialType)
VectorType = llvm.Class(SequentialType)
@Type
class Type:
_include_ = 'llvm/Type.h'
TypeID = Enum('''
VoidTyID, HalfTyID, FloatTyID, DoubleTyID,
X86_FP80TyID, FP128TyID, PPC_FP128TyID, LabelTyID,
MetadataTyID, X86_MMXTyID, IntegerTyID, FunctionTyID,
StructTyID, ArrayTyID, PointerTyID, VectorTyID,
NumTypeIDs, LastPrimitiveTyID, FirstDerivedTyID
''')
getContext = Method(ref(LLVMContext))
dump = Method()
print_ = Method(Void, ref(raw_ostream))
print_.realname = 'print'
getTypeID = Method(TypeID)
def type_checker():
return Method(cast(Bool, bool))
isVoidTy = type_checker()
isHalfTy = type_checker()
isFloatTy = type_checker()
isDoubleTy = type_checker()
isX86_FP80Ty = type_checker()
isFP128Ty = type_checker()
isPPC_FP128Ty = type_checker()
isFloatingPointTy = type_checker()
isX86_MMXTy = type_checker()
isFPOrFPVectorTy = type_checker()
isLabelTy = type_checker()
isMetadataTy = type_checker()
isIntOrIntVectorTy = type_checker()
isFunctionTy = type_checker()
isStructTy = type_checker()
isArrayTy = type_checker()
isPointerTy = type_checker()
isPtrOrPtrVectorTy = type_checker()
isVectorTy = type_checker()
isEmptyTy = type_checker()
isPrimitiveType = type_checker()
isDerivedType = type_checker()
isFirstClassType = type_checker()
isSingleValueType = type_checker()
isAggregateType = type_checker()
isSized = type_checker()
isIntegerTy = Method(cast(Bool, bool))
isIntegerTy |= Method(cast(Bool, bool), cast(int, Unsigned))
getIntegerBitWidth = Method(cast(Unsigned, int))
getFunctionParamType = Method(ptr(Type), cast(int, Unsigned))
getFunctionNumParams = Method(cast(int, Unsigned))
isFunctionVarArg = type_checker()
getStructName = Method(cast(StringRef, str))
getStructNumElements = Method(cast(Unsigned, int))
getStructElementType = Method(ptr(Type), cast(int, Unsigned))
getSequentialElementType = Method(ptr(Type))
# Factories
def type_factory():
return StaticMethod(ptr(Type), ref(LLVMContext))
getVoidTy = type_factory()
getLabelTy = type_factory()
getHalfTy = type_factory()
getFloatTy = type_factory()
getDoubleTy = type_factory()
getMetadataTy = type_factory()
getX86_FP80Ty = type_factory()
getFP128Ty = type_factory()
getPPC_FP128Ty = type_factory()
getX86_MMXTy = type_factory()
getIntNTy = StaticMethod(ptr(IntegerType),
ref(LLVMContext), cast(Unsigned, int))
def integer_factory():
return StaticMethod(ptr(IntegerType), ref(LLVMContext))
getInt1Ty = integer_factory()
getInt8Ty = integer_factory()
getInt16Ty = integer_factory()
getInt32Ty = integer_factory()
getInt64Ty = integer_factory()
def pointer_factory():
return StaticMethod(ptr(PointerType), ref(LLVMContext))
getHalfPtrTy = pointer_factory()
getFloatPtrTy = pointer_factory()
getDoublePtrTy = pointer_factory()
getX86_FP80PtrTy = pointer_factory()
getFP128PtrTy = pointer_factory()
getPPC_FP128PtrTy = pointer_factory()
getX86_MMXPtrTy = pointer_factory()
getInt1PtrTy = pointer_factory()
getInt8PtrTy = pointer_factory()
getInt16PtrTy = pointer_factory()
getInt32PtrTy = pointer_factory()
getInt64PtrTy = pointer_factory()
getIntNPtrTy = StaticMethod(ptr(PointerType),
ref(LLVMContext), cast(int, Unsigned))
@CustomPythonMethod
def __str__(self):
from llvmpy import extra
os = extra.make_raw_ostream_for_printing()
self.print_(os)
return os.str()
getContainedType = Method(ptr(Type), cast(int, Unsigned))
getNumContainedTypes = Method(cast(int, Unsigned))
getArrayNumElements = Method(cast(Uint64, int))
getArrayElementType = Method(ptr(Type))
getVectorNumElements = Method(cast(Unsigned, int))
getVectorElementType = Method(ptr(Type))
getPointerElementType = Method(ptr(Type))
getPointerAddressSpace = Method(cast(Unsigned, int))
getPointerTo = Method(ptr(PointerType), cast(int, Unsigned))
@IntegerType
class IntegerType:
_downcast_ = Type
@CompositeType
class CompositeType:
_downcast_ = Type
@SequentialType
class SequentialType:
_downcast_ = Type
@ArrayType
class ArrayType:
_downcast_ = Type
getNumElements = Method(cast(Uint64, int))
get = StaticMethod(ptr(ArrayType), ptr(Type), cast(int, Uint64))
isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type))
@PointerType
class PointerType:
_downcast_ = Type
getAddressSpace = Method(cast(Unsigned, int))
get = StaticMethod(ptr(PointerType), ptr(Type), cast(int, Unsigned))
getUnqual = StaticMethod(ptr(PointerType), ptr(Type))
isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type))
@VectorType
class VectorType:
_downcast_ = Type
getNumElements = Method(cast(Unsigned, int))
getBitWidth = Method(cast(Unsigned, int))
get = StaticMethod(ptr(VectorType), ptr(Type), cast(int, Unsigned))
getInteger = StaticMethod(ptr(VectorType), ptr(VectorType))
getExtendedElementVectorType = StaticMethod(ptr(VectorType),
ptr(VectorType))
getTruncatedElementVectorType = StaticMethod(ptr(VectorType),
ptr(VectorType))
isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type))
@StructType
class StructType:
_downcast_ = Type
isPacked = Method(cast(Bool, bool))
isLiteral = Method(cast(Bool, bool))
isOpaque = Method(cast(Bool, bool))
hasName = Method(cast(Bool, bool))
getName = Method(cast(StringRef, str))
setName = Method(Void, cast(str, StringRef))
setBody = CustomMethod('StructType_setBody',
PyObjectPtr, # None
PyObjectPtr, # ArrayRef<Type*>
cast(bool, Bool),
).require_only(1)
getNumElements = Method(cast(Unsigned, int))
getElementType = Method(ptr(Type), cast(int, Unsigned))
create = StaticMethod(ptr(StructType),
ref(LLVMContext),
cast(str, StringRef),
).require_only(1)
get = CustomStaticMethod('StructType_get',
PyObjectPtr, # StructType*
ref(LLVMContext),
PyObjectPtr, # ArrayRef <Type*> elements
cast(bool, Bool), # is packed
).require_only(2)
isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type))

11
llvmpy/src/User.py Normal file
View file

@ -0,0 +1,11 @@
from binding import *
from .namespace import llvm
from .Value import Value, User
@User
class User:
_downcast_ = Value
getOperand = Method(ptr(Value), cast(int, Unsigned))
setOperand = Method(Void, cast(int, Unsigned), ptr(Value))
getNumOperands = Method(cast(Unsigned, int))

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