diff --git a/CHANGELOG b/CHANGELOG index 46f7e02..197a1ae 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ -0,5, in progress: +0.5, 22-Nov-2008: + * Added vicmp, vfcmp instructions and constant expressions. + * Builds on FreeBSD. + * Updated documentation. * Migrate to LLVM 2.4. diff --git a/llvm/_core.c b/llvm/_core.c index a98c239..a663047 100644 --- a/llvm/_core.c +++ b/llvm/_core.c @@ -384,10 +384,8 @@ _wrap_objobj2obj(LLVMConstXor, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_intobjobj2obj(LLVMConstICmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_intobjobj2obj(LLVMConstFCmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) -/* after LLVM 2.3! _wrap_intobjobj2obj(LLVMConstVICmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_intobjobj2obj(LLVMConstVFCmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) -*/ _wrap_objobj2obj(LLVMConstShl, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objobj2obj(LLVMConstLShr, LLVMValueRef, LLVMValueRef, LLVMValueRef) @@ -634,10 +632,8 @@ _wrap_objobjobjstr2obj(LLVMBuildBitCast, LLVMBuilderRef, LLVMValueRef, LLVMTypeR _wrap_objintobjobjstr2obj(LLVMBuildICmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objintobjobjstr2obj(LLVMBuildFCmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -/* after LLVM 2.3! _wrap_objintobjobjstr2obj(LLVMBuildVICmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objintobjobjstr2obj(LLVMBuildVFCmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -*/ /* Miscellaneous instructions */ @@ -1113,10 +1109,8 @@ static PyMethodDef core_methods[] = { _method( LLVMConstXor ) _method( LLVMConstICmp ) _method( LLVMConstFCmp ) - /* after LLVM 2.3! _method( LLVMConstVICmp ) _method( LLVMConstVFCmp ) - */ _method( LLVMConstShl ) _method( LLVMConstLShr ) _method( LLVMConstAShr ) @@ -1296,10 +1290,8 @@ static PyMethodDef core_methods[] = { /* Comparisons */ _method( LLVMBuildICmp ) _method( LLVMBuildFCmp ) - /* after LLVM 2.3! _method( LLVMBuildVICmp ) _method( LLVMBuildVFCmp ) - */ /* Miscellaneous instructions */ _method( LLVMBuildGetResult ) diff --git a/llvm/core.py b/llvm/core.py index 8e8946b..06f5996 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -1481,14 +1481,13 @@ class Constant(Value): check_is_constant(rhs) return Constant(_core.LLVMConstFCmp(real_pred, self.ptr, rhs.ptr)) -# after LLVM 2.3! -# def vicmp(self, int_pred, rhs): -# check_is_constant(rhs) -# return Constant(_core.LLVMConstVICmp(int_pred, self.ptr, rhs.ptr)) -# -# def vfcmp(self, real_pred, rhs): -# check_is_constant(rhs) -# return Constant(_core.LLVMConstVFCmp(real_pred, self.ptr, rhs.ptr)) + def vicmp(self, int_pred, rhs): + check_is_constant(rhs) + return Constant(_core.LLVMConstVICmp(int_pred, self.ptr, rhs.ptr)) + + def vfcmp(self, real_pred, rhs): + check_is_constant(rhs) + return Constant(_core.LLVMConstVFCmp(real_pred, self.ptr, rhs.ptr)) def shl(self, rhs): check_is_constant(rhs) @@ -2168,16 +2167,15 @@ class Builder(object): check_is_value(rhs) return Value(_core.LLVMBuildFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name)) -# after LLVM 2.3! -# def vicmp(self, ipred, lhs, rhs, name=""): -# check_is_value(lhs) -# check_is_value(rhs) -# return Value(_core.LLVMBuildVICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name)) -# -# def vfcmp(self, rpred, lhs, rhs, name=""): -# check_is_value(lhs) -# check_is_value(rhs) -# return Value(_core.LLVMBuildVFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name)) + def vicmp(self, ipred, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return Value(_core.LLVMBuildVICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name)) + + def vfcmp(self, rpred, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return Value(_core.LLVMBuildVFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name)) # misc diff --git a/llvm/extra.cpp b/llvm/extra.cpp index cf47369..597761d 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -99,6 +99,66 @@ char *LLVMDumpValueToString(LLVMValueRef value) return do_print(value); } +LLVMValueRef LLVMConstVICmp(LLVMIntPredicate predicate, LLVMValueRef lhs, + LLVMValueRef rhs) +{ + llvm::Constant *lhsp = llvm::unwrap(lhs); + assert(lhsp); + llvm::Constant *rhsp = llvm::unwrap(rhs); + assert(rhsp); + + llvm::Constant *vicmp = + llvm::ConstantExpr::getVICmp(predicate, lhsp, rhsp); + return llvm::wrap(vicmp); +} + +LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate predicate, LLVMValueRef lhs, + LLVMValueRef rhs) +{ + llvm::Constant *lhsp = llvm::unwrap(lhs); + assert(lhsp); + llvm::Constant *rhsp = llvm::unwrap(rhs); + assert(rhsp); + + llvm::Constant *vfcmp = + llvm::ConstantExpr::getVFCmp(predicate, lhsp, rhsp); + return llvm::wrap(vfcmp); +} + +LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef builder, LLVMIntPredicate predicate, + LLVMValueRef lhs, LLVMValueRef rhs, const char *name) +{ + llvm::IRBuilder<> *builderp = llvm::unwrap(builder); + assert(builderp); + + llvm::Value *lhsp = llvm::unwrap(lhs); + assert(lhsp); + llvm::Value *rhsp = llvm::unwrap(rhs); + assert(rhsp); + + llvm::Value *inst = builderp->CreateVICmp( + static_cast(predicate), + lhsp, rhsp, name); + return llvm::wrap(inst); +} + +LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef builder, LLVMRealPredicate predicate, + LLVMValueRef lhs, LLVMValueRef rhs, const char *name) +{ + llvm::IRBuilder<> *builderp = llvm::unwrap(builder); + assert(builderp); + + llvm::Value *lhsp = llvm::unwrap(lhs); + assert(lhsp); + llvm::Value *rhsp = llvm::unwrap(rhs); + assert(rhsp); + + llvm::Value *inst = builderp->CreateVFCmp( + static_cast(predicate), + lhsp, rhsp, name); + return llvm::wrap(inst); +} + unsigned LLVMModuleGetPointerSize(LLVMModuleRef module) { llvm::Module *modulep = llvm::unwrap(module); diff --git a/llvm/extra.h b/llvm/extra.h index 0ff9333..e5482ca 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -66,6 +66,22 @@ LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef bulder, LLVMValueRef *values, LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value, unsigned index, const char *name); +/* 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); diff --git a/setup.py b/setup.py index abd3f12..8ace7ab 100644 --- a/setup.py +++ b/setup.py @@ -86,7 +86,7 @@ def call_setup(llvm_config): 'asmparser' ]) std_libs = [ 'pthread', 'm' ] - if not sys.platform.startswith("openbsd"): + if not ("openbsd" in sys.platform or "freebsd" in sys.platform): std_libs.append("dl") ext_core = Extension( diff --git a/test/testall.py b/test/testall.py index 1d1fc9f..93faff3 100644 --- a/test/testall.py +++ b/test/testall.py @@ -187,9 +187,8 @@ def do_constant(): f.fdiv(f).frem(f).fcmp(RPRED_ULT, f) vi = Constant.vector([Constant.int(ti,42)]*10) vf = Constant.vector([Constant.real(Type.float(), 3.14)]*10) - # after LLVM 2.3! - #vi.vicmp(IPRED_ULT, vi) - #vf.vfcmp(RPRED_ULT, vf) + vi.vicmp(IPRED_ULT, vi) + vf.vfcmp(RPRED_ULT, vf) k.shl(k).lshr(k).ashr(k) # TODO gep k.trunc(Type.int(1)) @@ -430,9 +429,8 @@ def do_builder(): b.fcmp(RPRED_ULT, fv, fv) vi = Constant.vector([Constant.int(ti,42)]*10) vf = Constant.vector([Constant.real(Type.float(), 3.14)]*10) - # after LLVM 2.3! - # b.vicmp(IPRED_ULT, vi, vi) - # b.vfcmp(RPRED_ULT, vf, vf) + b.vicmp(IPRED_ULT, vi, vi) + b.vfcmp(RPRED_ULT, vf, vf) # TODO b.getresult(v, 0) b.call(f, [v]) b.select(Constant.int(Type.int(1), 1), blk, blk) diff --git a/www/src/index.txt b/www/src/index.txt index e392f79..49e127d 100644 --- a/www/src/index.txt +++ b/www/src/index.txt @@ -12,18 +12,16 @@ llvm-py is just hatching. It should be stable enough to start hacking away, though. Be sure to send in a patch if you miss any specific LLVM API. -_Availability_: llvm-py is available (as a source package) for LLVM 2.3 -and Python 2.5. It has been built and tested on Linux (x86, amd64) and -is reported to work with OpenBSD. It is expected to be usable on -various unices, as well as with Python 2.4. - -_LLVM 2.4_: Read link:userguide.html#llvm24[this] if you're using LLVM -2.4! - +_Availability_: llvm-py is available (as a source package) for LLVM 2.4 +and Python 2.5. It has been built and tested on Linux and FreeBSD +(x86 and amd64). News ---- +22-Nov-2008:: + 0.5 released. For LLVM 2.4. + 21-Nov-2008:: 0.4 released. Bug fixes, few additional APIs, code cleanup. diff --git a/www/src/userguide.txt b/www/src/userguide.txt index ec9feea..0667123 100644 --- a/www/src/userguide.txt +++ b/www/src/userguide.txt @@ -31,8 +31,8 @@ and OpenBSD (i386, amd64). However, it should be trivial to build it on other unices. Windows is not supported, for a variety of reasons. .Versions -llvm-py requires verion 2.3 of LLVM. It will not work with previous -versions. If you're using LLVM 2.4, see link:#llvm24[below]. +llvm-py 0.5 requires verion 2.4 of LLVM. It will not work with previous +versions. llvm-py has been built and tested with Python 2.5. It should work with Python 2.4, with minimal changes, if any. @@ -60,8 +60,6 @@ It does not matter which compiler LLVM itself was built with (g\+\+, llvm-g\+\+ or any other); llvm-py can be built with any compiler. It has been tried only with gcc/g\+\+ though. -Tip: If LLVM 2.3 does not install cleanly, try installing ``ocamldoc'' -first. LLVM and `--enable-pic` ~~~~~~~~~~~~~~~~~~~~~~~ @@ -75,7 +73,7 @@ independent code). Be sure to use the `--enable-pic` option while configuring LLVM (default is no PIC), like this: ---- -~/llvm-2.3$ ./configure --enable-pic --enable-optimized +~/llvm-2.4$ ./configure --enable-pic --enable-optimized ---- @@ -106,8 +104,8 @@ If you have +llvm-config+ in your path, you can build and install llvm-py this way: ----------------------------------------------------------------------- -$ tar jxvf llvm-py-0.3.tar.bz2 -$ cd llvm-py-0.3 +$ tar jxvf llvm-py-0.5.tar.bz2 +$ cd llvm-py-0.5 $ sudo python setup.py install ----------------------------------------------------------------------- @@ -115,8 +113,8 @@ If you need to tell the build script where +llvm-config+ is, do it this way: ----------------------------------------------------------------------- -$ tar jxvf llvm-py-0.3.tar.bz2 -$ cd llvm-py-0.3 +$ tar jxvf llvm-py-0.5.tar.bz2 +$ cd llvm-py-0.5 $ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Release/bin/llvm-config ----------------------------------------------------------------------- @@ -124,8 +122,8 @@ To build a debug version of llvm-py, that links against the debug libraries of LLVM, use this: ----------------------------------------------------------------------- -$ tar jxvf llvm-py-0.3.tar.bz2 -$ cd llvm-py-0.3 +$ tar jxvf llvm-py-0.5.tar.bz2 +$ cd llvm-py-0.5 $ python setup.py build -g --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config $ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config ----------------------------------------------------------------------- @@ -139,35 +137,6 @@ Python Modules] and http://docs.python.org/dist/dist.html[Distributing Python Modules] for more information on such scripts. -[[llvm24]] -LLVM 2.4 -~~~~~~~~ - -LLVM 2.4 is currently in progress. There are incompatible API changes -from LLVM 2.3. The latest release of llvm-py will _not_ compile against -it. - -The llvm-py SVN has a branch called -http://code.google.com/p/llvm-py/source/browse/#svn/branches/llvm2.4[llvm2.4], -which attempts to track the changes happening in LLVM 2.4. There are -however, some caveats: - -- There are no releases from this branch. -- When LLVM 2.4 is released, then these changes will be merged to main. - From then on llvm-py will support LLVM 2.4 and no longer LLVM 2.3. -- This branch is not religiously kept up-to-date with the changes - happening in LLVM SVN. Therefore, it may not work for you, but might - still be worth a try. - -llvm-py can be checked out from this branch like this: - ------------------------------------------------------------------------ -$ svn co http://llvm-py.googlecode.com/svn/branches/llvm2.4 llvm-py-2.4 ------------------------------------------------------------------------ - -The rest of the steps (build, install) remain the same as before. - - [[uninstall]] Uninstall ~~~~~~~~~ @@ -1378,28 +1347,30 @@ in `llvm.core`. These are: [frame="all",grid="all"] `33`33`33~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -INTR_ANNOTATION,INTR_DBG_STOPPOINT,INTR_MEMSET_I64 -INTR_ARM_THREAD_POINTER,INTR_EH_DWARF_CFA,INTR_PART_SELECT -INTR_ATOMIC_LAS,INTR_EH_EXCEPTION,INTR_PART_SET -INTR_ATOMIC_LCS,INTR_EH_RETURN,INTR_PCMARKER -INTR_ATOMIC_LOAD_AND,INTR_EH_SELECTOR_I32,INTR_POW -INTR_ATOMIC_LOAD_MAX,INTR_EH_SELECTOR_I64,INTR_POWI -INTR_ATOMIC_LOAD_MIN,INTR_EH_TYPEID_FOR_I32,INTR_PREFETCH -INTR_ATOMIC_LOAD_OR,INTR_EH_TYPEID_FOR_I64,INTR_READCYCLECOUNTER -INTR_ATOMIC_LOAD_UMAX,INTR_EH_UNWIND_INIT,INTR_RETURNADDRESS -INTR_ATOMIC_LOAD_UMIN,INTR_FLT_ROUNDS,INTR_SETJMP -INTR_ATOMIC_LOAD_XOR,INTR_FRAMEADDRESS,INTR_SIGLONGJMP -INTR_ATOMIC_LSS,INTR_GCREAD,INTR_SIGSETJMP -INTR_ATOMIC_SWAP,INTR_GCROOT,INTR_SIN -INTR_BSWAP,INTR_GCWRITE,INTR_SQRT -INTR_COS,INTR_INIT_TRAMPOLINE,INTR_STACKRESTORE -INTR_CTLZ,INTR_LONGJMP,INTR_STACKSAVE -INTR_CTPOP,INTR_MEMCPY_I32,INTR_TRAP -INTR_CTTZ,INTR_MEMCPY_I64,INTR_VACOPY -INTR_DBG_DECLARE,INTR_MEMMOVE_I32,INTR_VAEND -INTR_DBG_FUNC_START,INTR_MEMMOVE_I64,INTR_VAR_ANNOTATION -INTR_DBG_REGION_END,INTR_MEMORY_BARRIER,INTR_VASTART -INTR_DBG_REGION_START,INTR_MEMSET_I32, +INTR_ANNOTATION,INTR_ATOMIC_CMP_SWAP,INTR_ATOMIC_LOAD_ADD +INTR_ATOMIC_LOAD_AND,INTR_ATOMIC_LOAD_MAX,INTR_ATOMIC_LOAD_MIN +INTR_ATOMIC_LOAD_NAND,INTR_ATOMIC_LOAD_OR,INTR_ATOMIC_LOAD_SUB +INTR_ATOMIC_LOAD_UMAX,INTR_ATOMIC_LOAD_UMIN,INTR_ATOMIC_LOAD_XOR +INTR_ATOMIC_SWAP,INTR_BSWAP,INTR_COS +INTR_CTLZ,INTR_CTPOP,INTR_CTTZ +INTR_DBG_DECLARE,INTR_DBG_FUNC_START,INTR_DBG_REGION_END +INTR_DBG_REGION_START,INTR_DBG_STOPPOINT,INTR_EH_DWARF_CFA +INTR_EH_EXCEPTION,INTR_EH_RETURN_I32,INTR_EH_RETURN_I64 +INTR_EH_SELECTOR_I32,INTR_EH_SELECTOR_I64,INTR_EH_TYPEID_FOR_I32 +INTR_EH_TYPEID_FOR_I64,INTR_EH_UNWIND_INIT,INTR_EXP +INTR_EXP2,INTR_FLT_ROUNDS,INTR_FRAMEADDRESS +INTR_GCREAD,INTR_GCROOT,INTR_GCWRITE +INTR_INIT_TRAMPOLINE,INTR_LOG,INTR_LOG10 +INTR_LOG2,INTR_LONGJMP,INTR_MEMCPY_I32 +INTR_MEMCPY_I64,INTR_MEMMOVE_I32,INTR_MEMMOVE_I64 +INTR_MEMORY_BARRIER,INTR_MEMSET_I32,INTR_MEMSET_I64 +INTR_PART_SELECT,INTR_PART_SET,INTR_PCMARKER +INTR_POW,INTR_POWI,INTR_PREFETCH +INTR_READCYCLECOUNTER,INTR_RETURNADDRESS,INTR_SETJMP +INTR_SIGLONGJMP,INTR_SIGSETJMP,INTR_SIN +INTR_SQRT,INTR_STACKRESTORE,INTR_STACKSAVE +INTR_TRAP,INTR_VACOPY,INTR_VAEND +INTR_VAR_ANNOTATION,INTR_VASTART, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are also target-specific intrinsics (which correspond to that diff --git a/www/web/index.html b/www/web/index.html index 7fe9f49..3b7a265 100644 --- a/www/web/index.html +++ b/www/web/index.html @@ -42,18 +42,23 @@ Boost.Python, swig etc.

llvm-py is just hatching. It should be stable enough to start hacking away, though. Be sure to send in a patch if you miss any specific LLVM API.

-

Availability: llvm-py is available (as a source package) for LLVM 2.3 -and Python 2.5. It has been built and tested on Linux (x86, amd64) and -is reported to work with OpenBSD. It is expected to be usable on -various unices, as well as with Python 2.4.

-

LLVM 2.4: Read this if you're using LLVM -2.4!

+

Availability: llvm-py is available (as a source package) for LLVM 2.4 +and Python 2.5. It has been built and tested on Linux and FreeBSD +(x86 and amd64).

News

+22-Nov-2008 +
+
+

+ 0.5 released. For LLVM 2.4. +

+
+
21-Nov-2008
@@ -98,7 +103,7 @@ various unices, as well as with Python 2.4.

diff --git a/www/web/userguide.html b/www/web/userguide.html index f31e3be..b893ebb 100644 --- a/www/web/userguide.html +++ b/www/web/userguide.html @@ -2,7 +2,7 @@ - + @@ -43,42 +43,39 @@ window.onload = function(){generateToc(2)}
-

llvm-py provides Python bindings for LLVM. This document explains how +

llvm-py provides Python bindings for LLVM. This document explains how you can setup and use it. A working knowledge of Python and a basic idea -of LLVM is assumed.

+of LLVM is assumed.

-

Introduction

+

Introduction

-

LLVM (Low-Level Virtual Machine) provides enough +

LLVM (Low-Level Virtual Machine) provides enough infrastructure to use it as the backend for your compiled, or JIT-compiled language. It provides extensive optimization support, and static and dynamic (JIT) backends for many platforms. See the website at -http://www.llvm.org/ to discover more.

-

Python bindings for LLVM provides a gentler learning curve for working +http://www.llvm.org/ to discover more.

+

Python bindings for LLVM provides a gentler learning curve for working with the LLVM APIs. It should also be easier to create working -prototypes and experimental languages using this medium.

-
License
-

Both LLVM and llvm-py are distributed under (different) permissive +prototypes and experimental languages using this medium.

+
License

Both LLVM and llvm-py are distributed under (different) permissive open source licenses. llvm-py uses the new BSD license. More -information is available here.

-
Platforms
-

Currently, llvm-py has been built and tested only on Linux (i386, amd64) +information is available here.

+
Platforms

Currently, llvm-py has been built and tested only on Linux (i386, amd64) and OpenBSD (i386, amd64). However, it should be trivial to build it on -other unices. Windows is not supported, for a variety of reasons.

-
Versions
-

llvm-py requires verion 2.3 of LLVM. It will not work with previous -versions. If you're using LLVM 2.4, see below.

-

llvm-py has been built and tested with Python 2.5. It should work with -Python 2.4, with minimal changes, if any.

+other unices. Windows is not supported, for a variety of reasons.

+
Versions

llvm-py 0.5 requires verion 2.4 of LLVM. It will not work with previous +versions.

+

llvm-py has been built and tested with Python 2.5. It should work with +Python 2.4, with minimal changes, if any.

-

Installation

+

Installation

-

llvm-py is distributed as a source tarball. You'll need to build and +

llvm-py is distributed as a source tarball. You'll need to build and install it before it can be used. At least the following will be -required for this:

-
    +required for this:

+
  • C and C++ compilers (gcc/g++) @@ -99,116 +96,80 @@ Python development files (headers and libraries) LLVM, either installed or built

  • -
-

On debian-based systems, the first three can be installed with the +

+

On debian-based systems, the first three can be installed with the command sudo apt-get install gcc g++ python python-dev. Note that ubuntu repository has an old version of llvm (1.8) which will not work -with llvm-py.

-

It does not matter which compiler LLVM itself was built with (g++, +with llvm-py.

+

It does not matter which compiler LLVM itself was built with (g++, llvm-g++ or any other); llvm-py can be built with any compiler. It has -been tried only with gcc/g++ though.

-

Tip: If LLVM 2.3 does not install cleanly, try installing “ocamldoc” -first.

-

LLVM and —enable-pic

-

The result of an LLVM build is a set of static libraries and object +been tried only with gcc/g++ though.

+

LLVM and —enable-pic

+

The result of an LLVM build is a set of static libraries and object files. The llvm-py contains an extension package that is built into a shared object (_core.so) which links to these static libraries and object files. It is therefore required that the LLVM libraries and object files be built with the -fPIC option (generate position independent code). Be sure to use the —enable-pic option while -configuring LLVM (default is no PIC), like this:

+configuring LLVM (default is no PIC), like this:

-
~/llvm-2.3$ ./configure --enable-pic --enable-optimized
+
~/llvm-2.4$ ./configure --enable-pic --enable-optimized
-

llvm-config

-

Inorder to build llvm-py, it's build script needs to know from where it +

llvm-config

+

Inorder to build llvm-py, it's build script needs to know from where it can invoke the llvm helper program, llvm-config. If you've installed LLVM, then this will be available in your PATH, and nothing further needs to be done. If you've built LLVM yourself, or for any reason llvm-config is not in your PATH, you'll need to pass the full path -of llvm-config to the build script.

-

You'll need to be root to install llvm-py. Remember that your PATH +of llvm-config to the build script.

+

You'll need to be root to install llvm-py. Remember that your PATH is different from that of root, so even if llvm-config is in your -PATH, it may not be available when you do sudo.

-

Steps

-

The commands illustrated below assume that the LLVM source is available +PATH, it may not be available when you do sudo.

+

Steps

+

The commands illustrated below assume that the LLVM source is available under /home/mdevan/llvm. If you've a previous version of llvm-py installed, it is recommended to remove it first, as described -below.

-

If you have llvm-config in your path, you can build and install -llvm-py this way:

+below.

+

If you have llvm-config in your path, you can build and install +llvm-py this way:

-
$ tar jxvf llvm-py-0.3.tar.bz2
-$ cd llvm-py-0.3
+
$ tar jxvf llvm-py-0.5.tar.bz2
+$ cd llvm-py-0.5
 $ sudo python setup.py install
-

If you need to tell the build script where llvm-config is, do it this -way:

+

If you need to tell the build script where llvm-config is, do it this +way:

-
$ tar jxvf llvm-py-0.3.tar.bz2
-$ cd llvm-py-0.3
+
$ tar jxvf llvm-py-0.5.tar.bz2
+$ cd llvm-py-0.5
 $ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Release/bin/llvm-config
-

To build a debug version of llvm-py, that links against the debug -libraries of LLVM, use this:

+

To build a debug version of llvm-py, that links against the debug +libraries of LLVM, use this:

-
$ tar jxvf llvm-py-0.3.tar.bz2
-$ cd llvm-py-0.3
+
$ tar jxvf llvm-py-0.5.tar.bz2
+$ cd llvm-py-0.5
 $ python setup.py build -g --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config
 $ sudo python setup.py install --llvm-config=/home/mdevan/llvm/Debug/bin/llvm-config
-

Be warned that debug binaries will be huge (100MB+) ! They are required -only if you need to debug into LLVM also.

-

setup.py is a standard Python distutils script. See the Python +

Be warned that debug binaries will be huge (100MB+) ! They are required +only if you need to debug into LLVM also.

+

setup.py is a standard Python distutils script. See the Python documentation regarding Installing Python Modules and Distributing -Python Modules for more information on such scripts.

-

LLVM 2.4

-

LLVM 2.4 is currently in progress. There are incompatible API changes -from LLVM 2.3. The latest release of llvm-py will not compile against -it.

-

The llvm-py SVN has a branch called -llvm2.4, -which attempts to track the changes happening in LLVM 2.4. There are -however, some caveats:

-
    -
  • -

    -There are no releases from this branch. -

    -
  • -
  • -

    -When LLVM 2.4 is released, then these changes will be merged to main. - From then on llvm-py will support LLVM 2.4 and no longer LLVM 2.3. -

    -
  • -
  • -

    -This branch is not religiously kept up-to-date with the changes - happening in LLVM SVN. Therefore, it may not work for you, but might - still be worth a try. -

    -
  • -
-

llvm-py can be checked out from this branch like this:

-
-
-
$ svn co http://llvm-py.googlecode.com/svn/branches/llvm2.4 llvm-py-2.4
-
-

The rest of the steps (build, install) remain the same as before.

-

Uninstall

-

To get rid of llvm-py completely, if you wish to do so:

+Python Modules for more information on such scripts.

+

Uninstall

+

To get rid of llvm-py completely, if you wish to do so:

# rm -rf /usr/lib/python2.5/site-packages/llvm
 # rm -f /usr/lib/python2.5/site-packages/llvm_py-0.1.egg-info
-
    +
    • You need to be root to do this. @@ -225,19 +186,19 @@ Note that there are version numbers (both Python's and llvm-py's) which you might need to change to suit your system.

    • -
    +
-

The Concepts

+

The Concepts

-

This section explains a few concepts related to LLVM.

-

Intermediate Representation

-

The intermediate representation, or IR for short, is an in-memory data +

This section explains a few concepts related to LLVM.

+

Intermediate Representation

+

The intermediate representation, or IR for short, is an in-memory data structure that represents executable code. The IR data structures allow for creation of types, constants, functions, function arguments, instructions, global variables and so on. For example, to create a function sum that takes two integers and returns their sum, we need to -follow these steps:

-
    +follow these steps:

+
  • create an integer type ti of required bitwidth @@ -264,7 +225,7 @@ add a basic block to the function using a helper object called an instruction builder, add two instructions into the basic block:

    -
      +
      1. an instruction to add the two arguments and store the result into @@ -276,25 +237,25 @@ an instruction to add the two arguments and store the result into a return instruction to return the value of the temporary variable

      2. -
      +
- -

(A basic block is a block of instructions.)

-

LLVM has it's own instruction set; the instructions used above (add +

+

(A basic block is a block of instructions.)

+

LLVM has it's own instruction set; the instructions used above (add and ret) are from this set. The LLVM instructions are at a higher level than the usual assembly language; for example there are instructions related to variable argument handling, exception handling, and garbage collection. These allow high-level languages to be -represented cleanly in the IR.

-

SSA Form and PHI Nodes

-

All LLVM instructions are represented in the Static Single Assignment +represented cleanly in the IR.

+

SSA Form and PHI Nodes

+

All LLVM instructions are represented in the Static Single Assignment (SSA) form. Essentially, this means that any variable can be assigned to only once. Such a representation facilitates better optimization, among -other benefits.

-

A consequence of single assignment are PHI (Φ) nodes. These +other benefits.

+

A consequence of single assignment are PHI (Φ) nodes. These are required when a variable can be assigned a different value based on the path of control flow. For example, the value of b at the end of -execution of the snippet below:

+execution of the snippet below:

a = 1;
@@ -302,10 +263,10 @@ if (v < 10)
   a = 2;
 b = a;
-

cannot be determined statically. The value of 2 cannot be assigned to +

cannot be determined statically. The value of 2 cannot be assigned to the original a, since a can be assigned to only once. There are two a 's in there, and the last assignment has to choose between which -version to pick. This is accomplished by adding a PHI node:

+version to pick. This is accomplished by adding a PHI node:

a1 = 1;
@@ -313,26 +274,26 @@ if (v < 10)
   a2 = 2;
 b = PHI(a1, a2);
-

The PHI node selects a1 or a2, depending on where the control +

The PHI node selects a1 or a2, depending on where the control reached the PHI node. The argument a1 of the PHI node is associated -with the block "a1 = 1;" and a2 with the block "a2 = 2;".

-

PHI nodes have to be explicitly created in the LLVM IR. Accordingly the -LLVM instruction set has an instruction called phi.

-

LLVM Assembly Language

-

The LLVM IR can be represented offline in two formats +with the block "a1 = 1;" and a2 with the block "a2 = 2;".

+

PHI nodes have to be explicitly created in the LLVM IR. Accordingly the +LLVM instruction set has an instruction called phi.

+

LLVM Assembly Language

+

The LLVM IR can be represented offline in two formats - a textual, human-readable form, similar to assembly language, called the LLVM assembly language (files with .ll extension) - a binary form, called the LLVM bitcode (files with .bc extension) All three formats (the in-memory IR, the LLVM assembly language and the LLVM bitcode) represent the same information. Each format can be -converted into the other two formats (using LLVM APIs).

-

The LLVM demo page lets you type in C or C++ +converted into the other two formats (using LLVM APIs).

+

The LLVM demo page lets you type in C or C++ code, converts it into LLVM IR and outputs the IR as LLVM assembly -language code.

-

Just to get a feel of the LLVM assembly language, here's a function in C, -and the corresponding LLVM assembly (as generated by the demo page):

+language code.

+

Just to get a feel of the LLVM assembly language, here's a function in C, +and the corresponding LLVM assembly (as generated by the demo page):

-
@@ -345,7 +306,7 @@ http://www.gnu.org/software/src-highlite --> return n + sum(n-1); }
-

The corresponding LLVM assembly:

+

The corresponding LLVM assembly:

; ModuleID = '/tmp/webcompile/_4940_0.bc'
@@ -373,14 +334,14 @@ bb10:           ; preds = %entry
         ret i32 0
 }
-

Note the usage of SSA form and the total absence of any loop or +

Note the usage of SSA form and the total absence of any loop or recursion at all! The long string called target datalayout is a specification of the platform ABI (like endianness, sizes of types, -alignment etc.).

-

The LLVM Language Reference +alignment etc.).

+

The LLVM Language Reference defines the LLVM assembly language including the entire instruction set. The table below lists all the LLVM instructions. Each instruction links -to it's documentation.

+to it's documentation.

-

Modules

-

Modules, in the LLVM IR, are similar to a single C language source -file (.c file). A module contains:

-
    +

    Modules

    +

    Modules, in the LLVM IR, are similar to a single C language source +file (.c file). A module contains:

    +
    • functions (declarations and definitions) @@ -557,39 +518,39 @@ global variables and constants global type aliases (typedef-s)

    • -
    -

    Modules are top-level containers; all executable code representation is -contained within modules.

    -

    Optimization and Passes

    -

    LLVM provides quite a few optimization algorithms that work on the IR. +

+

Modules are top-level containers; all executable code representation is +contained within modules.

+

Optimization and Passes

+

LLVM provides quite a few optimization algorithms that work on the IR. These algorithms are organized as passes. Each pass does something specific, like combining redundant instructions. Passes need not always optimize the IR, it can also do other operations like inserting instrumentation code, or analysing the IR (the result of which can be -used by passes that do optimizations) or even printing call graphs.

-

This LLVM documentation page -describes all the available passes, and what they do.

-

LLVM does not automatically choose to run any passes, anytime. Passes +used by passes that do optimizations) or even printing call graphs.

+

This LLVM documentation page +describes all the available passes, and what they do.

+

LLVM does not automatically choose to run any passes, anytime. Passes have to be explicitly selected and run on each module. This gives you the flexibility to choose transformations and optimizations that are -most suitable for the code in the module.

-

There is an LLVM binary called opt, +most suitable for the code in the module.

+

There is an LLVM binary called opt, which lets you run passes on bitcode files from the command line. You can write your own passes (in C/C++, as a shared library). This can be loaded and executed by opt. (Although llvm-py does not allow you to write your own passes, it does allow you to navigate the entire IR at -any stage, and perform any transforms on it as you like.)

+any stage, and perform any transforms on it as you like.)

-

The llvm-py Package

+

The llvm-py Package

-

The llvm-py is a Python package, consisting of 6 modules, that wrap +

The llvm-py is a Python package, consisting of 6 modules, that wrap over enough LLVM APIs to allow the implementation of your own compiler/VM backend in pure Python. If you're come this far, you -probably know why this is a good idea.

-

Out of the 6 modules, one is an “extension” module (i.e., it is +probably know why this is a good idea.

+

Out of the 6 modules, one is an “extension” module (i.e., it is written in C), and another one is a small private utility module, which -leaves 4 public modules. These are:

-
    +leaves 4 public modules. These are:

+
  • llvm — top-level package, common classes (like exceptions) @@ -610,24 +571,24 @@ leaves 4 public modules. These are:

    llvm.passes — pass manager and passes related APIs

  • -
-

The modules contain only classes and (integer) constants. Mostly simple +

+

The modules contain only classes and (integer) constants. Mostly simple Python constructs are used (deliberately) — property() and property decorators are probably the most exotic animals around. All classes are "new style" classes. The APIs are designed to be navigable (and guessable!) once you know a few conventions. These conventions are -highlighted in the sections below.

-

Here is a quick overview of the contents of each package:

-
llvm
    +highlighted in the sections below.

+

Here is a quick overview of the contents of each package:

+
llvm
  • LLVMException — exception class (currently the only one)

  • -
-
llvm.core
    +
+
llvm.core
  • Module — represents an LLVM Module @@ -712,8 +673,8 @@ constants VISIBILITY_* that represents visibility of symbols constants ATTR_* that represent function parameter attributes

  • -
-
llvm.ee
    +
+
llvm.ee
  • ExecutionEngine — represents an execution engine (which can be an @@ -726,8 +687,8 @@ TargetData — represents the ABI of the target platform (details like sizes and alignment of primitive types, endinanness etc)

  • -
-
llvm.passes
    +
+
llvm.passes
  • PassManager — represents an LLVM pass manager @@ -743,13 +704,12 @@ FunctionPassManager — represents an LLVM function pass manager constants PASS_* that represent various passes

  • -
-
A note on the 'import'ing of these modules
-

Pythonically, modules are imported with the statement "import +

+
A note on the 'import'ing of these modules

Pythonically, modules are imported with the statement "import llvm.core". However, you might find it more convenient to import -llvm-py modules thus:

+llvm-py modules thus:

-
@@ -758,7 +718,7 @@ http://www.gnu.org/software/src-highlite --> from llvm.ee import * from llvm.passes import *
-

This avoids quite some typing. Both conventions work, however.

+

This avoids quite some typing. Both conventions work, however.

@@ -770,12 +730,12 @@ interpreter or the object? of to get online help. (Note: not complete yet!)
-

Module (llvm.core)

-

Modules are top-level container objects. You need to create a module +

Module (llvm.core)

+

Modules are top-level container objects. You need to create a module object first, before you can add global variables, aliases or functions. -Modules are created using the static method Module.new:

+Modules are created using the static method Module.new:

-
@@ -785,10 +745,10 @@ http://www.gnu.org/software/src-highlite --> from llvm.core import * # create a module -my_module = Module.new('my_module') +my_module = Module.new('my_module')
-

The constructor of the Module class should not be used to instantiate -a Module object. This is a common feature for all llvm-py classes.

+

The constructor of the Module class should not be used to instantiate +a Module object. This is a common feature for all llvm-py classes.

@@ -796,55 +756,55 @@ a Module object. This is a common feature for all llvm-py classes.

Convention
-

All llvm-py objects are instantiated using static methods of -corresponding classes. Constructors should not be used.

+

All llvm-py objects are instantiated using static methods of +corresponding classes. Constructors should not be used.

-

The argument my_module is a module identifier (a plain string). A +

The argument my_module is a module identifier (a plain string). A module can also be constructed via deserialization from a bit code file, using the static method from_bitcode. This method takes a file-like object as argument, i.e., it should have a read() method that returns the entire data in a single call, as is the case with the builtin file -object. Here is an example:

+object. Here is an example:

-
# create a module from a bit code file
 bcfile = file("test.bc")
-my_module = Module.from_bitcode(bcfile)
+my_module = Module.from_bitcode(bcfile)
 
-

There is corresponding serialization method also, called to_bitcode:

+

There is corresponding serialization method also, called to_bitcode:

-
# write out a bit code file from the module
 bcfile = file("test.bc", "w")
-my_module.to_bitcode(bcfile)
+my_module.to_bitcode(bcfile)
 
-

Modules can also be constructed from LLVM assembly files (.ll files). +

Modules can also be constructed from LLVM assembly files (.ll files). The static method from_assembly can be used for this. Similar to the from_bitcode method, this one also takes a file-like object as -argument:

+argument:

-
# create a module from an assembly file
 llfile = file("test.ll")
-my_module = Module.from_assembly(llfile)
+my_module = Module.from_assembly(llfile)
 
-

Modules can be converted into their assembly representation by -stringifying them (see below).

+

Modules can be converted into their assembly representation by +stringifying them (see below).

llvm.core.Module
-
Static Constructors
+
Static Constructors
new(module_id)
@@ -872,8 +832,8 @@ stringifying them (see below).

represented by the file-like object fileobj.

-
-
Properties
+
+
Properties
data_layout
@@ -908,8 +868,8 @@ stringifying them (see below).

in the module.

-
-
Methods
+
+
Methods
add_type_name(name, ty)
@@ -981,8 +941,8 @@ stringifying them (see below).

object fileobj.

-
-
Special Methods
+
+
Special Methods
__str__
@@ -1002,7 +962,7 @@ stringifying them (see below).

compares the resultant strings.

-
+
@@ -1011,26 +971,26 @@ stringifying them (see below).

Convention
-

All llvm-py objects (where it makes sense), when stringified, return +

All llvm-py objects (where it makes sense), when stringified, return the LLVM assembly representation. “ print module_obj ” for example, -prints the LLVM assembly form of the entire module.

-

Such objects, when compared for equality, internally compare these -string representations.

+prints the LLVM assembly form of the entire module.

+

Such objects, when compared for equality, internally compare these +string representations.

-

Types (llvm.core)

-

Types are what you think they are. A instance of llvm.core.Type, or +

Types (llvm.core)

+

Types are what you think they are. A instance of llvm.core.Type, or one of its derived classes, represent a type. llvm-py does not use as many classes to represent types as does LLVM itself. Some types are represented using llvm.core.Type itself and the rest are represented using derived classes of llvm.core.Type. As usual, an instance is created via one of the static methods of Type. These methods return an instance of either llvm.core.Type itself or one of its derived -classes.

-

The following table lists all the available types along with the static +classes.

+

The following table lists all the available types along with the static method which has to be used to construct it and the name of the class whose -object is actually returned by the static method.

+object is actually returned by the static method.

-

The class hierarchy is:

+

The class hierarchy is:

Type
@@ -1231,11 +1191,11 @@ cellspacing="0" cellpadding="4">
   PointerType
   VectorType
-

The class-level documentation follows:

+

The class-level documentation follows:

llvm.core.Type
-
Static Constructors
+
Static Constructors
int(n)
@@ -1356,8 +1316,8 @@ cellspacing="0" cellpadding="4"> Opaque type, used for creating self-referencing types.

-
-
Properties
+
+
Properties
kind [read-only]
@@ -1367,37 +1327,37 @@ cellspacing="0" cellpadding="4"> one of the following constants defined in llvm.core:

-
-
TYPE_VOID       = 0
-TYPE_FLOAT      = 1
-TYPE_DOUBLE     = 2
-TYPE_X86_FP80   = 3
-TYPE_FP128      = 4
-TYPE_PPC_FP128  = 5
-TYPE_LABEL      = 6
-TYPE_INTEGER    = 7
-TYPE_FUNCTION   = 8
-TYPE_STRUCT     = 9
-TYPE_ARRAY      = 10
-TYPE_POINTER    = 11
-TYPE_OPAQUE     = 12
-TYPE_VECTOR     = 13
+
TYPE_VOID       = 0
+TYPE_FLOAT      = 1
+TYPE_DOUBLE     = 2
+TYPE_X86_FP80   = 3
+TYPE_FP128      = 4
+TYPE_PPC_FP128  = 5
+TYPE_LABEL      = 6
+TYPE_INTEGER    = 7
+TYPE_FUNCTION   = 8
+TYPE_STRUCT     = 9
+TYPE_ARRAY      = 10
+TYPE_POINTER    = 11
+TYPE_OPAQUE     = 12
+TYPE_VECTOR     = 13
 
-

Example:

+

Example:

-
-
assert Type.int().kind == TYPE_INTEGER
-assert Type.void().kind == TYPE_VOID
+
assert Type.int().kind == TYPE_INTEGER
+assert Type.void().kind == TYPE_VOID
 
-
-
Methods
+
+
Methods
refine
@@ -1407,8 +1367,8 @@ http://www.gnu.org/software/src-highlite --> of TypeHandle objects.

-
-
Special Methods
+
+
Special Methods
__str__
@@ -1428,19 +1388,19 @@ http://www.gnu.org/software/src-highlite --> compares the resultant strings.

-
+
llvm.core.IntegerType
-
Base Class
    +
    Base Class
    • llvm.core.Type

    • -
    -
    Properties
    +
+
Properties
width [read-only]
@@ -1449,19 +1409,19 @@ http://www.gnu.org/software/src-highlite --> The width of the integer type, in number of bits.

-
+
llvm.core.FunctionType
-
Base Class
    +
    Base Class
    • llvm.core.Type

    • -
    -
    Properties
    +
+
Properties
return_type [read-only]
@@ -1488,15 +1448,15 @@ http://www.gnu.org/software/src-highlite --> function. Used like this:

-
-
func_type = Type.function( Type.int(), [ Type.int(), Type.int() ] )
-for arg in func_type.args:
-    assert arg.kind == TYPE_INTEGER
-    assert arg == Type.int()
-assert func_type.arg_count == len(func_type.args)
+
func_type = Type.function( Type.int(), [ Type.int(), Type.int() ] )
+for arg in func_type.args:
+    assert arg.kind == TYPE_INTEGER
+    assert arg == Type.int()
+assert func_type.arg_count == len(func_type.args)
 
@@ -1507,19 +1467,19 @@ http://www.gnu.org/software/src-highlite --> The number of arguments. Same as len(obj.args), but faster.

-
+
llvm.core.StructType
-
Base Class
    +
    Base Class
    • llvm.core.Type

    • -
    -
    Properties
    +
+
Properties
packed [read-only]
@@ -1538,15 +1498,15 @@ http://www.gnu.org/software/src-highlite --> Used like this:

-
-
struct_type = Type.struct( [ Type.int(), Type.int() ] )
-for elem in struct_type.elements:
-    assert elem.kind == TYPE_INTEGER
-    assert elem == Type.int()
-assert struct_type.element_count == len(struct_type.elements)
+
struct_type = Type.struct( [ Type.int(), Type.int() ] )
+for elem in struct_type.elements:
+    assert elem.kind == TYPE_INTEGER
+    assert elem == Type.int()
+assert struct_type.element_count == len(struct_type.elements)
 
@@ -1557,19 +1517,19 @@ http://www.gnu.org/software/src-highlite --> The number of elements. Same as len(obj.elements), but faster.

-
+
llvm.core.ArrayType
-
Base Class
    +
    Base Class
    • llvm.core.Type

    • -
    -
    Properties
    +
+
Properties
element [read-only]
@@ -1586,19 +1546,19 @@ http://www.gnu.org/software/src-highlite --> The number of elements in the array.

-
+
llvm.core.PointerType
-
Base Class
    +
    Base Class
    • llvm.core.Type

    • -
    -
    Properties
    +
+
Properties
address_space [read-only]
@@ -1615,19 +1575,19 @@ http://www.gnu.org/software/src-highlite --> TODO missing

-
+
llvm.core.VectorType
-
Base Class
    +
    Base Class
    • llvm.core.Type

    • -
    -
    Properties
    +
+
Properties
element [read-only]
@@ -1644,66 +1604,66 @@ http://www.gnu.org/software/src-highlite --> The number of elements in the vector.

-
+
-

Here is an example that demonstrates the creation of types:

+

Here is an example that demonstrates the creation of types:

-
#!/usr/bin/env python
 
 # integers
-int_ty      = Type.int()
-bool_ty     = Type.int(1)
-int_64bit   = Type.int(64)
+int_ty      = Type.int()
+bool_ty     = Type.int(1)
+int_64bit   = Type.int(64)
 
 # floats
-sprec_real  = Type.float()
-dprec_real  = Type.double()
+sprec_real  = Type.float()
+dprec_real  = Type.double()
 
 # arrays and vectors
-intar_ty    = Type.array( int_ty, 10 )     # "typedef int intar_ty[10];"
-twodim      = Type.array( intar_ty , 10 )  # "typedef int twodim[10][10];"
-vec         = Type.array( int_ty, 10 )
+intar_ty    = Type.array( int_ty, 10 )     # "typedef int intar_ty[10];"
+twodim      = Type.array( intar_ty , 10 )  # "typedef int twodim[10][10];"
+vec         = Type.array( int_ty, 10 )
 
 # structures
-s1_ty       = Type.struct( [ int_ty, sprec_real ] )
+s1_ty       = Type.struct( [ int_ty, sprec_real ] )
     # "struct s1_ty { int v1; float v2; };"
 
 # pointers
-intptr_ty   = Type.pointer(int_ty)         # "typedef int *intptr_ty;"
+intptr_ty   = Type.pointer(int_ty)         # "typedef int *intptr_ty;"
 
 # functions
-f1 = Type.function( int_ty, [ int_ty ] )
+f1 = Type.function( int_ty, [ int_ty ] )
     # functions that take 1 int_ty and return 1 int_ty
 
-f2 = Type.function( Type.void(), [ int_ty, int_ty ] )
+f2 = Type.function( Type.void(), [ int_ty, int_ty ] )
     # functions that take 2 int_tys and return nothing
 
-f3 = Type.function( Type.void(), ( int_ty, int_ty ) )
+f3 = Type.function( Type.void(), ( int_ty, int_ty ) )
     # same as f2; any iterable can be used
 
-fnargs = [ Type.pointer( Type.int(8) ) ]
-printf = Type.function( Type.int(), fnargs, True )
+fnargs = [ Type.pointer( Type.int(8) ) ]
+printf = Type.function( Type.int(), fnargs, True )
     # variadic function
 
-

TypeHandle (llvm.core)

-

TypeHandle objects are used to create recursive types, like this linked -list node structure in C:

+

TypeHandle (llvm.core)

+

TypeHandle objects are used to create recursive types, like this linked +list node structure in C:

-
-
struct node
+
struct node
 {
     int data;
-    struct node *next;
+    struct node *next;
 };
 
-

This can be realized in llvm-py like this:

+

This can be realized in llvm-py like this:

#!/usr/bin/env python
@@ -1726,24 +1686,24 @@ m.add_type_name("struct.node", th.type)
 # show what we created
 print m
-

which gives the output:

+

which gives the output:

; ModuleID = 'mod1'
         %struct.node = type { i32, %struct.node* }
-

For more details on what is going on here, please refer the LLVM +

For more details on what is going on here, please refer the LLVM Programmer's Manual section "LLVM Type Resolution". The TypeHandle class of llvm-py corresponds to llvm::PATypeHolder in C++. The above example is available as test/typehandle.py -in the source distribution.

+in the source distribution.

llvm.core.TypeHandle
-
Static Constructors
+
Static Constructors
new(abstract_ty)
@@ -1754,8 +1714,8 @@ in the source distribution.

is Type.opaque().

-
-
Properties
+
+
Properties
type
@@ -1765,13 +1725,13 @@ in the source distribution.

on the returned type.

-
+
-

Values (llvm.core)

-

llvm.core.Value is the base class of all values computed by a program +

Values (llvm.core)

+

llvm.core.Value is the base class of all values computed by a program that may be used as operands to other values. A value has a type -associated with it (an object of llvm.core.Type).

-

The class hierarchy is:

+associated with it (an object of llvm.core.Type).

+

The class hierarchy is:

Value
@@ -1786,7 +1746,7 @@ associated with it (an object of llvm.core.Type).

SwitchInstruction BasicBlock
-

The Value class is abstract, it's not meant to be instantiated. +

The Value class is abstract, it's not meant to be instantiated. Constant-s represent constants that appear within code or as initializers of globals. They are constructed using static methods of Constant. The Constant class is covered in a separate section below. @@ -1795,12 +1755,12 @@ objects contain Argument objects, which represent the actual, local-variable-like arguments of the function (not to be confused with the arguments returned by a function type object — these represent the type of the arguments). The various Instruction-s are created by -the Builder class. These are also covered separately.

-

Value objects have a type (read-only), and a name (read-write).

+the Builder class. These are also covered separately.

+

Value objects have a type (read-only), and a name (read-write).

llvm.core.Value
-
Properties
+
Properties
name
@@ -1817,8 +1777,8 @@ the Builder class. These are also covered separately.

An llvm.core.Type object representing the type of the value.

-
-
Special Methods
+
+
Special Methods
__str__
@@ -1838,36 +1798,35 @@ the Builder class. These are also covered separately.

compares the resultant strings.

-
+
-

Constants (llvm.core)

-

Constant-s represents constants that appear within the code. The +

Constants (llvm.core)

+

Constant-s represents constants that appear within the code. The values of such objects are known at creation time. Constants can be created from Python constants. A constant expression is also a constant — given a Constant object, an operation (like addition, subtraction etc) can be specified, to yield a new Constant object. Let's see some -examples:

+examples:

-
#!/usr/bin/env python
 
-ti = Type.int()                         # a 32-bit int type
+ti = Type.int()                         # a 32-bit int type
 
-k1 = Constant.int(ti, 42)               # "int k1 = 42;"
-k2 = k1.add( Constant.int( ti, 10 ) )   # "int k2 = k1 + 10;"
+k1 = Constant.int(ti, 42)               # "int k1 = 42;"
+k2 = k1.add( Constant.int( ti, 10 ) )   # "int k2 = k1 + 10;"
 
-tr = Type.float()
+tr = Type.float()
 
-r1 = Constant.real(tr, "3.141592")      # create from a string
-r2 = Constant.real(tr, 1.61803399)      # create from a Python float
+r1 = Constant.real(tr, "3.141592")      # create from a string
+r2 = Constant.real(tr, 1.61803399)      # create from a Python float
 
-

The following constructors (static methods) can be used to create -constants:

-
- +

The following constructors (static methods) can be used to create +constants:

+
@@ -1991,12 +1950,11 @@ cellspacing="0" cellpadding="4">
-

The following operations on constants are supported. For more details on +

The following operations on constants are supported. For more details on any operation, consult the Constant Expressions -section of the LLVM Language Reference.

-
- +section of the LLVM Language Reference.

+
@@ -2304,8 +2262,8 @@ cellspacing="0" cellpadding="4">
-

Predicates for use with icmp instruction are listed below. All -of these are integer constants defined in the llvm.core module.

+

Predicates for use with icmp instruction are listed below. All +of these are integer constants defined in the llvm.core module.

-

Predicates for use with fcmp instruction are listed below. All -of these are integer constants defined in the llvm.core module.

+

Predicates for use with fcmp instruction are listed below. All +of these are integer constants defined in the llvm.core module.

llvm.core.Constant
-
Base Class
    +
    Base Class
    • llvm.core.Value

    • -
    -
    Static Constructors
    -

    See table of constructors above for full list.

    -
    Methods
    -

    See table of operations above for full list. There are no other -methods.

    +
+
Static Constructors

See table of constructors above for full list.

+
Methods

See table of operations above for full list. There are no other +methods.

-

Global Value (llvm.core)

-

The class llvm.core.GlobalValue represents module-scope aliases, variables +

Global Value (llvm.core)

+

The class llvm.core.GlobalValue represents module-scope aliases, variables and functions. Global variables are represented by the sub-class -llvm.core.GlobalVariable and functions by llvm.core.Function.

-

Global values have the read-write properties linkage, section, +llvm.core.GlobalVariable and functions by llvm.core.Function.

+

Global values have the read-write properties linkage, section, visibility and alignment. Use one of the following constants (from llvm.core) as values for linkage (see LLVM documentaion for -details on each):

+details on each):

-

The section property can be assigned strings (like ".rodata"), which +

The section property can be assigned strings (like ".rodata"), which will be used if the target supports it. Visibility property can be set to one of thse constants (from llvm.core, see also -LLVM docs):

+LLVM docs):

-

The alignment property can be 0 (default), or can be set to a power of +

The alignment property can be 0 (default), or can be set to a power of 2. The read-only property is_declaration can be used to check if the global is a declaration or not. The module to which the global belongs -to can be retrieved using the module property (read-only).

+to can be retrieved using the module property (read-only).

llvm.core.GlobalValue
-
Base Class
    +
    Base Class
    • llvm.core.Constant

    • -
    -
    Properties
    +
+
Properties
linkage
@@ -2787,75 +2743,75 @@ to can be retrieved using the module property (read-only).

The module object to which this global belongs to.

-
+
-

Global Variable (llvm.core)

-

Global variables (llvm.core.GlobalVariable) are subclasses of +

Global Variable (llvm.core)

+

Global variables (llvm.core.GlobalVariable) are subclasses of llvm.core.GlobalValue and represent module-level variables. These can have optional initializers and can be marked as constants. Global variables can be created either by using the add_global_variable method of the Module class (see above), or by using the static method -GlobalVariable.new.

+GlobalVariable.new.

-
# create a global variable using add_global_variable method
-gv1 = module_obj.add_global_variable(Type.int(), "gv1")
+gv1 = module_obj.add_global_variable(Type.int(), "gv1")
 
 # or equivalently, using a static constructor method
-gv2 = GlobalVariable.new(module_obj, Type.int(), "gv2")
+gv2 = GlobalVariable.new(module_obj, Type.int(), "gv2")
 
-

Existing global variables of a module can be accessed by name using +

Existing global variables of a module can be accessed by name using module_obj.get_global_variable_named(name) or GlobalVariable.get. All existing global variables can be enumerated via iterating over the -property module_obj.global_variables.

+property module_obj.global_variables.

-
# retrieve a reference to the global variable gv1,
 # using the get_global_variable_named method
-gv1 = module_obj.get_global_variable_named("gv1")
+gv1 = module_obj.get_global_variable_named("gv1")
 
 # or equivalently, using the static `get` method:
-gv2 = GlobalVariable.get(module_obj, "gv2")
+gv2 = GlobalVariable.get(module_obj, "gv2")
 
 # list all global variables in a module
-for gv in module_obj.global_variables:
+for gv in module_obj.global_variables:
     print gv.name, "of type", gv.type
 
-

The initializer for a global variable can be set by assigning to the +

The initializer for a global variable can be set by assigning to the initializer property of the object. The is_global_constant property -can be used to indicate that the variable is a global constant.

-

Global variables can be delete using the delete method. Do not use the -object after calling delete on it.

+can be used to indicate that the variable is a global constant.

+

Global variables can be delete using the delete method. Do not use the +object after calling delete on it.

-
# add an initializer 10 (32-bit integer)
-gv.initializer = Constant.int( Type.int(), 10 )
+gv.initializer = Constant.int( Type.int(), 10 )
 
 # delete the global
 gv.delete()
 # DO NOT dereference `gv' beyond this point!
-gv = None
+gv = None
 
llvm.core.GlobalVariable
-
Base Class
    +
    Base Class
    • llvm.core.GlobalValue

    • -
    -
    Static Constructors
    +
+
Static Constructors
new(module_obj, ty, name)
@@ -2875,8 +2831,8 @@ gv = None -
-
Properties
+
+
Properties
initializer
@@ -2894,8 +2850,8 @@ gv = NoneTrue
if the variable is a global constant, False otherwise.

-
-
Methods
+
+
Methods
delete()
@@ -2905,64 +2861,64 @@ gv = Nonedelete on it.

-
+
-

Function (llvm.core)

-

Functions are represented by llvm.core.Function objects. They are +

Function (llvm.core)

+

Functions are represented by llvm.core.Function objects. They are contained within modules, and can be created either with the method module_obj.add_function or the static constructor Function.new. References to functions already present in a module can be retrieved via module.get_function_named or by the static constructor method Function.get. All functions in a module can be enumerated by iterating -over module_obj.functions.

+over module_obj.functions.

-
# create a type, representing functions that take an integer and return
 # a floating point value.
-ft = Type.function( Type.float(), [ Type.int() ] )
+ft = Type.function( Type.float(), [ Type.int() ] )
 
 # create a function of this type
-f1 = module_obj.add_function(ft, "func1")
+f1 = module_obj.add_function(ft, "func1")
 
 # or equivalently, like this:
-f2 = Function.new(module_obj, ft, "func2")
+f2 = Function.new(module_obj, ft, "func2")
 
 # get a reference to an existing function
-f3 = module_obj.get_function_named("func3")
+f3 = module_obj.get_function_named("func3")
 
 # or like this:
-f4 = Function.get(module_obj, "func4")
+f4 = Function.get(module_obj, "func4")
 
 # list all function names in a module
-for f in module_obj.functions:
+for f in module_obj.functions:
     print f.name
 
-

References to intrinsic functions can be got via the static constructor +

References to intrinsic functions can be got via the static constructor intrinsic. This returns a Function object, calling which is equivalent to invoking the intrinsic. The intrinsic method has to be called with a module object, an instrinic ID (which is a numeric constant) and a list of the types of arguments (which LLVM uses to -resolve overloaded intrinsic functions).

+resolve overloaded intrinsic functions).

-
# get a reference to the llvm.bswap intrinsic
-bswap = Function.intrinsic(mod, INTR_BSWAP, [Type.int()])
+bswap = Function.intrinsic(mod, INTR_BSWAP, [Type.int()])
 
 # call it
 builder.call(bswap, [value])
 
-

Here, the constant INTR_BSWAP, available from llvm.core, represents +

Here, the constant INTR_BSWAP, available from llvm.core, represents the LLVM intrinsic llvm.bswap. The [Type.int()] selects the version of llvm.bswap that has a single 32-bit integer argument. The list of intrinsic IDs defined as integer constants -in llvm.core. These are:

+in llvm.core. These are:

INTR_ANNOTATION - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- INTR_DBG_STOPPOINT + INTR_ATOMIC_CMP_SWAP - INTR_MEMSET_I64 -
- INTR_ARM_THREAD_POINTER - - INTR_EH_DWARF_CFA - - INTR_PART_SELECT -
- INTR_ATOMIC_LAS - - INTR_EH_EXCEPTION - - INTR_PART_SET -
- INTR_ATOMIC_LCS - - INTR_EH_RETURN - - INTR_PCMARKER + INTR_ATOMIC_LOAD_ADD
INTR_ATOMIC_LOAD_AND - INTR_EH_SELECTOR_I32 - - INTR_POW -
INTR_ATOMIC_LOAD_MAX - INTR_EH_SELECTOR_I64 - - INTR_POWI -
INTR_ATOMIC_LOAD_MIN - INTR_EH_TYPEID_FOR_I32 - - INTR_PREFETCH -
+ INTR_ATOMIC_LOAD_NAND + INTR_ATOMIC_LOAD_OR - INTR_EH_TYPEID_FOR_I64 - - INTR_READCYCLECOUNTER + INTR_ATOMIC_LOAD_SUB
INTR_ATOMIC_LOAD_UMAX - INTR_EH_UNWIND_INIT - - INTR_RETURNADDRESS -
INTR_ATOMIC_LOAD_UMIN - INTR_FLT_ROUNDS - - INTR_SETJMP -
INTR_ATOMIC_LOAD_XOR - INTR_FRAMEADDRESS - - INTR_SIGLONGJMP -
- INTR_ATOMIC_LSS - - INTR_GCREAD - - INTR_SIGSETJMP -
INTR_ATOMIC_SWAP - INTR_GCROOT - - INTR_SIN -
INTR_BSWAP - INTR_GCWRITE - - INTR_SQRT -
INTR_COS - INTR_INIT_TRAMPOLINE - - INTR_STACKRESTORE -
INTR_CTLZ - INTR_LONGJMP - - INTR_STACKSAVE -
INTR_CTPOP - INTR_MEMCPY_I32 - - INTR_TRAP -
INTR_CTTZ - INTR_MEMCPY_I64 - - INTR_VACOPY -
INTR_DBG_DECLARE - INTR_MEMMOVE_I32 - - INTR_VAEND -
INTR_DBG_FUNC_START - INTR_MEMMOVE_I64 - - INTR_VAR_ANNOTATION -
INTR_DBG_REGION_END - INTR_MEMORY_BARRIER - - INTR_VASTART -
INTR_DBG_REGION_START + INTR_DBG_STOPPOINT + + INTR_EH_DWARF_CFA +
+ INTR_EH_EXCEPTION + + INTR_EH_RETURN_I32 + + INTR_EH_RETURN_I64 +
+ INTR_EH_SELECTOR_I32 + + INTR_EH_SELECTOR_I64 + + INTR_EH_TYPEID_FOR_I32 +
+ INTR_EH_TYPEID_FOR_I64 + + INTR_EH_UNWIND_INIT + + INTR_EXP +
+ INTR_EXP2 + + INTR_FLT_ROUNDS + + INTR_FRAMEADDRESS +
+ INTR_GCREAD + + INTR_GCROOT + + INTR_GCWRITE +
+ INTR_INIT_TRAMPOLINE + + INTR_LOG + + INTR_LOG10 +
+ INTR_LOG2 + + INTR_LONGJMP + + INTR_MEMCPY_I32 +
+ INTR_MEMCPY_I64 + + INTR_MEMMOVE_I32 + + INTR_MEMMOVE_I64 +
+ INTR_MEMORY_BARRIER + INTR_MEMSET_I32 - + INTR_MEMSET_I64 +
+ INTR_PART_SELECT + + INTR_PART_SET + + INTR_PCMARKER +
+ INTR_POW + + INTR_POWI + + INTR_PREFETCH +
+ INTR_READCYCLECOUNTER + + INTR_RETURNADDRESS + + INTR_SETJMP +
+ INTR_SIGLONGJMP + + INTR_SIGSETJMP + + INTR_SIN +
+ INTR_SQRT + + INTR_STACKRESTORE + + INTR_STACKSAVE +
+ INTR_TRAP + + INTR_VACOPY + + INTR_VAEND +
+ INTR_VAR_ANNOTATION + + INTR_VASTART +
-

There are also target-specific intrinsics (which correspond to that +

There are also target-specific intrinsics (which correspond to that target's CPU instructions) available, but are omitted here for brevity. Full list can be seen from core.py. @@ -3225,10 +3202,10 @@ for more information on the intrinsics, and the test directory in the source distribution for more examples. The intrinsic ID can be retrieved from a function object with the read-only property -intrinsic_id.

-

The function's calling convention can be set using the +intrinsic_id.

+

The function's calling convention can be set using the calling_convention property. The following (integer) constants defined -in llvm.core can be used as values:

+in llvm.core can be used as values:

-

See the LLVM docs for +

See the LLVM docs for more information on each. Backend-specific numbered conventions can be -directly set as numbers.

-

An arbitrary string identifying which garbage collector to use can be -set or got with the property collector.

-

The value objects corresponding to the arguments of a function can be +directly set as numbers.

+

An arbitrary string identifying which garbage collector to use can be +set or got with the property collector.

+

The value objects corresponding to the arguments of a function can be got using the read-only property args. These can be iterated over, and -also be indexed via integers. An example:

+also be indexed via integers. An example:

-
@@ -3309,7 +3286,7 @@ http://www.gnu.org/software/src-highlite --> # change the name of the first argument fn.args[0].name = "objptr"
-

Basic blocks (see later) are contained within functions. When newly +

Basic blocks (see later) are contained within functions. When newly created, a function has no basic blocks. They have to be added explicitly, using the append_basic_block method, which adds a new, empty basic block as the last one in the function. The first basic block @@ -3318,9 +3295,9 @@ method. The existing basic blocks can be enumerated by iterating over using the read-only property basic_blocks. The number of basic blocks can be got via basic_block_count method. Note that get_entry_basic_block is slightly faster than basic_blocks[0] and so -is basic_block_count, over len(f.basic_blocks).

+is basic_block_count, over len(f.basic_blocks).

-
@@ -3329,28 +3306,28 @@ b1 = fn. # get the first one b2 = fn.get_entry_basic_block() -b2 = fn.basic_blocks[0] # slower than previous method +b2 = fn.basic_blocks[0] # slower than previous method # print names of all basic blocks -for b in fn.basic_blocks: +for b in fn.basic_blocks: print b.name # get number of basic blocks -n = fn.basic_block_count -n = len(fn.basic_blocks) # slower than previous method +n = fn.basic_block_count +n = len(fn.basic_blocks) # slower than previous method
-

Functions can be deleted using the method delete. This deletes them +

Functions can be deleted using the method delete. This deletes them from their containing module. All references to the function object -should be dropped after delete has been called.

-

Functions can be verified with the verify method. This does not work -properly yet (aborts on errors), investigation pending.

-

Argument (llvm.core)

-

The args property of llvm.core.Function objects yields +should be dropped after delete has been called.

+

Functions can be verified with the verify method. This does not work +properly yet (aborts on errors), investigation pending.

+

Argument (llvm.core)

+

The args property of llvm.core.Function objects yields llvm.core.Argument objects. This allows for setting attributes for functions arguments. Argument objects cannot be constructed from user -code, the only way to get a reference to these are via functions.

-

The method add_attribute and remove_attribute can be used to add or -remove the following attributes:

+code, the only way to get a reference to these are via functions.

+

The method add_attribute and remove_attribute can be used to add or +remove the following attributes:

-

The corresponding +

The corresponding LLVM docs -provide more information.

-

The alignment of any parameter can also be set via set_argument(a) -where a is a power of 2.

-

Basic Block (llvm.core)

-

TODO

-

Builder (llvm.core)

-

TODO

-

Instructions (llvm.core)

-

TODO

-

Module Provider (llvm.core)

-

TODO

-

Target Data (llvm.ee)

-

TODO

-

Execution Engine (llvm.ee)

-

TODO. For now, see test/example-jit.py.

-

Pass Managers and Passes (llvm.passes)

-

TODO. For now, see test/passes.py.

+provide more information.

+

The alignment of any parameter can also be set via set_argument(a) +where a is a power of 2.

+

Basic Block (llvm.core)

+

TODO

+

Builder (llvm.core)

+

TODO

+

Instructions (llvm.core)

+

TODO

+

Module Provider (llvm.core)

+

TODO

+

Target Data (llvm.ee)

+

TODO

+

Execution Engine (llvm.ee)

+

TODO. For now, see test/example-jit.py.

+

Pass Managers and Passes (llvm.passes)

+

TODO. For now, see test/passes.py.

-

About the llvm-py Project

+

About the llvm-py Project

-

llvm-py lives at +

llvm-py lives at http://mdevan.nfshost.com/llvm-py/. The code (subversion repository) and the issue tracker are hosted on the Google code hosting service, at @@ -3489,21 +3466,21 @@ Google code hosting service, at It is distributed under the new BSD license, the full license text is in the file named LICENSE -available in the source distribution.

-

The entire llvm-py website is generated from marked up text files +available in the source distribution.

+

The entire llvm-py website is generated from marked up text files using the tool AsciiDoc. These text files and the (pre-)generated HTML pages are available in the source -distribution.

-

llvm-py is an ongoing, live project. Your contributions in any form +distribution.

+

llvm-py is an ongoing, live project. Your contributions in any form are most welcome. You can checkout the latest SVN HEAD from -here.

-

Mahadevan R wrote llvm-py and works on it in his spare time. He can be -reached at mdevan.foobar@gmail.com.

+here.

+

Mahadevan R wrote llvm-py and works on it in his spare time. He can be +reached at mdevan.foobar@gmail.com.