changeset 1274:4ff9ab0d472c

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.
author Frits van Bommel <fvbommel wxs.nl>
date Mon, 27 Apr 2009 22:34:36 +0200
parents 1ba61de8796b
children bedf0bfb8fdb
files tools/binding/llvm-typemonitor.cpp tools/binding/llvm/builder.d tools/binding/llvm/c/Core.d tools/binding/llvm/executionengine.d tools/binding/llvm/llvm.d tools/binding/llvm/type.d tools/binding/prebuild.sh
diffstat 7 files changed, 86 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- 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"
 
--- 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;
--- 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 --------------------------------------------------===*/
--- 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);
--- 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()
--- 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.
--- 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