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:
$ tar jxvf llvm-py-0.2.tar.bz2
$ cd llvm-py-0.2
$ tar jxvf llvm-py-0.3.tar.bz2
$ cd llvm-py-0.3
# Locate llvm-config, usually under <llvm>/Release/bin
$ sudo python setup.py install --llvm-config=/path/to/llvm-config

View file

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

View file

@ -751,6 +751,21 @@ class Module(llvm.Ownable):
else:
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):
"""DO NOT CALL DIRECTLY.

View file

@ -20,6 +20,7 @@
#include "llvm/Support/CallSite.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Parser.h"
// +includes for passes
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoopPass.h"
@ -110,6 +111,20 @@ LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef M, int ID,
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,
char **OutMessage)
{

View file

@ -51,6 +51,11 @@ LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef, LLVMValueRef V,
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef B, int ID,
LLVMTypeRef *Types, unsigned Count);
/* reading llvm "assembly" */
LLVMModuleRef LLVMGetModuleFromAssembly(const char *A, unsigned Len,
char **OutMessage);
/* bitcode related */
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,
['core', 'analysis', 'scalaropts', 'executionengine',
'jit', 'native', 'interpreter', 'bitreader', 'bitwriter',
'instrumentation', 'ipa', 'ipo', 'transformutils'])
'instrumentation', 'ipa', 'ipo', 'transformutils',
'asmparser' ])
std_libs = [ 'pthread', 'm' ]
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)
m3 = Module.from_bitcode(ss)
t = m2 == m3
ss2 = strstream()
ss2.write(str(m))
m4 = Module.from_assembly(ss2)
t = m4 == m
def do_type():

View file

@ -1,9 +1,9 @@
About
=====
llvm-py is developed by Mahadevan R, in his spare time, without being
paid for it. He can be reached at mdevan.foobar@gmail.com, on the
llvm-dev mailing list and irc.oftc.net#llvm (mdevan).
llvm-py is developed by Mahadevan R, in his spare time. He can be
reached at mdevan.foobar@gmail.com, on the llvm-dev mailing list and
irc.oftc.net#llvm (mdevan).
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
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/]
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]
@ -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
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.