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:
mdevan.foobar 2009-02-21 10:02:46 +00:00
commit 6028e1765b
6 changed files with 89 additions and 2 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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