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.
This commit is contained in:
Frits van Bommel
2009-04-27 22:34:36 +02:00
parent e3b8cb29ea
commit f712c48312
7 changed files with 86 additions and 21 deletions

View File

@@ -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"

View File

@@ -72,6 +72,12 @@ private
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 @@ class Builder
"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;

View File

@@ -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 @@ void LLVMDumpModule(LLVMModuleRef M);
*/
LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty);
void LLVMRefineAbstractType(LLVMTypeRef AbstractType, LLVMTypeRef ConcreteType);
/* Operations on integer types */
LLVMTypeRef LLVMInt1Type();
@@ -371,6 +371,11 @@ LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant,
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 LLVMGetLastGlobal(LLVMModuleRef M);
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 @@ void LLVMDeleteFunction(LLVMValueRef Fn);
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 LLVMBuildInsertElement(LLVMBuilderRef, LLVMValueRef VecVal,
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 --------------------------------------------------===*/

View File

@@ -100,6 +100,8 @@ class ExecutionEngine
{
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 @@ class ExecutionEngine
{
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 @@ class ExecutionEngine
{
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 @@ class ExecutionEngine
{
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);

View File

@@ -53,6 +53,13 @@ class Module
///
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 @@ class Module
{
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 @@ class Module
{
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 @@ class Module
{
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 @@ class Module
{
auto errmsg = from_stringz(msg).dup;
LLVMDisposeMessage(msg);
if (errmsg.length == 0)
errmsg = "Module verification failed";
throw new LLVMException(errmsg);
}
}
@@ -256,6 +272,8 @@ class ModuleProvider
{
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 @@ class ModuleProvider
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 @@ class Constant : Value
///
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 @@ abstract class GlobalValue : Constant
///
class GlobalVariable : GlobalValue
{
/// TODO:
/// void DeleteGlobal(ValueRef GlobalVar);
/// TODO: void DeleteGlobal(ValueRef GlobalVar);
///
private this(LLVMValueRef v, Type t) {
@@ -772,7 +810,7 @@ class GlobalVariable : GlobalValue
///
bool hasInitializer()
{
return LLVMHasInitializer(value) != 0;
return isDeclaration() == 0;
}
///
Constant initializer()
@@ -811,9 +849,8 @@ class GlobalVariable : GlobalValue
///
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 @@ class Function : GlobalValue
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()

View File

@@ -111,7 +111,7 @@ class Type
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.

View File

@@ -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