diff --git a/llvm/_core.c b/llvm/_core.c index 051159f..2b0748a 100644 --- a/llvm/_core.c +++ b/llvm/_core.c @@ -286,6 +286,8 @@ _wrap_objobj2obj(LLVMConstXor, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_intobjobj2obj(LLVMConstICmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_intobjobj2obj(LLVMConstFCmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_intobjobj2obj(LLVMConstVICmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_intobjobj2obj(LLVMConstVFCmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objobj2obj(LLVMConstShl, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objobj2obj(LLVMConstLShr, LLVMValueRef, LLVMValueRef, LLVMValueRef) @@ -435,6 +437,7 @@ _wrap_obj2none(LLVMDisposeBuilder, LLVMBuilderRef) _wrap_obj2obj(LLVMBuildRetVoid, LLVMBuilderRef, LLVMValueRef) _wrap_objobj2obj(LLVMBuildRet, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objlist2obj(LLVMBuildRetMultiple, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) _wrap_objobj2obj(LLVMBuildBr, LLVMBuilderRef, LLVMBasicBlockRef, LLVMValueRef) _wrap_objobjobjobj2obj(LLVMBuildCondBr, LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMBasicBlockRef, LLVMValueRef) _wrap_objobjobjint2obj(LLVMBuildSwitch, LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMValueRef) @@ -527,9 +530,12 @@ _wrap_objobjobjstr2obj(LLVMBuildBitCast, LLVMBuilderRef, LLVMValueRef, LLVMTypeR _wrap_objintobjobjstr2obj(LLVMBuildICmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objintobjobjstr2obj(LLVMBuildFCmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objintobjobjstr2obj(LLVMBuildVICmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objintobjobjstr2obj(LLVMBuildVFCmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) /* Miscellaneous instructions */ +_wrap_objobjintstr2obj(LLVMBuildGetResult, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) _wrap_objobjstr2obj(LLVMBuildPhi, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) _wrap_objobjliststr2obj(LLVMBuildCall, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) _wrap_objobjobjobjstr2obj(LLVMBuildSelect, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) @@ -837,6 +843,8 @@ static PyMethodDef core_methods[] = { _method( LLVMConstXor ) _method( LLVMConstICmp ) _method( LLVMConstFCmp ) + _method( LLVMConstVICmp ) + _method( LLVMConstVFCmp ) _method( LLVMConstShl ) _method( LLVMConstLShr ) _method( LLVMConstAShr ) @@ -947,6 +955,7 @@ static PyMethodDef core_methods[] = { /* Terminators */ _method( LLVMBuildRetVoid ) _method( LLVMBuildRet ) + _method( LLVMBuildRetMultiple ) _method( LLVMBuildBr ) _method( LLVMBuildCondBr ) _method( LLVMBuildSwitch ) @@ -1003,8 +1012,11 @@ static PyMethodDef core_methods[] = { /* Comparisons */ _method( LLVMBuildICmp ) _method( LLVMBuildFCmp ) + _method( LLVMBuildVICmp ) + _method( LLVMBuildVFCmp ) /* Miscellaneous instructions */ + _method( LLVMBuildGetResult ) _method( LLVMBuildPhi ) _method( LLVMBuildCall ) _method( LLVMBuildSelect ) diff --git a/llvm/core.py b/llvm/core.py index 34db34b..fed02f8 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -660,6 +660,10 @@ class Constant(Value): check_is_constant(rhs) return Constant(_core.LLVMConstSRem(self.ptr, rhs.ptr)) + def frem(self, rhs): + check_is_constant(rhs) + return Constant(_core.LLVMConstFRem(self.ptr, rhs.ptr)) + def and_(self, rhs): check_is_constant(rhs) return Constant(_core.LLVMConstAnd(self.ptr, rhs.ptr)) @@ -674,11 +678,19 @@ class Constant(Value): def icmp(self, int_pred, rhs): check_is_constant(rhs) - return Constant(_core.LLVMConstICmp(self.ptr, int_pred, rhs.ptr)) + return Constant(_core.LLVMConstICmp(int_pred, self.ptr, rhs.ptr)) def fcmp(self, real_pred, rhs): check_is_constant(rhs) - return Constant(_core.LLVMConstFCmp(self.ptr, real_pred, rhs.ptr)) + return Constant(_core.LLVMConstFCmp(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) @@ -749,16 +761,16 @@ class Constant(Value): check_is_constant(false_const) return Constant(_core.LLVMConstSelect(self.ptr, true_const.ptr, false_const.ptr)) - def extract(self, index): # note: self must be a _vector_ constant + def extract_element(self, index): # note: self must be a _vector_ constant check_is_constant(index) return Constant(_core.LLVMConstExtractElement(self.ptr, index.ptr)) - def insert(self, value, index): # note: self must be a _vector_ constant + def insert_element(self, value, index): # note: self must be a _vector_ constant check_is_constant(value) check_is_constant(index) return Constant(_core.LLVMConstInsertElement(self.ptr, value.ptr, index.ptr)) - def shuffle(self, vector_b, mask): # note: self must be a _vector_ constant + def shuffle_element(self, vector_b, mask): # note: self must be a _vector_ constant check_is_constant(vector_b) # note: vector_b must be a _vector_ constant check_is_constant(mask) return Constant(_core.LLVMConstShuffleVector(self.ptr, vector_b.ptr, mask.ptr)) @@ -1035,11 +1047,15 @@ class Builder(object): def ret_void(self): return Instruction(_core.LLVMBuildRetVoid(self.ptr)) - + def ret(self, value): check_is_value(value) return Instruction(_core.LLVMBuildRet(self.ptr, value.ptr)) - + + def ret_many(self, values): + vs = unpack_values(values) + return Instruction(_core.LLVMBuildRetMultiple(self.ptr, vs)) + def branch(self, bblk): check_is_basic_block(bblk) return Instruction(_core.LLVMBuildBr(self.ptr, bblk.ptr)) @@ -1265,8 +1281,22 @@ class Builder(object): check_is_value(rhs) return Value(_core.LLVMBuildFCmp(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 + def getresult(self, retval, idx, name=""): + check_is_value(retval) + return PHINode(_core.LLVMBuildGetResult(self.ptr, retval.ptr, idx, name)) + def phi(self, ty, name=""): check_is_type(ty) return PHINode(_core.LLVMBuildPhi(self.ptr, ty.ptr, name)) diff --git a/llvm/extra.cpp b/llvm/extra.cpp index f8a5fa4..e54741b 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -41,3 +41,45 @@ char *LLVMDumpValueToString(LLVMValueRef Val) { return strdup(buf.str().c_str()); } +LLVMValueRef LLVMConstVICmp(LLVMIntPredicate Predicate, + LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getVICmp(Predicate, + unwrap(LHSConstant), + unwrap(RHSConstant))); +} + +LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate Predicate, + LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getVFCmp(Predicate, + unwrap(LHSConstant), + unwrap(RHSConstant))); +} + +LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef B, LLVMValueRef *Values, + unsigned NumValues) { + std::vector Vs; + for (LLVMValueRef *I = Values, *E = Values + NumValues; I != E; ++I) + Vs.push_back(unwrap(*I)); + + return wrap(unwrap(B)->CreateRet(&Vs[0], NumValues)); +} + +LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef B, LLVMIntPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateVICmp(static_cast(Op), + unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef B, LLVMRealPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateVFCmp(static_cast(Op), + unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef B, LLVMValueRef V, + unsigned Index, const char *Name) { + return wrap(unwrap(B)->CreateGetResult(unwrap(V), Index, Name)); +} + diff --git a/llvm/extra.h b/llvm/extra.h index 2b463e0..b405cf4 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -23,6 +23,26 @@ char *LLVMDumpTypeToString(LLVMTypeRef Ty); LLVMDisposeMessage, after use. */ char *LLVMDumpValueToString(LLVMValueRef Val); +/* missing constant expressions */ + +LLVMValueRef LLVMConstVICmp(LLVMIntPredicate Predicate, + LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); +LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate Predicate, + LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); + +/* missing instructions */ + +LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef, LLVMValueRef *Values, + unsigned NumValues); +LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef, LLVMIntPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef, LLVMRealPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef, LLVMValueRef V, + unsigned Index, const char *Name); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/llvm/wrap.h b/llvm/wrap.h index 7be34b6..3f8ffdf 100644 --- a/llvm/wrap.h +++ b/llvm/wrap.h @@ -464,6 +464,29 @@ _w ## func (PyObject *self, PyObject *args) \ } +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, int arg3, const char *arg4) + */ +#define _wrap_objobjintstr2obj(func, intype1, intype2, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 arg2; \ + int arg3; \ + const char *arg4; \ + \ + if (!PyArg_ParseTuple(args, "OOis", &obj1, &obj2, &arg3, &arg4)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4)) ;\ +} + /** * Wrap LLVM functions of the type * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, const char *arg4) diff --git a/www/src/about.txt b/www/src/about.txt index c0a10b1..5cbda80 100644 --- a/www/src/about.txt +++ b/www/src/about.txt @@ -5,6 +5,5 @@ 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). -Many thanks to the guys over at LLVM for all the nifty software, and a -helpful mailing list. +Many thanks to the guys over at LLVM for all the nifty software. diff --git a/www/src/instrset.inc b/www/src/instrset.inc new file mode 100644 index 0000000..ade818c --- /dev/null +++ b/www/src/instrset.inc @@ -0,0 +1,118 @@ +.LLVM Instruction Set + +[frame="all",grid="all"] +`30`70~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Category, Instructions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Terminator instructions,\ +"http://www.llvm.org/docs/LangRef.html#i_ret[ret], \ +http://www.llvm.org/docs/LangRef.html#i_br[br], \ +http://www.llvm.org/docs/LangRef.html#i_switch[switch], \ +http://www.llvm.org/docs/LangRef.html#i_invoke[invoke], \ +http://www.llvm.org/docs/LangRef.html#i_unwind[unwind], \ +http://www.llvm.org/docs/LangRef.html#i_unreachable[unreachable]" +Binary operations,\ +"http://www.llvm.org/docs/LangRef.html#i_add[add], \ +http://www.llvm.org/docs/LangRef.html#i_sub[sub], \ +http://www.llvm.org/docs/LangRef.html#i_mul[mul], \ +http://www.llvm.org/docs/LangRef.html#i_udiv[udiv], \ +http://www.llvm.org/docs/LangRef.html#i_sdiv[sdiv], \ +http://www.llvm.org/docs/LangRef.html#i_fdiv[fdiv], \ +http://www.llvm.org/docs/LangRef.html#i_urem[urem], \ +http://www.llvm.org/docs/LangRef.html#i_srem[srem], \ +http://www.llvm.org/docs/LangRef.html#i_frem[frem]" +Bitwise binary operations,\ +"http://www.llvm.org/docs/LangRef.html#i_shl[shl], \ +http://www.llvm.org/docs/LangRef.html#i_lshr[lshr], \ +http://www.llvm.org/docs/LangRef.html#i_ashr[ashr], \ +http://www.llvm.org/docs/LangRef.html#i_and[and], \ +http://www.llvm.org/docs/LangRef.html#i_or[or], \ +http://www.llvm.org/docs/LangRef.html#i_xor[xor]" +Vector operations,\ +"http://www.llvm.org/docs/LangRef.html#i_extractelement[extractelement], \ +http://www.llvm.org/docs/LangRef.html#i_insertelement[insertelement], \ +http://www.llvm.org/docs/LangRef.html#i_shufflevector[shufflevector]" +Aggregate operations,\ +"http://www.llvm.org/docs/LangRef.html#i_extractvalue[extractvalue], \ +http://www.llvm.org/docs/LangRef.html#i_insertvalue[insertvalue]" +Memory access and addressing operations,\ +"http://www.llvm.org/docs/LangRef.html#i_malloc[malloc], \ +http://www.llvm.org/docs/LangRef.html#i_free[free], \ +http://www.llvm.org/docs/LangRef.html#i_alloca[alloca], \ +http://www.llvm.org/docs/LangRef.html#i_load[load], \ +http://www.llvm.org/docs/LangRef.html#i_store[store], \ +http://www.llvm.org/docs/LangRef.html#i_getelementptr[getelementptr]" +Conversion operations,\ +"http://www.llvm.org/docs/LangRef.html#i_trunc[trunc], \ +http://www.llvm.org/docs/LangRef.html#i_zext[zext], \ +http://www.llvm.org/docs/LangRef.html#i_sext[sext], \ +http://www.llvm.org/docs/LangRef.html#i_fptrunc[fptrunc], \ +http://www.llvm.org/docs/LangRef.html#i_fpext[fpext], \ +http://www.llvm.org/docs/LangRef.html#i_fptoui[fptoui], \ +http://www.llvm.org/docs/LangRef.html#i_fptosi[fptosi], \ +http://www.llvm.org/docs/LangRef.html#i_uitofp[uitofp], \ +http://www.llvm.org/docs/LangRef.html#i_sitofp[sitofp], \ +http://www.llvm.org/docs/LangRef.html#i_ptrtoint[ptrtoint], \ +http://www.llvm.org/docs/LangRef.html#i_inttoptr[inttoptr], \ +http://www.llvm.org/docs/LangRef.html#i_bitcast[bitcast]" +Other operations,\ +"http://www.llvm.org/docs/LangRef.html#i_icmp[icmp], \ +http://www.llvm.org/docs/LangRef.html#i_fcmp[fcmp], \ +http://www.llvm.org/docs/LangRef.html#i_vicmp[vicmp], \ +http://www.llvm.org/docs/LangRef.html#i_vfcmp[vfcmp], \ +http://www.llvm.org/docs/LangRef.html#i_phi[phi], \ +http://www.llvm.org/docs/LangRef.html#i_select[select], \ +http://www.llvm.org/docs/LangRef.html#i_call[call], \ +http://www.llvm.org/docs/LangRef.html#i_va_arg[va_arg], \ +http://www.llvm.org/docs/LangRef.html#i_getresult[getresult]" +Variable argument handling intrinsics,\ +"http://www.llvm.org/docs/LangRef.html#int_va_start[llvm.va_start], \ +http://www.llvm.org/docs/LangRef.html#int_va_end[llvm.va_end], \ +http://www.llvm.org/docs/LangRef.html#int_va_copy[llvm.va_copy]" +Accurate garbage collection intrinsics,\ +"http://www.llvm.org/docs/LangRef.html#int_returnaddress[llvm.returnaddress], \ +http://www.llvm.org/docs/LangRef.html#int_frameaddress[llvm.frameaddress], \ +http://www.llvm.org/docs/LangRef.html#int_stacksave[llvm.stacksave], \ +http://www.llvm.org/docs/LangRef.html#int_stackrestore[llvm.stackrestore], \ +http://www.llvm.org/docs/LangRef.html#int_prefetch[llvm.prefetch], \ +http://www.llvm.org/docs/LangRef.html#int_pcmarker[llvm.pcmarker], \ +http://www.llvm.org/docs/LangRef.html#int_readcyclecounter[llvm.readcyclecounter]" +Standard C library intrinsics,\ +"http://www.llvm.org/docs/LangRef.html#int_memcpy[llvm.memcpy.\*], \ +http://www.llvm.org/docs/LangRef.html#int_memmove[llvm.memmove.\*], \ +http://www.llvm.org/docs/LangRef.html#int_memset[llvm.memset.\*], \ +http://www.llvm.org/docs/LangRef.html#int_sqrt[llvm.sqrt.\*], \ +http://www.llvm.org/docs/LangRef.html#int_powi[llvm.powi.\*], \ +http://www.llvm.org/docs/LangRef.html#int_sin[llvm.sin.\*], \ +http://www.llvm.org/docs/LangRef.html#int_cos[llvm.cos.\*], \ +http://www.llvm.org/docs/LangRef.html#int_pow[llvm.pow.\*]" +Bit manipulation intrinsics,\ +"http://www.llvm.org/docs/LangRef.html#int_bswap[llvm.bswap.\*], \ +http://www.llvm.org/docs/LangRef.html#int_ctpop[llvm.ctpop.\*], \ +http://www.llvm.org/docs/LangRef.html#int_ctlz[llvm.ctlz.\*], \ +http://www.llvm.org/docs/LangRef.html#int_cttz[llvm.cttz.\*], \ +http://www.llvm.org/docs/LangRef.html#int_part_select[llvm.part.select.\*], \ +http://www.llvm.org/docs/LangRef.html#int_part_set[llvm.part.set.\*]" +Debugger intrinsics,\ +"http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_stoppoint[llvm.dbg.stoppoint], \ +http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_func_start[llvm.dbg.func.start], \ +http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_region_start[llvm.dbg.region.start], \ +http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_region_end[llvm.dbg.region.end], \ +http://www.llvm.org/docs/SourceLevelDebugging.html#format_common_declare[llvm.dbg.declare]" +Exception handling intrinsics,\ +"http://www.llvm.org/docs/ExceptionHandling.html#llvm_eh_exception[llvm.eh_exception], \ +http://www.llvm.org/docs/ExceptionHandling.html#llvm_eh_selector[llvm.eh_selector], \ +http://www.llvm.org/docs/ExceptionHandling.html#llvm_eh_typeid_for[llvm.eh_typeid_for]" +Trampoline intrinsics,\ +"http://www.llvm.org/docs/LangRef.html#int_it[llvm.init.trampoline]" +Atomic intrinsics,\ +"http://www.llvm.org/docs/LangRef.html#int_memory_barrier[llvm.memory.barrier], \ +http://www.llvm.org/docs/LangRef.html#int_atomic_lcs[llvm.atomic.lcs], \ +http://www.llvm.org/docs/LangRef.html#int_atomic_las[llvm.atomic.las], \ +http://www.llvm.org/docs/LangRef.html#int_atomic_swap[llvm.atomic.swap]" +General intrinsics,\ +"http://www.llvm.org/docs/LangRef.html#int_var_annotation[llvm.var.annotation], \ +http://www.llvm.org/docs/LangRef.html#int_annotation[llvm.annotation.\*], \ +http://www.llvm.org/docs/LangRef.html#int_trap[llvm.trap]" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + diff --git a/www/src/layout.conf b/www/src/layout.conf index f18fd08..ec0f087 100644 --- a/www/src/layout.conf +++ b/www/src/layout.conf @@ -78,5 +78,14 @@ Last updated {localdate}. + + diff --git a/www/src/license.txt b/www/src/license.txt index c1938ad..e40da20 100644 --- a/www/src/license.txt +++ b/www/src/license.txt @@ -1,9 +1,9 @@ License ======= -_llvm-py_ is distributed under the +llvm-py is distributed under the http://www.opensource.org/licenses/bsd-license.php[new BSD license]. -This is similar to LLVM's license. You should be able to use _llvm-py_ +This is similar to LLVM's license. You should be able to use llvm-py where-ever and how-ever you're able to use LLVM itself. The license text is present in the diff --git a/www/src/userguide.txt b/www/src/userguide.txt index b613398..b590284 100644 --- a/www/src/userguide.txt +++ b/www/src/userguide.txt @@ -167,11 +167,6 @@ instructions related to variable argument handling, exception handling, and garbage collection. These allow high-level languages to be represented cleanly in the IR. -The full set of instructions are: - -TODO - - SSA Form and PHI Nodes ~~~~~~~~~~~~~~~~~~~~~~ @@ -217,7 +212,7 @@ 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) (XXX ?) + 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 @@ -227,27 +222,62 @@ The http://www.llvm.org/demo/[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. -Here's a function in C, that calculates the sum of the first _n_ -fibonacci numbers: +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): [C] source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -int fibsum(int n) +/* compute sum of 1..n */ +unsigned sum(unsigned n) { + if (n == 0) + return 0; + else + return n + sum(n-1); } source~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -And here's the corresponding LLVM assembly listing, as provided by the -demo page: +The corresponding LLVM assembly: ----- ----- +----------------------------------------------------------------------- +; ModuleID = '/tmp/webcompile/_4940_0.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i386-pc-linux-gnu" -Note the ... TODO ... +define i32 @sum(i32 %n) nounwind { +entry: + %tmp215 = icmp eq i32 %n, 0 ; [#uses=1] + br i1 %tmp215, label %bb10, label %tailrecurse.bb10_crit_edge + +tailrecurse.bb10_crit_edge: ; preds = %entry + %tmp = add i32 %n, -1 ; [#uses=3] + %tmp17 = mul i32 %tmp, %tmp ; [#uses=1] + %tmp18 = add i32 %tmp17, %n ; [#uses=1] + %tmp. = zext i32 %tmp to i64 ; [#uses=2] + %tmp19 = add i64 %tmp., -1 ; [#uses=1] + %tmp20 = mul i64 %tmp19, %tmp. ; [#uses=1] + %tmp21 = lshr i64 %tmp20, 1 ; [#uses=1] + %tmp.22 = trunc i64 %tmp21 to i32 ; [#uses=1] + %tmp24 = sub i32 %tmp18, %tmp.22 ; [#uses=1] + ret i32 %tmp24 + +bb10: ; preds = %entry + ret i32 0 +} +----------------------------------------------------------------------- + +Note the usage of SSA form and the total absence of any loop or +recursion at all! The http://www.llvm.org/docs/LangRef.html[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. +include::instrset.inc[] + +Intrinsics (instructions that start with +llvm.+) are not yet available +in llvm-py. Modules ~~~~~~~ @@ -288,8 +318,7 @@ 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.) -Passes are run using a _pass manager_. For our purposes, there are two -pass managers TODO +Passes are run using a _pass manager_. TODO Execution Engine @@ -331,9 +360,10 @@ The modules contain only classes and (integer) constants. Mostly simple Python constructs are used (deliberately) -- http://docs.python.org/lib/built-in-funcs.html[property()] and http://wiki.python.org/moin/PythonDecoratorLibrary[property -decorators] are probably the most exotic animals around. The APIs are -designed to be navigable (and guessable!) once you know a few -conventions. These conventions are highlighted in the sections below. +decorators] are probably the most exotic animals around. All classes are +the "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: @@ -426,8 +456,46 @@ a Module object. This is a common feature for all llvm-py classes. corresponding classes. Constructors _should not_ be used. ======================================================================= -The argument 'my_module' is a module identifier (a plain string). +The argument `my_module` is a module identifier (a plain string). The +attributes of the `Module` class is: +.llvm.core.Module +[caption=""] +======================================================================= +.Static Constructors +`new(module_id)`:: + create a new `Module` instance with given `module_id`. The `module_id` + should be a string. + +.Properties +`data_layout` (r/w):: + a string representing the ABI of the platform +`target` (r/w):: + a string like `i386-pc-linux-gnu` or `i386-pc-solaris2.8` +`global_variables` (r):: + TODO +`functions` (r):: + TODO + +.Methods +`add_type_name`:: + TODO +`delete_type_name`:: + TODO +`add_global_variable`:: + TODO +`get_global_variable_named`:: + TODO + +.Special Methods +`\_\_str\_\_`:: + Module objects can be stringified into it's LLVM assembly language + representation. +`\_\_eq\_\_`:: + Module objects can be compared for equality. Internally, this + converts both into their LLVM assembly representations and compares + them. +======================================================================= Types (llvm.core) ~~~~~~~~~~~~~~~~~ @@ -466,6 +534,16 @@ label, +Type.label()+, +Type+ opaque, +Type.opaque()+, +Type+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The class hierarchy is: +----------------------------------------------------------------------- +Type + IntegerType + FunctionType + StructType + ArrayType + PointerType + VectorType +----------------------------------------------------------------------- Values (llvm.core) ~~~~~~~~~~~~~~~~~ diff --git a/www/web/about.html b/www/web/about.html index 6019c23..508a036 100644 --- a/www/web/about.html +++ b/www/web/about.html @@ -38,19 +38,27 @@

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

-

Many thanks to the guys over at LLVM for all the nifty software, and a -helpful mailing list.

+

Many thanks to the guys over at LLVM for all the nifty software.

+ + diff --git a/www/web/contribute.html b/www/web/contribute.html index 5123fbb..a8ecef7 100644 --- a/www/web/contribute.html +++ b/www/web/contribute.html @@ -91,5 +91,14 @@ Last updated 10-Jun-2008. + + diff --git a/www/web/download.html b/www/web/download.html index 29846e3..f14a930 100644 --- a/www/web/download.html +++ b/www/web/download.html @@ -107,7 +107,7 @@ package.

-
0.2, ongoing:
+
0.2, xx-Jun-2008:
 
   * Independent package, need not be unpacked into llvm/bindings
   * Fixed ownership issues with Module/ModuleProvider
@@ -126,7 +126,6 @@ package.

* Initial release. -
@@ -140,5 +139,14 @@ Last updated 10-Jun-2008. + + diff --git a/www/web/examples.html b/www/web/examples.html index 4640e3f..a2f3cef 100644 --- a/www/web/examples.html +++ b/www/web/examples.html @@ -110,5 +110,14 @@ Last updated 10-Jun-2008. + + diff --git a/www/web/index.html b/www/web/index.html index 9dae87d..80126bc 100644 --- a/www/web/index.html +++ b/www/web/index.html @@ -67,5 +67,14 @@ Last updated 10-Jun-2008. + + diff --git a/www/web/license.html b/www/web/license.html index fb3aaed..c33da95 100644 --- a/www/web/license.html +++ b/www/web/license.html @@ -35,9 +35,9 @@
-

llvm-py is distributed under the +

llvm-py is distributed under the new BSD license. -This is similar to LLVM's license. You should be able to use llvm-py +This is similar to LLVM's license. You should be able to use llvm-py where-ever and how-ever you're able to use LLVM itself.

The license text is present in the LICENSE @@ -76,12 +76,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ + diff --git a/www/web/userguide.html b/www/web/userguide.html index a82d02e..068a2ff 100644 --- a/www/web/userguide.html +++ b/www/web/userguide.html @@ -224,8 +224,6 @@ 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.

-

The full set of instructions are:

-

TODO

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 @@ -261,7 +259,7 @@ 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) (XXX ?) + 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 @@ -269,26 +267,215 @@ 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.

-

Here's a function in C, that calculates the sum of the first n -fibonacci numbers:

+

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

-
int fibsum(int n)
+
/* compute sum of 1..n */
+unsigned sum(unsigned n)
 {
+  if (n == 0)
+    return 0;
+  else
+    return n + sum(n-1);
 }
 
-

And here's the corresponding LLVM assembly listing, as provided by the -demo page:

+

The corresponding LLVM assembly:

-
+
; ModuleID = '/tmp/webcompile/_4940_0.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i386-pc-linux-gnu"
+
+define i32 @sum(i32 %n) nounwind  {
+entry:
+        %tmp215 = icmp eq i32 %n, 0             ; <i1> [#uses=1]
+        br i1 %tmp215, label %bb10, label %tailrecurse.bb10_crit_edge
+
+tailrecurse.bb10_crit_edge:             ; preds = %entry
+        %tmp = add i32 %n, -1           ; <i32> [#uses=3]
+        %tmp17 = mul i32 %tmp, %tmp             ; <i32> [#uses=1]
+        %tmp18 = add i32 %tmp17, %n             ; <i32> [#uses=1]
+        %tmp. = zext i32 %tmp to i64            ; <i64> [#uses=2]
+        %tmp19 = add i64 %tmp., -1              ; <i64> [#uses=1]
+        %tmp20 = mul i64 %tmp19, %tmp.          ; <i64> [#uses=1]
+        %tmp21 = lshr i64 %tmp20, 1             ; <i64> [#uses=1]
+        %tmp.22 = trunc i64 %tmp21 to i32               ; <i32> [#uses=1]
+        %tmp24 = sub i32 %tmp18, %tmp.22                ; <i32> [#uses=1]
+        ret i32 %tmp24
+
+bb10:           ; preds = %entry
+        ret i32 0
+}
-

Note the … TODO …

+

Note the usage of SSA form and the total absence of any loop or +recursion at all!

The LLVM Language Reference -defines the LLVM assembly language including the entire instruction set.

+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.

+
+ + +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table: LLVM Instruction Set
+ Category + + Instructions +
+ Terminator instructions + + ret, br, switch, invoke, unwind, unreachable +
+ Binary operations + + add, sub, mul, udiv, sdiv, fdiv, urem, srem, frem +
+ Bitwise binary operations + + shl, lshr, ashr, and, or, xor +
+ Vector operations + + extractelement, insertelement, shufflevector +
+ Aggregate operations + + extractvalue, insertvalue +
+ Memory access and addressing operations + + malloc, free, alloca, load, store, getelementptr +
+ Conversion operations + + trunc, zext, sext, fptrunc, fpext, fptoui, fptosi, uitofp, sitofp, ptrtoint, inttoptr, bitcast +
+ Other operations + + icmp, fcmp, vicmp, vfcmp, phi, select, call, va_arg, getresult +
+ Variable argument handling intrinsics + + llvm.va_start, llvm.va_end, llvm.va_copy +
+ Accurate garbage collection intrinsics + + llvm.returnaddress, llvm.frameaddress, llvm.stacksave, llvm.stackrestore, llvm.prefetch, llvm.pcmarker, llvm.readcyclecounter +
+ Standard C library intrinsics + + llvm.memcpy.*, llvm.memmove.*, llvm.memset.*, llvm.sqrt.*, llvm.powi.*, llvm.sin.*, llvm.cos.*, llvm.pow.* +
+ Bit manipulation intrinsics + + llvm.bswap.*, llvm.ctpop.*, llvm.ctlz.*, llvm.cttz.*, llvm.part.select.*, llvm.part.set.* +
+ Debugger intrinsics + + llvm.dbg.stoppoint, llvm.dbg.func.start, llvm.dbg.region.start, llvm.dbg.region.end, llvm.dbg.declare +
+ Exception handling intrinsics + + llvm.eh_exception, llvm.eh_selector, llvm.eh_typeid_for +
+ Trampoline intrinsics + + llvm.init.trampoline +
+ Atomic intrinsics + + llvm.memory.barrier, llvm.atomic.lcs, llvm.atomic.las, llvm.atomic.swap +
+ General intrinsics + + llvm.var.annotation, llvm.annotation.*, llvm.trap +
+
+

Intrinsics (instructions that start with llvm.) are not yet available +in llvm-py.

Modules

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

@@ -330,8 +517,7 @@ 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.)

-

Passes are run using a pass manager. For our purposes, there are two -pass managers TODO

+

Passes are run using a pass manager. TODO

Execution Engine

TODO

BitCode

@@ -374,9 +560,10 @@ public modules. These are:

Python constructs are used (deliberately) — property() and property -decorators are probably the most exotic animals around. The APIs are -designed to be navigable (and guessable!) once you know a few -conventions. These conventions are highlighted in the sections below.

+decorators are probably the most exotic animals around. All classes are +the "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
  • @@ -559,7 +746,112 @@ corresponding classes. Constructors should not be used.

-

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

+

The argument my_module is a module identifier (a plain string). The +attributes of the Module class is:

+
+
llvm.core.Module
+
+
Static Constructors
+
+new(module_id) +
+
+

+ create a new Module instance with given module_id. The module_id + should be a string. +

+
+
+
Properties
+
+data_layout (r/w) +
+
+

+ a string representing the ABI of the platform +

+
+
+target (r/w) +
+
+

+ a string like i386-pc-linux-gnu or i386-pc-solaris2.8 +

+
+
+global_variables (r) +
+
+

+ TODO +

+
+
+functions (r) +
+
+

+ TODO +

+
+
+
Methods
+
+add_type_name +
+
+

+ TODO +

+
+
+delete_type_name +
+
+

+ TODO +

+
+
+add_global_variable +
+
+

+ TODO +

+
+
+get_global_variable_named +
+
+

+ TODO +

+
+
+
Special Methods
+
+__str__ +
+
+

+ Module objects can be stringified into it's LLVM assembly language + representation. +

+
+
+__eq__ +
+
+

+ Module objects can be compared for equality. Internally, this + converts both into their LLVM assembly representations and compares + them. +

+
+
+

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 @@ -761,6 +1053,17 @@ cellspacing="0" cellpadding="4"> +

The class hierarchy is:

+
+
+
Type
+  IntegerType
+  FunctionType
+  StructType
+  ArrayType
+  PointerType
+  VectorType
+

Values (llvm.core)

TODO

Instructions (llvm.core)

@@ -806,12 +1109,21 @@ reached at mdevan.foobar@gmail.com.

+ +