Added API for reading assembly (.ll) files

git-svn-id: http://llvm-py.googlecode.com/svn/trunk@35 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
mdevan.foobar 2008-09-08 13:09:43 +00:00
commit c10b1b58c3
10 changed files with 82 additions and 18 deletions

4
README
View file

@ -25,8 +25,8 @@ Quickstart:
2. Unpack llvm-py, build and install: 2. Unpack llvm-py, build and install:
$ tar jxvf llvm-py-0.2.tar.bz2 $ tar jxvf llvm-py-0.3.tar.bz2
$ cd llvm-py-0.2 $ cd llvm-py-0.3
# Locate llvm-config, usually under <llvm>/Release/bin # Locate llvm-config, usually under <llvm>/Release/bin
$ sudo python setup.py install --llvm-config=/path/to/llvm-config $ sudo python setup.py install --llvm-config=/path/to/llvm-config

View file

@ -62,8 +62,11 @@ _wLLVMVerifyModule(PyObject *self, PyObject *args)
return ret; return ret;
} }
typedef LLVMModuleRef (*asm_or_bc_fn_t)(const char *A, unsigned Len,
char **OutMessage);
static PyObject * static PyObject *
_wLLVMGetModuleFromBitcode(PyObject *self, PyObject *args) _get_asm_or_bc(asm_or_bc_fn_t fn, PyObject *self, PyObject *args)
{ {
PyObject *obj, *ret; PyObject *obj, *ret;
Py_ssize_t len; Py_ssize_t len;
@ -77,7 +80,7 @@ _wLLVMGetModuleFromBitcode(PyObject *self, PyObject *args)
len = PyString_Size(obj); len = PyString_Size(obj);
outmsg = 0; outmsg = 0;
m = LLVMGetModuleFromBitcode(start, len, &outmsg); m = fn(start, len, &outmsg);
if (!m) { if (!m) {
if (outmsg) { if (outmsg) {
ret = PyString_FromString(outmsg); ret = PyString_FromString(outmsg);
@ -91,6 +94,18 @@ _wLLVMGetModuleFromBitcode(PyObject *self, PyObject *args)
return ctor_LLVMModuleRef(m); return ctor_LLVMModuleRef(m);
} }
static PyObject *
_wLLVMGetModuleFromAssembly(PyObject *self, PyObject *args)
{
return _get_asm_or_bc(LLVMGetModuleFromAssembly, self, args);
}
static PyObject *
_wLLVMGetModuleFromBitcode(PyObject *self, PyObject *args)
{
return _get_asm_or_bc(LLVMGetModuleFromBitcode, self, args);
}
static PyObject * static PyObject *
_wLLVMGetBitcodeFromModule(PyObject *self, PyObject *args) _wLLVMGetBitcodeFromModule(PyObject *self, PyObject *args)
{ {
@ -910,6 +925,7 @@ static PyMethodDef core_methods[] = {
_method( LLVMDisposeModule ) _method( LLVMDisposeModule )
_method( LLVMDumpModuleToString ) _method( LLVMDumpModuleToString )
_method( LLVMVerifyModule ) _method( LLVMVerifyModule )
_method( LLVMGetModuleFromAssembly )
_method( LLVMGetModuleFromBitcode ) _method( LLVMGetModuleFromBitcode )
_method( LLVMGetBitcodeFromModule ) _method( LLVMGetBitcodeFromModule )

View file

@ -751,6 +751,21 @@ class Module(llvm.Ownable):
else: else:
return Module(ret) return Module(ret)
@staticmethod
def from_assembly(fileobj):
"""Create a Module instance from the contents of an LLVM
assembly (.ll) file."""
data = fileobj.read()
ret = _core.LLVMGetModuleFromAssembly(data)
if not ret:
raise llvm.LLVMException, \
"Unable to create module from assembly"
elif isinstance(ret, str):
raise llvm.LLVMException, ret
else:
return Module(ret)
def __init__(self, ptr): def __init__(self, ptr):
"""DO NOT CALL DIRECTLY. """DO NOT CALL DIRECTLY.

View file

@ -20,6 +20,7 @@
#include "llvm/Support/CallSite.h" #include "llvm/Support/CallSite.h"
#include "llvm/IntrinsicInst.h" #include "llvm/IntrinsicInst.h"
#include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Parser.h"
// +includes for passes // +includes for passes
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/LoopPass.h"
@ -110,6 +111,20 @@ LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef M, int ID,
return wrap(intfunc); return wrap(intfunc);
} }
LLVMModuleRef LLVMGetModuleFromAssembly(const char *A, unsigned Len,
char **OutMessage)
{
ParseError e;
Module *MP = ParseAssemblyString(A, NULL /*unused within!*/, &e);
if (!MP) {
*OutMessage = strdup(e.getMessage().c_str());
return NULL;
}
return wrap(MP);
}
LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len, LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len,
char **OutMessage) char **OutMessage)
{ {

View file

@ -51,6 +51,11 @@ LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef, LLVMValueRef V,
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef B, int ID, LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef B, int ID,
LLVMTypeRef *Types, unsigned Count); LLVMTypeRef *Types, unsigned Count);
/* reading llvm "assembly" */
LLVMModuleRef LLVMGetModuleFromAssembly(const char *A, unsigned Len,
char **OutMessage);
/* bitcode related */ /* bitcode related */
LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len, LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len,

View file

@ -51,7 +51,8 @@ def call_setup(llvm_config):
libs_core, objs_core = get_libs_and_objs(llvm_config, libs_core, objs_core = get_libs_and_objs(llvm_config,
['core', 'analysis', 'scalaropts', 'executionengine', ['core', 'analysis', 'scalaropts', 'executionengine',
'jit', 'native', 'interpreter', 'bitreader', 'bitwriter', 'jit', 'native', 'interpreter', 'bitreader', 'bitwriter',
'instrumentation', 'ipa', 'ipo', 'transformutils']) 'instrumentation', 'ipa', 'ipo', 'transformutils',
'asmparser' ])
std_libs = [ 'pthread', 'm' ] std_libs = [ 'pthread', 'm' ]
if not sys.platform.startswith("openbsd"): if not sys.platform.startswith("openbsd"):

17
test/asm.py Normal file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env python
from llvm import *
from llvm.core import *
# create a module
m = Module.new('module1')
m.add_global_variable(Type.int(), 'i')
# write it's assembly representation to a file
asm = str(m)
print >> file("/tmp/testasm.ll", "w"), asm
# read it back into a module
m2 = Module.from_assembly(file("/tmp/testasm.ll"))
print m2

View file

@ -74,6 +74,10 @@ def do_module():
m2.to_bitcode(ss) m2.to_bitcode(ss)
m3 = Module.from_bitcode(ss) m3 = Module.from_bitcode(ss)
t = m2 == m3 t = m2 == m3
ss2 = strstream()
ss2.write(str(m))
m4 = Module.from_assembly(ss2)
t = m4 == m
def do_type(): def do_type():

View file

@ -1,9 +1,9 @@
About About
===== =====
llvm-py is developed by Mahadevan R, in his spare time, without being llvm-py is developed by Mahadevan R, in his spare time. He can be
paid for it. He can be reached at mdevan.foobar@gmail.com, on the reached at mdevan.foobar@gmail.com, on the llvm-dev mailing list and
llvm-dev mailing list and irc.oftc.net#llvm (mdevan). irc.oftc.net#llvm (mdevan).
Many thanks to the guys over at LLVM for all the nifty software. Many thanks to the guys over at LLVM for all the nifty software.

View file

@ -5,7 +5,7 @@ llvm-py is just hatching. It needs your patches and suggestions to
grow up. Please contribute! All patches are welcome. Here are some links grow up. Please contribute! All patches are welcome. Here are some links
to start hacking away: to start hacking away:
`75`25~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `25`75~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Google code hosting, http://code.google.com/p/llvm-py/[http://code.google.com/p/llvm-py/] Google code hosting, http://code.google.com/p/llvm-py/[http://code.google.com/p/llvm-py/]
Browse SVN, http://code.google.com/p/llvm-py/source/browse/[http://code.google.com/p/llvm-py/source/browse] Browse SVN, http://code.google.com/p/llvm-py/source/browse/[http://code.google.com/p/llvm-py/source/browse]
Issues tracker, http://code.google.com/p/llvm-py/issues/list[http://code.google.com/p/llvm-py/issues/list] Issues tracker, http://code.google.com/p/llvm-py/issues/list[http://code.google.com/p/llvm-py/issues/list]
@ -20,13 +20,4 @@ $ svn checkout http://llvm-py.googlecode.com/svn/trunk/ llvm-py
Mahadevan R (mdevan.foobar@gmail.com) is available to answer your Mahadevan R (mdevan.foobar@gmail.com) is available to answer your
queries. queries.
Current Next Steps
------------------
- Wrap GenericValue, function call args for execution engine.
* done.
- Add APIs to read/write `.bc` and `.ll` files.
- Wrap `lto`.
- Add examples.
- Update documentation.
- Improve tests.