# HG changeset patch # User Frits van Bommel # Date 1240864476 -7200 # Node ID 4ff9ab0d472c24ed2ad1e3ab529c78b881d52931 # Parent 1ba61de8796b093c5d704fa877ccf9cffaf3cc5b Check in some old changes to the binding, from before I had commit access. - Add bindings for InsertValue and ExtractValue - Updates to use new APIs where they were renamed or removed. - Add generic error messages if LLVM didn't provide one. - Enable typesafe variadic arguments for GetGEP. diff -r 1ba61de8796b -r 4ff9ab0d472c tools/binding/llvm-typemonitor.cpp --- a/tools/binding/llvm-typemonitor.cpp Mon Apr 27 22:33:17 2009 +0200 +++ b/tools/binding/llvm-typemonitor.cpp Mon Apr 27 22:34:36 2009 +0200 @@ -1,5 +1,6 @@ /// Support for callbacks when an abstract type becomes more concrete. +#include "llvm/Support/Streams.h" #include "llvm/Type.h" #include "llvm-c/Core.h" diff -r 1ba61de8796b -r 4ff9ab0d472c tools/binding/llvm/builder.d --- a/tools/binding/llvm/builder.d Mon Apr 27 22:33:17 2009 +0200 +++ b/tools/binding/llvm/builder.d Mon Apr 27 22:34:36 2009 +0200 @@ -72,6 +72,12 @@ template Build_Value_Value_Value_Name(char[] N) { const Build_Value_Value_Value_Name = Build_Named_Mixin!(N, "Value a, Value b, Value c", `a.value, b.value, c.value`); } + template Build_Value_uint_Name(char[] N) { + const Build_Value_uint_Name = Build_Named_Mixin!(N, "Value a, uint n", `a.value, n`); + } + template Build_Value_Value_uint_Name(char[] N) { + const Build_Value_Value_uint_Name = Build_Named_Mixin!(N, "Value a, Value b, uint n", `a.value, b.value, n`); + } template Build_Cmp(char[] PRED, char[] N) { const Build_Cmp = Build_Named_Mixin!(N, ""~PRED~"Predicate p, Value l, Value r", `p, l.value, r.value`); } @@ -172,6 +178,10 @@ "Select", "InsertElement", "ShuffleVector" )); /// + mixin(Build_Value_uint_Name!("ExtractValue")); + /// + mixin(Build_Value_Value_uint_Name!("InsertValue")); + /// Value buildCall(Value fn, Value[] args, char[] name) { auto llargs = new LLVMValueRef[args.length]; foreach(i,a; args) llargs[i] = a.value; diff -r 1ba61de8796b -r 4ff9ab0d472c tools/binding/llvm/c/Core.d --- a/tools/binding/llvm/c/Core.d Mon Apr 27 22:33:17 2009 +0200 +++ b/tools/binding/llvm/c/Core.d Mon Apr 27 22:34:36 2009 +0200 @@ -1,4 +1,5 @@ // Converted to the D programming language by Tomas Lindquist Olsen 2008 +// and Frits van Bommel 2008 // Original file header: /*===-- llvm-c/Core.h - Core Library C Interface ------------------*- C -*-===*\ |* *| @@ -222,7 +223,6 @@ */ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty); -void LLVMRefineAbstractType(LLVMTypeRef AbstractType, LLVMTypeRef ConcreteType); /* Operations on integer types */ LLVMTypeRef LLVMInt1Type(); @@ -371,6 +371,11 @@ LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, LLVMValueRef VectorBConstant, LLVMValueRef MaskConstant); +LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, uint *IdxList, + uint NumIdx); +LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, + LLVMValueRef ElementValueConstant, + uint *IdxList, uint NumIdx); /* Operations on global variables, functions, and aliases (globals) */ LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global); @@ -392,7 +397,6 @@ LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar); LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar); void LLVMDeleteGlobal(LLVMValueRef GlobalVar); -int LLVMHasInitializer(LLVMValueRef GlobalVar); LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar); void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal); int LLVMIsThreadLocal(LLVMValueRef GlobalVar); @@ -412,8 +416,8 @@ uint LLVMGetIntrinsicID(LLVMValueRef Fn); uint LLVMGetFunctionCallConv(LLVMValueRef Fn); void LLVMSetFunctionCallConv(LLVMValueRef Fn, uint CC); -/*const*/ char *LLVMGetCollector(LLVMValueRef Fn); -void LLVMSetCollector(LLVMValueRef Fn, /*const*/ char *Coll); +/*const*/ char *LLVMGetGC(LLVMValueRef Fn); +void LLVMSetGC(LLVMValueRef Fn, /*const*/ char *Name); /* Operations on parameters */ uint LLVMCountParams(LLVMValueRef Fn); @@ -604,6 +608,11 @@ LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1, LLVMValueRef V2, LLVMValueRef Mask, /*const*/ char *Name); +LLVMValueRef LLVMBuildExtractValue(LLVMBuilderRef, LLVMValueRef AggVal, + uint Index, /*const*/ char *Name); +LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef, LLVMValueRef AggVal, + LLVMValueRef EltVal, uint Index, + /*const*/ char *Name); /*===-- Module providers --------------------------------------------------===*/ diff -r 1ba61de8796b -r 4ff9ab0d472c tools/binding/llvm/executionengine.d --- a/tools/binding/llvm/executionengine.d Mon Apr 27 22:33:17 2009 +0200 +++ b/tools/binding/llvm/executionengine.d Mon Apr 27 22:34:36 2009 +0200 @@ -100,6 +100,8 @@ { auto errmsg = from_stringz(err).dup; LLVMDisposeMessage(err); + if (errmsg.length == 0) + errmsg = "Error creating execution engine"; throw new LLVMException(errmsg); } return new ExecutionEngine(ee); @@ -113,6 +115,8 @@ { auto errmsg = from_stringz(err).dup; LLVMDisposeMessage(err); + if (errmsg.length == 0) + errmsg = "Error creating interpreter"; throw new LLVMException(errmsg); } return new ExecutionEngine(ee); @@ -126,6 +130,8 @@ { auto errmsg = from_stringz(err).dup; LLVMDisposeMessage(err); + if (errmsg.length == 0) + errmsg = "Error creating JIT"; throw new LLVMException(errmsg); } return new ExecutionEngine(ee); @@ -199,6 +205,8 @@ { auto errmsg = from_stringz(err).dup; LLVMDisposeMessage(err); + if (errmsg.length == 0) + errmsg = "Error removing ModuleProvider from ExecutionEngine"; throw new LLVMException(errmsg); } return Module.GetExisting(mod); diff -r 1ba61de8796b -r 4ff9ab0d472c tools/binding/llvm/llvm.d --- a/tools/binding/llvm/llvm.d Mon Apr 27 22:33:17 2009 +0200 +++ b/tools/binding/llvm/llvm.d Mon Apr 27 22:34:36 2009 +0200 @@ -53,6 +53,13 @@ /// private LLVMModuleRef mod; const char[] name; + + // Make all methods final to enable linking with just needed libs. + // To make use of this if compiling with GDC: use -ffunction-sections when + // compiling and --gc-sections when linking. + // (Final avoids references in the vtable) + final: + /// this(char[] nam) { @@ -86,6 +93,8 @@ { errmsg = from_stringz(msg).dup; LLVMDisposeMessage(msg); + if (errmsg.length == 0) + errmsg = "Error reading bitcode file"; throw new LLVMException(errmsg); } scope(exit) @@ -95,6 +104,8 @@ { errmsg = from_stringz(msg).dup; LLVMDisposeMessage(msg); + if (errmsg.length == 0) + errmsg = "Error parsing bitcode"; LLVMDisposeMemoryBuffer(bref); throw new LLVMException(errmsg); } @@ -194,8 +205,11 @@ { assert(mod !is null); auto c = LLVMGetOrInsertFunction(mod, to_stringz(nam), t.ll); - assert(c !is null); - return cast(Function)getValueOf(c); + auto val = getValueOf(c); + auto fn = cast(Function) val; + // Can happen if 'nam' names a function of a different type: + assert(fn !is null, "Not a function of type " ~ t.toString() ~ ": " ~ val.toString()); + return fn; } /// Performs the same optimizations as `opt -std-compile-opts ...' would on the module. /// If inline is true, function inlining will be performed. @@ -221,6 +235,8 @@ { auto errmsg = from_stringz(msg).dup; LLVMDisposeMessage(msg); + if (errmsg.length == 0) + errmsg = "Module verification failed"; throw new LLVMException(errmsg); } } @@ -256,6 +272,8 @@ { auto errmsg = from_stringz(msg).dup; LLVMDisposeMessage(msg); + if (errmsg.length == 0) + errmsg = "ModuleProvider: Error reading bitcode file"; throw new LLVMException(errmsg); } @@ -268,6 +286,8 @@ auto errmsg = from_stringz(msg).dup; LLVMDisposeMessage(msg); + if (errmsg.length == 0) + errmsg = "Error creating ModuleProvider for bitcode file"; throw new LLVMException(errmsg); } return new ModuleProvider(mp); @@ -567,14 +587,33 @@ /// mixin(GenericConstCmp!("Real","FCmp")); /// - Constant GetGEP(Constant ptr, Constant[] idxs) + Constant GetGEP(Constant ptr, Constant[] idxs...) { + static if (size_t.max > uint.max) { + assert(idxs.length <= uint.max, "Ridiculous number of indexes to GEP"); + } auto ar = new LLVMValueRef[idxs.length]; foreach(i,v; idxs) ar[i] = v.value; auto c = LLVMConstGEP(ptr.value, ar.ptr, ar.length); return cast(Constant)getValueOf(c); } /// + Constant GetExtractValue(Constant agg, uint[] idxs...) { + static if (size_t.max > uint.max) { + assert(idxs.length <= uint.max, "Ridiculous number of indexes to ExtractValue"); + } + auto c = LLVMConstExtractValue(agg.value, idxs.ptr, idxs.length); + return cast(Constant)getValueOf(c); + } + /// + Constant GetInsertValue(Constant agg, Constant elt, uint[] idxs...) { + static if (size_t.max > uint.max) { + assert(idxs.length <= uint.max, "Ridiculous number of indexes to InsertValue"); + } + auto c = LLVMConstInsertValue(agg.value, elt.value, idxs.ptr, idxs.length); + return cast(Constant)getValueOf(c); + } + /// Constant GetSizeOf(Type t) { return cast(Constant)getValueOf(LLVMSizeOf(t.ll)); @@ -762,8 +801,7 @@ /// class GlobalVariable : GlobalValue { - /// TODO: - /// void DeleteGlobal(ValueRef GlobalVar); + /// TODO: void DeleteGlobal(ValueRef GlobalVar); /// private this(LLVMValueRef v, Type t) { @@ -772,7 +810,7 @@ /// bool hasInitializer() { - return LLVMHasInitializer(value) != 0; + return isDeclaration() == 0; } /// Constant initializer() @@ -811,9 +849,8 @@ /// class Function : GlobalValue { - /// TODO: - /// void GetParams(ValueRef Fn, ValueRef *Params); - /// void GetBasicBlocks(ValueRef Fn, BasicBlockRef *BasicBlocks); + /// TODO: void GetParams(ValueRef Fn, ValueRef *Params); + /// TODO: void GetBasicBlocks(ValueRef Fn, BasicBlockRef *BasicBlocks); /// package this(LLVMValueRef v, Type t) { @@ -852,14 +889,14 @@ LLVMSetFunctionCallConv(value, cc); } /// - char[] collector() + char[] gc() { - return from_stringz(LLVMGetCollector(value)); + return from_stringz(LLVMGetGC(value)); } /// - void collector(char[] col) + void gc(char[] name) { - LLVMSetCollector(value, to_stringz(col)); + LLVMSetGC(value, to_stringz(name)); } /// uint numBasicBlocks() diff -r 1ba61de8796b -r 4ff9ab0d472c tools/binding/llvm/type.d --- a/tools/binding/llvm/type.d Mon Apr 27 22:33:17 2009 +0200 +++ b/tools/binding/llvm/type.d Mon Apr 27 22:34:36 2009 +0200 @@ -111,7 +111,7 @@ Type refineAbstractType(Type to) { assert(isAbstract()); - LLVMRefineAbstractType(type, to.type); + LLVMRefineType(type, to.type); // Either type will do. Go through the registry to try to use the // "canonical" Type object for the type. diff -r 1ba61de8796b -r 4ff9ab0d472c tools/binding/prebuild.sh --- a/tools/binding/prebuild.sh Mon Apr 27 22:33:17 2009 +0200 +++ b/tools/binding/prebuild.sh Mon Apr 27 22:34:36 2009 +0200 @@ -1,8 +1,8 @@ #!/bin/sh -g++ llvm-ext.cpp -c `llvm-config --cflags` -g++ llvm-opt.cpp -c `llvm-config --cflags` -g++ llvm-typemonitor.cpp -c `llvm-config --cflags` +g++ llvm-ext.cpp -c `llvm-config --cxxflags` +g++ llvm-opt.cpp -c `llvm-config --cxxflags` +g++ llvm-typemonitor.cpp -c `llvm-config --cxxflags` rm -f libllvm-c-ext.a ar rc libllvm-c-ext.a llvm-ext.o llvm-opt.o llvm-typemonitor.o