Merge branch 'newbinding_integrate'
Conflicts: llvm/core.py
This commit is contained in:
commit
17096867f7
111 changed files with 7927 additions and 11314 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -2,4 +2,7 @@
|
|||
build
|
||||
_build
|
||||
*.pyc
|
||||
*.so
|
||||
/llvm/_intrinsic_ids.py
|
||||
llvm_
|
||||
newbinding/api/*
|
||||
2117
llvm/2.9_update.diff
2117
llvm/2.9_update.diff
File diff suppressed because it is too large
Load diff
158
llvm/__init__.py
158
llvm/__init__.py
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
2212
llvm/_core.cpp
2212
llvm/_core.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||
}
|
||||
101
llvm/_dwarf.h
101
llvm/_dwarf.h
|
|
@ -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)
|
||||
|
||||
108
llvm/_util.py
108
llvm/_util.py
|
|
@ -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
|
||||
|
||||
|
|
@ -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 */
|
||||
2253
llvm/core.py
2253
llvm/core.py
File diff suppressed because it is too large
Load diff
|
|
@ -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),
|
||||
]
|
||||
303
llvm/ee.py
303
llvm/ee.py
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
1361
llvm/extra.cpp
1361
llvm/extra.cpp
File diff suppressed because it is too large
Load diff
676
llvm/extra.h
676
llvm/extra.h
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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_
|
||||
|
||||
298
llvm/passes.py
298
llvm/passes.py
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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>
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
1277
llvm/wrap.h
1277
llvm/wrap.h
File diff suppressed because it is too large
Load diff
4
llvmpy/.gitignore
vendored
Normal file
4
llvmpy/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
api.cpp
|
||||
api/*.py
|
||||
api/*/*.py
|
||||
|
||||
21
llvmpy/Makefile
Normal file
21
llvmpy/Makefile
Normal 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
5
llvmpy/README
Normal 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
0
llvmpy/__init__.py
Normal file
117
llvmpy/capsule.cpp
Normal file
117
llvmpy/capsule.cpp
Normal 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
213
llvmpy/capsule.py
Normal 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
25
llvmpy/extra.py
Normal 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
840
llvmpy/gen/binding.py
Normal 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
289
llvmpy/gen/codegen.py
Normal 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
107
llvmpy/gen/gen.py
Normal 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()
|
||||
108
llvmpy/include/capsulethunk.h
Normal file
108
llvmpy/include/capsulethunk.h
Normal 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 */
|
||||
37
llvmpy/include/llvm_binding/auto_pyobject.h
Normal file
37
llvmpy/include/llvm_binding/auto_pyobject.h
Normal 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_
|
||||
87
llvmpy/include/llvm_binding/binding.h
Normal file
87
llvmpy/include/llvm_binding/binding.h
Normal 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;
|
||||
}
|
||||
|
||||
66
llvmpy/include/llvm_binding/capsule_context.h
Normal file
66
llvmpy/include/llvm_binding/capsule_context.h
Normal 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_
|
||||
|
||||
261
llvmpy/include/llvm_binding/conversion.h
Normal file
261
llvmpy/include/llvm_binding/conversion.h
Normal 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);
|
||||
}
|
||||
};
|
||||
|
||||
904
llvmpy/include/llvm_binding/extra.h
Normal file
904
llvmpy/include/llvm_binding/extra.h
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
32
llvmpy/include/python3adapt.h
Normal file
32
llvmpy/include/python3adapt.h
Normal 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
64
llvmpy/setup.py
Normal 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")
|
||||
17
llvmpy/src/ADT/SmallVector.py
Normal file
17
llvmpy/src/ADT/SmallVector.py
Normal 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()
|
||||
7
llvmpy/src/ADT/StringRef.py
Normal file
7
llvmpy/src/ADT/StringRef.py
Normal 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
55
llvmpy/src/ADT/Triple.py
Normal 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)
|
||||
|
||||
2
llvmpy/src/ADT/__init__.py
Normal file
2
llvmpy/src/ADT/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
25
llvmpy/src/Analysis/Verifier.py
Normal file
25
llvmpy/src/Analysis/Verifier.py
Normal 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)
|
||||
|
||||
2
llvmpy/src/Analysis/__init__.py
Normal file
2
llvmpy/src/Analysis/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
15
llvmpy/src/Argument.py
Normal file
15
llvmpy/src/Argument.py
Normal 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))
|
||||
|
||||
7
llvmpy/src/Assembly/AssemblyAnnotationWriter.py
Normal file
7
llvmpy/src/Assembly/AssemblyAnnotationWriter.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from binding import *
|
||||
from ..namespace import llvm
|
||||
|
||||
@llvm.Class()
|
||||
class AssemblyAnnotationWriter:
|
||||
_include_ = "llvm/Assembly/AssemblyAnnotationWriter.h"
|
||||
|
||||
14
llvmpy/src/Assembly/Parser.py
Normal file
14
llvmpy/src/Assembly/Parser.py
Normal 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))
|
||||
2
llvmpy/src/Assembly/__init__.py
Normal file
2
llvmpy/src/Assembly/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
39
llvmpy/src/Attributes.py
Normal file
39
llvmpy/src/Attributes.py
Normal 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
26
llvmpy/src/BasicBlock.py
Normal 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()
|
||||
30
llvmpy/src/Bitcode/ReaderWriter.py
Normal file
30
llvmpy/src/Bitcode/ReaderWriter.py
Normal 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)
|
||||
2
llvmpy/src/Bitcode/__init__.py
Normal file
2
llvmpy/src/Bitcode/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
10
llvmpy/src/CallingConv.py
Normal file
10
llvmpy/src/CallingConv.py
Normal 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
|
||||
13
llvmpy/src/CodeGen/MachineCodeInfo.py
Normal file
13
llvmpy/src/CodeGen/MachineCodeInfo.py
Normal 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))
|
||||
|
||||
2
llvmpy/src/CodeGen/__init__.py
Normal file
2
llvmpy/src/CodeGen/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
274
llvmpy/src/Constant.py
Normal file
274
llvmpy/src/Constant.py
Normal 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
103
llvmpy/src/DataLayout.py
Normal 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))
|
||||
33
llvmpy/src/DerivedTypes.py
Normal file
33
llvmpy/src/DerivedTypes.py
Normal 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))
|
||||
|
||||
62
llvmpy/src/EngineBuilder.py
Normal file
62
llvmpy/src/EngineBuilder.py
Normal 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)
|
||||
|
||||
103
llvmpy/src/ExecutionEngine/ExecutionEngine.py
Normal file
103
llvmpy/src/ExecutionEngine/ExecutionEngine.py
Normal 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))
|
||||
|
||||
2
llvmpy/src/ExecutionEngine/__init__.py
Normal file
2
llvmpy/src/ExecutionEngine/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
55
llvmpy/src/Function.py
Normal file
55
llvmpy/src/Function.py
Normal 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
|
||||
|
||||
34
llvmpy/src/GenericValue.py
Normal file
34
llvmpy/src/GenericValue.py
Normal 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
49
llvmpy/src/GlobalValue.py
Normal 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))
|
||||
49
llvmpy/src/GlobalVariable.py
Normal file
49
llvmpy/src/GlobalVariable.py
Normal 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
326
llvmpy/src/IRBuilder.py
Normal 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
24
llvmpy/src/InlineAsm.py
Normal 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
390
llvmpy/src/Instruction.py
Normal 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
16
llvmpy/src/Intrinsics.py
Normal 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)
|
||||
7
llvmpy/src/JITMemoryManager.py
Normal file
7
llvmpy/src/JITMemoryManager.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from binding import *
|
||||
from .namespace import llvm
|
||||
|
||||
@llvm.Class()
|
||||
class JITMemoryManager:
|
||||
pass
|
||||
|
||||
8
llvmpy/src/LLVMContext.py
Normal file
8
llvmpy/src/LLVMContext.py
Normal 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
58
llvmpy/src/Linker.py
Normal 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
54
llvmpy/src/Metadata.py
Normal 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
87
llvmpy/src/Module.py
Normal 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
35
llvmpy/src/Pass.py
Normal 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
36
llvmpy/src/PassManager.py
Normal 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))
|
||||
|
||||
21
llvmpy/src/PassRegistry.py
Normal file
21
llvmpy/src/PassRegistry.py
Normal 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
24
llvmpy/src/PassSupport.py
Normal 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))
|
||||
20
llvmpy/src/Support/CodeGen.py
Normal file
20
llvmpy/src/Support/CodeGen.py
Normal 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')
|
||||
|
||||
12
llvmpy/src/Support/CommandLine.py
Normal file
12
llvmpy/src/Support/CommandLine.py
Normal 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)
|
||||
|
||||
28
llvmpy/src/Support/DynamicLibrary.py
Normal file
28
llvmpy/src/Support/DynamicLibrary.py
Normal 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
|
||||
)
|
||||
15
llvmpy/src/Support/FormattedStream.py
Normal file
15
llvmpy/src/Support/FormattedStream.py
Normal 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
|
||||
|
||||
25
llvmpy/src/Support/Host.py
Normal file
25
llvmpy/src/Support/Host.py
Normal 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
|
||||
)
|
||||
|
||||
10
llvmpy/src/Support/SourceMgr.py
Normal file
10
llvmpy/src/Support/SourceMgr.py
Normal 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()
|
||||
|
||||
68
llvmpy/src/Support/TargetRegistry.py
Normal file
68
llvmpy/src/Support/TargetRegistry.py
Normal 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
|
||||
)
|
||||
28
llvmpy/src/Support/TargetSelect.py
Normal file
28
llvmpy/src/Support/TargetSelect.py
Normal 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')
|
||||
2
llvmpy/src/Support/__init__.py
Normal file
2
llvmpy/src/Support/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
18
llvmpy/src/Support/raw_ostream.py
Normal file
18
llvmpy/src/Support/raw_ostream.py
Normal 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))
|
||||
|
||||
78
llvmpy/src/Target/TargetLibraryInfo.py
Normal file
78
llvmpy/src/Target/TargetLibraryInfo.py
Normal 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()
|
||||
|
||||
54
llvmpy/src/Target/TargetMachine.py
Normal file
54
llvmpy/src/Target/TargetMachine.py
Normal 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)
|
||||
|
||||
|
||||
12
llvmpy/src/Target/TargetOptions.py
Normal file
12
llvmpy/src/Target/TargetOptions.py
Normal 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()
|
||||
|
||||
2
llvmpy/src/Target/__init__.py
Normal file
2
llvmpy/src/Target/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
24
llvmpy/src/TargetTransformInfo.py
Normal file
24
llvmpy/src/TargetTransformInfo.py
Normal 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))
|
||||
|
||||
9
llvmpy/src/Transforms/IPO.py
Normal file
9
llvmpy/src/Transforms/IPO.py
Normal 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)
|
||||
46
llvmpy/src/Transforms/PassManagerBuilder.py
Normal file
46
llvmpy/src/Transforms/PassManagerBuilder.py
Normal 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))
|
||||
25
llvmpy/src/Transforms/Utils/Cloning.py
Normal file
25
llvmpy/src/Transforms/Utils/Cloning.py
Normal 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)
|
||||
2
llvmpy/src/Transforms/Utils/__init__.py
Normal file
2
llvmpy/src/Transforms/Utils/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
2
llvmpy/src/Transforms/__init__.py
Normal file
2
llvmpy/src/Transforms/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from src import _init
|
||||
_init(__name__, __file__)
|
||||
219
llvmpy/src/Type.py
Normal file
219
llvmpy/src/Type.py
Normal 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
11
llvmpy/src/User.py
Normal 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
Loading…
Add table
Add a link
Reference in a new issue