Module.link_in and Instruction.is_volatile APIs added (Seth Warn)
git-svn-id: http://llvm-py.googlecode.com/svn/trunk@62 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
parent
75161701a1
commit
6028e1765b
6 changed files with 89 additions and 2 deletions
31
llvm/_core.c
31
llvm/_core.c
|
|
@ -162,6 +162,33 @@ _wLLVMGetBitcodeFromModule(PyObject *self, PyObject *args)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_wLLVMLinkModules(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *dest_obj, *src_obj, *ret;
|
||||
LLVMModuleRef dest, src;
|
||||
char *errmsg;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO", &dest_obj, &src_obj))
|
||||
return NULL;
|
||||
|
||||
dest = (LLVMModuleRef) PyCObject_AsVoidPtr(dest_obj);
|
||||
src = (LLVMModuleRef) PyCObject_AsVoidPtr(src_obj);
|
||||
|
||||
if (!LLVMLinkModules(dest, src, &errmsg)) {
|
||||
if (errmsg) {
|
||||
ret = PyString_FromString(errmsg);
|
||||
LLVMDisposeMessage(errmsg);
|
||||
} else {
|
||||
ret = PyString_FromString("Link error");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* note: success => None, failure => string with error message */
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*===----------------------------------------------------------------------===*/
|
||||
/* Types */
|
||||
/*===----------------------------------------------------------------------===*/
|
||||
|
|
@ -505,7 +532,7 @@ _wrap_obj2obj(LLVMInstIsCommutative, LLVMValueRef, int)
|
|||
_wrap_obj2obj(LLVMInstIsTrapping, LLVMValueRef, int)
|
||||
_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int)
|
||||
_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef)
|
||||
|
||||
_wrap_obj2obj(LLVMInstIsVolatile, LLVMValueRef, int)
|
||||
|
||||
/*===-- Call Sites (Call or Invoke) --------------------------------------===*/
|
||||
|
||||
|
|
@ -1001,6 +1028,7 @@ static PyMethodDef core_methods[] = {
|
|||
_method( LLVMGetBitcodeFromModule )
|
||||
_method( LLVMModuleGetPointerSize )
|
||||
_method( LLVMModuleGetOrInsertFunction )
|
||||
_method( LLVMLinkModules )
|
||||
|
||||
/* Types */
|
||||
|
||||
|
|
@ -1209,6 +1237,7 @@ static PyMethodDef core_methods[] = {
|
|||
_method( LLVMInstIsTrapping )
|
||||
_method( LLVMInstGetOpcode )
|
||||
_method( LLVMInstGetOpcodeName )
|
||||
_method( LLVMInstIsVolatile )
|
||||
|
||||
/* Call Sites (Call or Invoke) */
|
||||
_method( LLVMSetInstructionCallConv )
|
||||
|
|
|
|||
19
llvm/core.py
19
llvm/core.py
|
|
@ -918,6 +918,20 @@ class Module(llvm.Ownable):
|
|||
llvm::Module::AnyPointerSize."""
|
||||
return _core.LLVMModuleGetPointerSize(self.ptr)
|
||||
|
||||
def link_in(self, other):
|
||||
"""Link the `other' module into this one.
|
||||
|
||||
The `other' module is linked into this one such that types,
|
||||
global variables, function, etc. are matched and resolved.
|
||||
|
||||
The `other' module is no longer valid after this method is
|
||||
invoked, and will behave in undefined ways.
|
||||
"""
|
||||
check_is_module(other)
|
||||
ret = _core.LLVMLinkModules(self.ptr, other.ptr)
|
||||
if isinstance(ret, str):
|
||||
raise llvm.LLVMException, ret
|
||||
|
||||
def add_type_name(self, name, ty):
|
||||
"""Map a string to a type.
|
||||
|
||||
|
|
@ -1842,6 +1856,11 @@ class Instruction(Value):
|
|||
def is_trapping(self):
|
||||
return _core.LLVMInstIsTrapping(self.ptr) != 0
|
||||
|
||||
@property
|
||||
def is_volatile(self):
|
||||
"""True if this is a volatile load or store."""
|
||||
return _core.LLVMInstIsVolatile(self.ptr) != 0
|
||||
|
||||
@property
|
||||
def opcode(self):
|
||||
return _core.LLVMInstGetOpcode(self.ptr)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
// LLVM includes
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
|
|
@ -60,6 +61,7 @@
|
|||
#include "llvm/Transforms/IPO.h"
|
||||
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
#include "llvm/Linker.h"
|
||||
|
||||
// LLVM-C includes
|
||||
#include "llvm-c/Core.h"
|
||||
|
|
@ -212,6 +214,15 @@ inst_checkfn(LLVMInstIsAssociative, isAssociative)
|
|||
inst_checkfn(LLVMInstIsCommutative, isCommutative)
|
||||
inst_checkfn(LLVMInstIsTrapping, isTrapping)
|
||||
|
||||
unsigned LLVMInstIsVolatile(LLVMValueRef v)
|
||||
{
|
||||
using namespace llvm;
|
||||
Instruction *ip = unwrap<Instruction>(v);
|
||||
assert(ip);
|
||||
return ((isa<LoadInst>(*ip) && cast<LoadInst>(*ip).isVolatile()) ||
|
||||
(isa<StoreInst>(*ip) && cast<StoreInst>(*ip).isVolatile()) );
|
||||
}
|
||||
|
||||
const char *LLVMInstGetOpcodeName(LLVMValueRef inst)
|
||||
{
|
||||
llvm::Instruction *instp = llvm::unwrap<llvm::Instruction>(inst);
|
||||
|
|
@ -332,6 +343,22 @@ LLVMModuleRef LLVMGetModuleFromBitcode(const char *bitcode, unsigned bclen,
|
|||
return wrap(modulep);
|
||||
}
|
||||
|
||||
unsigned LLVMLinkModules(LLVMModuleRef dest, LLVMModuleRef src, char **out)
|
||||
{
|
||||
llvm::Module *sourcep = llvm::unwrap(src);
|
||||
assert(sourcep);
|
||||
llvm::Module *destinationp = llvm::unwrap(dest);
|
||||
assert(destinationp);
|
||||
|
||||
std::string msg;
|
||||
if (llvm::Linker::LinkModules(destinationp, sourcep, &msg)) {
|
||||
*out = strdup(msg.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, unsigned *lenp)
|
||||
{
|
||||
assert(lenp);
|
||||
|
|
|
|||
|
|
@ -109,6 +109,9 @@ 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);
|
||||
|
||||
|
|
@ -127,6 +130,11 @@ LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtxt, unsigned txten,
|
|||
LLVMModuleRef LLVMGetModuleFromBitcode(const char *bc, unsigned bclen,
|
||||
char **out);
|
||||
|
||||
/* 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, char **errmsg);
|
||||
|
||||
/* 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, unsigned *len);
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -83,7 +83,7 @@ def call_setup(llvm_config):
|
|||
['core', 'analysis', 'scalaropts', 'executionengine',
|
||||
'jit', 'native', 'interpreter', 'bitreader', 'bitwriter',
|
||||
'instrumentation', 'ipa', 'ipo', 'transformutils',
|
||||
'asmparser' ])
|
||||
'asmparser', 'linker', 'support'])
|
||||
|
||||
std_libs = [ 'pthread', 'm', 'stdc++' ]
|
||||
if not ("openbsd" in sys.platform or "freebsd" in sys.platform):
|
||||
|
|
|
|||
|
|
@ -95,6 +95,9 @@ def do_module():
|
|||
m4 = Module.from_assembly(ss2)
|
||||
t = m4 == m
|
||||
t = m4.pointer_size
|
||||
mA = Module.new('ma')
|
||||
mB = Module.new('mb')
|
||||
mA.link_in(mB)
|
||||
|
||||
|
||||
def do_type():
|
||||
|
|
@ -451,6 +454,7 @@ def do_builder():
|
|||
t = i.is_associative == False
|
||||
t = i.is_commutative == False
|
||||
t = i.is_trapping == False
|
||||
t = i.is_volatile == False
|
||||
t = i.opcode
|
||||
t = i.opcode_name
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue