Committing LLVM binding for D as it currently exists in the SVN repository.

This commit is contained in:
Frits van Bommel
2009-04-27 22:33:17 +02:00
parent f290ff0530
commit e3b8cb29ea
21 changed files with 3493 additions and 0 deletions

72
tools/binding/LICENSE.TXT Normal file
View File

@@ -0,0 +1,72 @@
==============================================================================
LLVM Release License
==============================================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
Copyrights and Licenses for Third Party Software Distributed with LLVM:
==============================================================================
The LLVM software contains code written by third parties. Such software will
have its own individual LICENSE.TXT file in the directory in which it appears.
This file will describe the copyrights, license, and restrictions which apply
to that code.
The disclaimer of warranty in the University of Illinois Open Source License
applies to all code in the LLVM Distribution, and nothing in any of the
other licenses gives permission to use the names of the LLVM Team or the
University of Illinois to endorse or promote products derived from this
Software.
The following pieces of software have additional or alternate copyrights,
licenses, and/or restrictions:
Program Directory
------- ---------
System Library llvm/lib/System
Compiler Driver llvm/tools/llvmc
Autoconf llvm/autoconf
llvm/projects/ModuleMaker/autoconf
llvm/projects/sample/autoconf
Boost C++ Libraries llvm/include : docs/BOOST_LICENSE_1_0.txt
CellSPU backend llvm/lib/Target/CellSPU/README.txt

30
tools/binding/dsss.conf Normal file
View File

@@ -0,0 +1,30 @@
defaulttargets= llvm
[llvm]
type= library
prebuild= sh prebuild.sh
postinstall= install libllvm-c-ext.a $PREFIX/lib
[llvmsample1.d]
buildflags = libllvm-c-ext.a -llstdc++ \
-llLLVMCore -llLLVMBitWriter -llLLVMBitReader -llLLVMAnalysis -llLLVMTarget \
-llLLVMTransformUtils -llLLVMScalarOpts -llLLVMipa -llLLVMipo \
-llLLVMInstrumentation -llLLVMSystem -llLLVMSupport -lldl
[llvmsample2.d]
buildflags = libllvm-c-ext.a -llstdc++ \
-llLLVMCore -llLLVMBitWriter -llLLVMBitReader -llLLVMAnalysis -llLLVMTarget \
-llLLVMTransformUtils -llLLVMScalarOpts -llLLVMipa -llLLVMipo \
-llLLVMInstrumentation -llLLVMSystem -llLLVMSupport -lldl
[llvmsample3.d]
buildflags = libllvm-c-ext.a -llstdc++ \
-llLLVMCore -llLLVMBitWriter -llLLVMBitReader -llLLVMAnalysis -llLLVMTarget \
-llLLVMTransformUtils -llLLVMScalarOpts -llLLVMipa -llLLVMipo \
-llLLVMInstrumentation -llLLVMSystem -llLLVMSupport -lldl
[llvmsample4.d]
buildflags = libllvm-c-ext.a -llstdc++ \
-llLLVMCore -llLLVMBitWriter -llLLVMBitReader -llLLVMAnalysis -llLLVMTarget \
-llLLVMTransformUtils -llLLVMScalarOpts -llLLVMipa -llLLVMipo \
-llLLVMInstrumentation -llLLVMSystem -llLLVMSupport -lldl

View File

@@ -0,0 +1,87 @@
// Extension of the LLVM C interface for use with D, some things in the
// LLVM 2.2 release are kind sparse or even broken...
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
#ifndef D11_LLVMCEXT_H
#define D11_LLVMCEXT_H
#include "llvm/Type.h"
#include "llvm/Constants.h"
#include "llvm/Support/CFG.h"
#include "llvm/Target/TargetData.h"
#include "llvm-c/Core.h"
#include <sstream>
#include <cstring>
using namespace llvm;
using namespace std;
extern "C"
{
// we need to be able to erase an instruction from its parent
void LLVMEraseFromParent(LLVMValueRef I) {
unwrap<Instruction>(I)->eraseFromParent();
}
// we need to be able to check if a basic block is terminated
int LLVMIsTerminated(LLVMBasicBlockRef BB) {
return (unwrap(BB)->getTerminator() != NULL);
}
// we need to be able to check if a basic block has any predecessors
int LLVMHasPredecessors(LLVMBasicBlockRef BB) {
BasicBlock* B = unwrap(BB);
return (pred_begin(B) != pred_end(B));
}
// we need to be able to check if a basic block is empty
int LLVMIsBasicBlockEmpty(LLVMBasicBlockRef BB) {
return unwrap(BB)->empty();
}
// we need to be able to replace all uses of V with W
void LLVMReplaceAllUsesWith(LLVMValueRef V, LLVMValueRef W) {
unwrap<Value>(V)->replaceAllUsesWith(unwrap<Value>(W));
}
// sometimes it's nice to be able to dump a type, not only values...
void LLVMDumpType(LLVMTypeRef T) {
unwrap(T)->dump();
}
LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, char* Name, LLVMTypeRef Type) {
return wrap(unwrap(M)->getOrInsertFunction(Name, unwrap<FunctionType>(Type)));
}
// being able to determine the "kind" of a value is really useful
unsigned LLVMGetValueKind(LLVMValueRef Value) {
return unwrap(Value)->getValueID();
}
char* LLVMValueToString(LLVMValueRef v) {
stringstream ss;
unwrap(v)->print(ss);
return strdup(ss.str().c_str());
}
char* LLVMTypeToString(LLVMTypeRef ty) {
stringstream ss;
unwrap(ty)->print(ss);
return strdup(ss.str().c_str());
}
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, char* Name) {
return wrap(unwrap(M)->getTypeByName(Name));
}
int LLVMIsTypeAbstract(LLVMTypeRef T) {
return unwrap(T)->isAbstract();
}
} // extern "C"
#endif

View File

@@ -0,0 +1,75 @@
// Optimizer functionality for the LLVM D binding.
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
#include "llvm/PassManager.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Target/TargetData.h"
#include "llvm-c/Core.h"
using namespace llvm;
extern "C" {
void LLVMOptimizeModule(LLVMModuleRef M, int doinline)
{
Module* m = unwrap(M);
PassManager pm;
pm.add(new TargetData(m));
//pm.add(createStripDeadPrototypesPass());
pm.add(createGlobalDCEPass());
pm.add(createRaiseAllocationsPass());
pm.add(createCFGSimplificationPass());
pm.add(createPromoteMemoryToRegisterPass());
pm.add(createGlobalOptimizerPass());
pm.add(createGlobalDCEPass());
pm.add(createIPConstantPropagationPass());
pm.add(createDeadArgEliminationPass());
pm.add(createInstructionCombiningPass());
pm.add(createCFGSimplificationPass());
pm.add(createPruneEHPass());
if (doinline)
pm.add(createFunctionInliningPass());
pm.add(createArgumentPromotionPass());
pm.add(createTailDuplicationPass());
pm.add(createInstructionCombiningPass());
pm.add(createCFGSimplificationPass());
pm.add(createScalarReplAggregatesPass());
pm.add(createInstructionCombiningPass());
pm.add(createCondPropagationPass());
pm.add(createTailCallEliminationPass());
pm.add(createCFGSimplificationPass());
pm.add(createReassociatePass());
pm.add(createLoopRotatePass());
pm.add(createLICMPass());
pm.add(createLoopUnswitchPass());
pm.add(createInstructionCombiningPass());
pm.add(createIndVarSimplifyPass());
pm.add(createLoopUnrollPass());
pm.add(createInstructionCombiningPass());
pm.add(createGVNPass());
pm.add(createSCCPPass());
pm.add(createInstructionCombiningPass());
pm.add(createCondPropagationPass());
pm.add(createDeadStoreEliminationPass());
pm.add(createAggressiveDCEPass());
pm.add(createCFGSimplificationPass());
pm.add(createSimplifyLibCallsPass());
pm.add(createDeadTypeEliminationPass());
pm.add(createConstantMergePass());
pm.run(*m);
}
}

View File

@@ -0,0 +1,45 @@
/// Support for callbacks when an abstract type becomes more concrete.
#include "llvm/Type.h"
#include "llvm-c/Core.h"
using namespace llvm;
extern "C" typedef int (*RefineCallback)(void *handle, LLVMTypeRef newT);
class TypeMonitor : AbstractTypeUser {
void *handle_;
RefineCallback callback_;
void onRefineType(const Type* oldT, const Type* newT) {
callback_(handle_, wrap(newT));
oldT->removeAbstractTypeUser(this);
delete this;
}
public:
TypeMonitor(Type* T, void *handle, RefineCallback callback)
: handle_(handle), callback_(callback) {
T->addAbstractTypeUser(this);
}
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
onRefineType(OldTy, NewTy);
}
virtual void typeBecameConcrete(const DerivedType *AbsTy) {
onRefineType(AbsTy, AbsTy);
}
virtual void dump() const {
cerr << "<TypeMonitor>";
}
};
extern "C" void LLVMRegisterAbstractTypeCallback(LLVMTypeRef T,
void *handle,
RefineCallback callback)
{
new TypeMonitor(unwrap(T), handle, callback);
}

View File

@@ -0,0 +1,192 @@
// Written in the D programming language by Tomas Lindquist Olsen 2008
// Binding of llvm.c.Core builder for D.
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
module llvm.builder;
import llvm.c.Core;
import llvm.c.Ext;
import llvm.llvm;
import llvm.util;
private
{
template Build_NoArgs_Mixin(char[] N) {
const Build_NoArgs_Mixin = "
Value build"~N~"() {
return new Value(LLVMBuild"~N~"(builder));
}
";
}
template Build_Mixin(char[] NAME, char[] ARGS, char[] VALUES) {
const Build_Mixin = "
Value build"~NAME~"("~ARGS~") {
return new Value(LLVMBuild"~NAME~"(builder, "~VALUES~"));
}
";
static assert(ARGS != "");
static assert(VALUES != "");
}
// unnamed
template Build_Value(char[] N) {
const Build_Value = Build_Mixin!(N, "Value v", `v.value`);
}
template Build_Value_Value(char[] N) {
const Build_Value_Value = Build_Mixin!(N, "Value v, Value w", `v.value, w.value`);
}
template Build_BB(char[] N) {
const Build_BB = Build_Mixin!(N, "BasicBlock b", `b.bb`);
}
template Build_Value_BB_BB(char[] N) {
const Build_Value_BB_BB = Build_Mixin!(N, "Value v, BasicBlock b1, BasicBlock b2", `v.value, b1.bb, b2.bb`);
}
template Build_Value_BB_uint(char[] N) {
const Build_Value_BB_uint = Build_Mixin!(N, "Value v, BasicBlock b, uint n", `v.value, b.bb, n`);
}
// named
template Build_Named_Mixin(char[] NAME, char[] ARGS, char[] VALUES) {
const Build_Named_Mixin = Build_Mixin!(NAME, ARGS~", char[] name", VALUES~`, to_stringz(name)`);
}
template Build_Type_Name(char[] N) {
const Build_Type_Name = Build_Named_Mixin!(N, "Type t", `t.ll`);
}
template Build_Value_Name(char[] N) {
const Build_Value_Name = Build_Named_Mixin!(N, "Value v", `v.value`);
}
template Build_Type_Value_Name(char[] N) {
const Build_Type_Value_Name = Build_Named_Mixin!(N, "Type t, Value v", `t.ll, v.value`);
}
template Build_Value_Type_Name(char[] N) {
const Build_Value_Type_Name = Build_Named_Mixin!(N, "Value v, Type t", `v.value, t.ll`);
}
template Build_Value_Value_Name(char[] N) {
const Build_Value_Value_Name = Build_Named_Mixin!(N, "Value a, Value b", `a.value, b.value`);
}
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_Cmp(char[] PRED, char[] N) {
const Build_Cmp = Build_Named_Mixin!(N, ""~PRED~"Predicate p, Value l, Value r", `p, l.value, r.value`);
}
template StringDistribute(alias T, U...)
{
static if (!U.length)
const char[] StringDistribute="";
else
const char[] StringDistribute = T!(U[0]) ~ StringDistribute!(T, U[1..$]);
}
}
///
class Builder
{
///
private LLVMBuilderRef builder;
///
this()
{
builder = LLVMCreateBuilder();
}
///
void dispose()
{
LLVMDisposeBuilder(builder);
builder = null;
}
///
~this()
{
// safe because builder isn't on the GC heap and isn't exposed.
dispose();
}
///
void positionBefore(Value v)
{
assert(builder !is null);
LLVMPositionBuilderBefore(builder, v.value);
}
///
void positionAtEnd(BasicBlock bb)
{
assert(builder !is null);
LLVMPositionBuilderAtEnd(builder, bb.bb);
}
///
void positionAtStart(BasicBlock bb)
{
assert(builder !is null);
LLVMPositionBuilderBefore(builder, LLVMGetFirstInstruction(bb.bb));
}
///
BasicBlock getInsertBlock()
{
return new BasicBlock(LLVMGetInsertBlock(builder));
}
///
mixin(StringDistribute!(Build_NoArgs_Mixin, "RetVoid", "Unwind", "Unreachable"));
mixin(Build_BB!("Br"));
mixin(Build_Value_BB_BB!("CondBr"));
mixin(Build_Value_BB_uint!("Switch"));
///
mixin(StringDistribute!(Build_Value, "Ret", "Free"));
///
mixin(Build_Value_Value!("Store"));
///
mixin(StringDistribute!(Build_Value_Value_Name,
"Add","Sub","Mul","UDiv","SDiv","FDiv","URem","SRem","FRem",
"Shl","LShr","AShr","And","Or","Xor",
"ExtractElement"
));
///
mixin(StringDistribute!(Build_Value_Name, "Neg","Not", "Load"));
///
mixin(StringDistribute!(Build_Value_Type_Name,
"Trunc","SExt","ZExt","FPTrunc","FPExt",
"UIToFP","SIToFP","FPToUI","FPToSI",
"PtrToInt","IntToPtr","BitCast",
"VAArg"
));
///
mixin(Build_Cmp!("Int","ICmp"));
///
mixin(Build_Cmp!("Real","FCmp"));
///
mixin(StringDistribute!(Build_Type_Name,
"Phi", "Malloc", "Alloca"
));
///
mixin(StringDistribute!(Build_Type_Value_Name,
"ArrayMalloc", "ArrayAlloca"
));
///
mixin(StringDistribute!(Build_Value_Value_Value_Name,
"Select", "InsertElement", "ShuffleVector"
));
///
Value buildCall(Value fn, Value[] args, char[] name) {
auto llargs = new LLVMValueRef[args.length];
foreach(i,a; args) llargs[i] = a.value;
return new Value(LLVMBuildCall(builder, fn.value, llargs.ptr, llargs.length, to_stringz(name)));
}
///
Value buildGEP(Value ptr, Value[] indices, char[] name) {
auto llindices = new LLVMValueRef[indices.length];
foreach(i,idx; indices) llindices[i] = idx.value;
return new Value(LLVMBuildGEP(builder, ptr.value, llindices.ptr, llindices.length, to_stringz(name)));
}
///
Value buildInvoke(Value fn, Value[] args, BasicBlock thenbb, BasicBlock catchbb, char[] name) {
auto llargs = new LLVMValueRef[args.length];
foreach(i,a; args) llargs[i] = a.value;
return new Value(LLVMBuildInvoke(builder, fn.value, llargs.ptr, llargs.length, thenbb.bb, catchbb.bb, to_stringz(name)));
}
}

View File

@@ -0,0 +1,42 @@
// Converted to the D programming language by Tomas Lindquist Olsen 2008
// Original file header:
/*===-- llvm-c/Analysis.h - Analysis Library C Interface --------*- C++ -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header declares the C interface to libLLVMAnalysis.a, which *|
|* implements various analyses of the LLVM IR. *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
\*===----------------------------------------------------------------------===*/
module llvm.c.Analysis;
import llvm.c.Core;
extern(C):
enum LLVMVerifierFailureAction {
AbortProcess, /* verifier will print to stderr and abort() */
PrintMessage, /* verifier will print to stderr and return 1 */
ReturnStatus /* verifier will just return 1 */
}
/* Verifies that a module is valid, taking the specified action if not.
Optionally returns a human-readable description of any invalid constructs.
OutMessage must be disposed with LLVMDisposeMessage. */
int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
char **OutMessage);
/* Verifies that a single function is valid, taking the specified action. Useful
for debugging. */
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);

View File

@@ -0,0 +1,38 @@
// Converted to the D programming language by Tomas Lindquist Olsen 2008
// Original file header:
/*===-- llvm-c/BitReader.h - BitReader Library C Interface ------*- C++ -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header declares the C interface to libLLVMBitReader.a, which *|
|* implements input of the LLVM bitcode format. *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
\*===----------------------------------------------------------------------===*/
module llvm.c.BitReader;
import llvm.c.Core;
extern(C):
/* Builds a module from the bitcode in the specified memory buffer, returning a
reference to the module via the OutModule parameter. Returns 0 on success.
Optionally returns a human-readable error message via OutMessage. */
int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
LLVMModuleRef *OutModule, char **OutMessage);
/* Reads a module from the specified path, returning via the OutMP parameter
a module provider which performs lazy deserialization. Returns 0 on success.
Optionally returns a human-readable error message via OutMessage. */
int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
LLVMModuleProviderRef *OutMP,
char **OutMessage);

View File

@@ -0,0 +1,33 @@
// Converted to the D programming language by Tomas Lindquist Olsen 2008
// Original file header:
/*===-- llvm-c/BitWriter.h - BitWriter Library C Interface ------*- C++ -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header declares the C interface to libLLVMBitWriter.a, which *|
|* implements output of the LLVM bitcode format. *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
\*===----------------------------------------------------------------------===*/
module llvm.c.BitWriter;
import llvm.c.Core;
extern(C):
/*===-- Operations on modules ---------------------------------------------===*/
/** Writes a module to an open file descriptor. Returns 0 on success. */
int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle);
/** Writes a module to the specified path. Returns 0 on success. */
int LLVMWriteBitcodeToFile(LLVMModuleRef M, /*const*/ char *Path);

670
tools/binding/llvm/c/Core.d Normal file
View File

@@ -0,0 +1,670 @@
// Converted to the D programming language by Tomas Lindquist Olsen 2008
// Original file header:
/*===-- llvm-c/Core.h - Core Library C Interface ------------------*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header declares the C interface to libLLVMCore.a, which implements *|
|* the LLVM intermediate representation. *|
|* *|
|* LLVM uses a polymorphic type hierarchy which C cannot represent, therefore *|
|* parameters must be passed as base types. Despite the declared types, most *|
|* of the functions provided operate only on branches of the type hierarchy. *|
|* The declared parameter names are descriptive and specify which type is *|
|* required. Additionally, each type hierarchy is documented along with the *|
|* functions that operate upon it. For more detail, refer to LLVM's C++ code. *|
|* If in doubt, refer to Core.cpp, which performs paramter downcasts in the *|
|* form unwrap<RequiredType>(Param). *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
|* When included into a C++ source file, also declares 'wrap' and 'unwrap' *|
|* helpers to perform opaque reference<-->pointer conversions. These helpers *|
|* are shorter and more tightly typed than writing the casts by hand when *|
|* authoring bindings. In assert builds, they will do runtime type checking. *|
|* *|
\*===----------------------------------------------------------------------===*/
module llvm.c.Core;
extern(C):
/* Opaque types. */
private
{
struct LLVM_OpaqueModule {}
struct LLVM_OpaqueType {}
struct LLVM_OpaqueTypeHandle {}
struct LLVM_OpaqueValue {}
struct LLVM_OpaqueBasicBlock {}
struct LLVM_OpaqueBuilder {}
struct LLVM_OpaqueModuleProvider {}
struct LLVM_OpaqueMemoryBuffer {}
struct LLVM_OpaquePassManager {}
}
/**
* The top-level container for all other LLVM Intermediate Representation (IR)
* objects. See the llvm::Module class.
*/
typedef LLVM_OpaqueModule* LLVMModuleRef;
/**
* Each value in the LLVM IR has a type, an instance of [lltype]. See the
* llvm::Type class.
*/
typedef LLVM_OpaqueType* LLVMTypeRef;
/**
* When building recursive types using [refine_type], [lltype] values may become
* invalid; use [lltypehandle] to resolve this problem. See the
* llvm::AbstractTypeHolder] class.
*/
typedef LLVM_OpaqueTypeHandle* LLVMTypeHandleRef;
typedef LLVM_OpaqueValue* LLVMValueRef;
typedef LLVM_OpaqueBasicBlock* LLVMBasicBlockRef;
typedef LLVM_OpaqueBuilder* LLVMBuilderRef;
/* Used to provide a module to JIT or interpreter.
* See the llvm::ModuleProvider class.
*/
typedef LLVM_OpaqueModuleProvider* LLVMModuleProviderRef;
/* Used to provide a module to JIT or interpreter.
* See the llvm::MemoryBuffer class.
*/
typedef LLVM_OpaqueMemoryBuffer* LLVMMemoryBufferRef;
/** See the llvm::PassManagerBase class. */
typedef LLVM_OpaquePassManager* LLVMPassManagerRef;
enum LLVMParamAttr {
ZExt = 1<<0,
SExt = 1<<1,
NoReturn = 1<<2,
InReg = 1<<3,
StructRet = 1<<4,
NoUnwind = 1<<5,
NoAlias = 1<<6,
ByVal = 1<<7,
Nest = 1<<8,
ReadNone = 1<<9,
ReadOnly = 1<<10
}
enum LLVMTypeKind {
Void, /**< type with no size */
Float, /**< 32 bit floating point type */
Double, /**< 64 bit floating point type */
X86_FP80, /**< 80 bit floating point type (X87) */
FP128, /**< 128 bit floating point type (112-bit mantissa)*/
PPC_FP128, /**< 128 bit floating point type (two 64-bits) */
Label, /**< Labels */
Integer, /**< Arbitrary bit width integers */
Function, /**< Functions */
Struct, /**< Structures */
Array, /**< Arrays */
Pointer, /**< Pointers */
Opaque, /**< Opaque: type with unknown structure */
Vector /**< SIMD 'packed' format, or other vector type */
}
enum LLVMLinkage {
External, /**< Externally visible function */
LinkOnce, /**< Keep one copy of function when linking (inline)*/
Weak, /**< Keep one copy of function when linking (weak) */
Appending, /**< Special purpose, only applies to global arrays */
Internal, /**< Rename collisions when linking (static functions) */
DLLImport, /**< Function to be imported from DLL */
DLLExport, /**< Function to be accessible from DLL */
ExternalWeak,/**< ExternalWeak linkage description */
Ghost /**< Stand-in functions for streaming fns from bitcode */
}
enum LLVMVisibility {
Default, /**< The GV is visible */
Hidden, /**< The GV is hidden */
Protected/**< The GV is protected */
}
enum LLVMCallConv {
C = 0,
Fast = 8,
Cold = 9,
X86Stdcall = 64,
X86Fastcall= 65
}
enum LLVMIntPredicate {
EQ = 32, /**< equal */
NE, /**< not equal */
UGT, /**< uint greater than */
UGE, /**< uint greater or equal */
ULT, /**< uint less than */
ULE, /**< uint less or equal */
SGT, /**< signed greater than */
SGE, /**< signed greater or equal */
SLT, /**< signed less than */
SLE /**< signed less or equal */
}
enum LLVMRealPredicate {
False, /**< Always false (always folded) */
OEQ, /**< True if ordered and equal */
OGT, /**< True if ordered and greater than */
OGE, /**< True if ordered and greater than or equal */
OLT, /**< True if ordered and less than */
OLE, /**< True if ordered and less than or equal */
ONE, /**< True if ordered and operands are unequal */
ORD, /**< True if ordered (no nans) */
UNO, /**< True if unordered: isnan(X) | isnan(Y) */
UEQ, /**< True if unordered or equal */
UGT, /**< True if unordered or greater than */
UGE, /**< True if unordered, greater than, or equal */
ULT, /**< True if unordered or less than */
ULE, /**< True if unordered, less than, or equal */
UNE, /**< True if unordered or not equal */
True /**< Always true (always folded) */
}
/*===-- Error handling ----------------------------------------------------===*/
void LLVMDisposeMessage(char *Message);
/*===-- Modules -----------------------------------------------------------===*/
/* Create and destroy modules. */
/** See llvm::Module::Module. */
LLVMModuleRef LLVMModuleCreateWithName(/*const*/ char *ModuleID);
/** See llvm::Module::~Module. */
void LLVMDisposeModule(LLVMModuleRef M);
/** Data layout. See Module::getDataLayout. */
/*const*/ char *LLVMGetDataLayout(LLVMModuleRef M);
void LLVMSetDataLayout(LLVMModuleRef M, /*const*/ char *Triple);
/** Target triple. See Module::getTargetTriple. */
/*const*/ char *LLVMGetTarget(LLVMModuleRef M);
void LLVMSetTarget(LLVMModuleRef M, /*const*/ char *Triple);
/** See Module::addTypeName. */
int LLVMAddTypeName(LLVMModuleRef M, /*const*/ char *Name, LLVMTypeRef Ty);
void LLVMDeleteTypeName(LLVMModuleRef M, /*const*/ char *Name);
/** See Module::dump. */
void LLVMDumpModule(LLVMModuleRef M);
/*===-- Types -------------------------------------------------------------===*/
/* LLVM types conform to the following hierarchy:
*
* types:
* integer type
* real type
* function type
* sequence types:
* array type
* pointer type
* vector type
* void type
* label type
* opaque type
*/
LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty);
void LLVMRefineAbstractType(LLVMTypeRef AbstractType, LLVMTypeRef ConcreteType);
/* Operations on integer types */
LLVMTypeRef LLVMInt1Type();
LLVMTypeRef LLVMInt8Type();
LLVMTypeRef LLVMInt16Type();
LLVMTypeRef LLVMInt32Type();
LLVMTypeRef LLVMInt64Type();
LLVMTypeRef LLVMIntType(uint NumBits);
uint LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy);
/* Operations on real types */
LLVMTypeRef LLVMFloatType();
LLVMTypeRef LLVMDoubleType();
LLVMTypeRef LLVMX86FP80Type();
LLVMTypeRef LLVMFP128Type();
LLVMTypeRef LLVMPPCFP128Type();
/* Operations on function types */
LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType,
LLVMTypeRef *ParamTypes, uint ParamCount,
int IsVarArg);
int LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy);
LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy);
uint LLVMCountParamTypes(LLVMTypeRef FunctionTy);
void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest);
/* Operations on struct types */
LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, uint ElementCount,
int Packed);
uint LLVMCountStructElementTypes(LLVMTypeRef StructTy);
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
int LLVMIsPackedStruct(LLVMTypeRef StructTy);
/* Operations on array, pointer, and vector types (sequence types) */
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, uint ElementCount);
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, uint AddressSpace);
LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, uint ElementCount);
LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty);
uint LLVMGetArrayLength(LLVMTypeRef ArrayTy);
uint LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy);
uint LLVMGetVectorSize(LLVMTypeRef VectorTy);
/* Operations on other types */
LLVMTypeRef LLVMVoidType();
LLVMTypeRef LLVMLabelType();
LLVMTypeRef LLVMOpaqueType();
/* Operations on type handles */
LLVMTypeHandleRef LLVMCreateTypeHandle(LLVMTypeRef PotentiallyAbstractTy);
void LLVMRefineType(LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy);
LLVMTypeRef LLVMResolveTypeHandle(LLVMTypeHandleRef TypeHandle);
void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle);
/*===-- Values ------------------------------------------------------------===*/
/* The bulk of LLVM's object model consists of values, which comprise a very
* rich type hierarchy.
*
* values:
* constants:
* scalar constants
* composite contants
* globals:
* global variable
* function
* alias
* basic blocks
*/
/* Operations on all values */
LLVMTypeRef LLVMTypeOf(LLVMValueRef Val);
/*const*/ char *LLVMGetValueName(LLVMValueRef Val);
void LLVMSetValueName(LLVMValueRef Val, /*const*/ char *Name);
void LLVMDumpValue(LLVMValueRef Val);
/* Operations on constants of any type */
LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */
LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty); /* only for int/vector */
LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty);
int LLVMIsConstant(LLVMValueRef Val);
int LLVMIsNull(LLVMValueRef Val);
int LLVMIsUndef(LLVMValueRef Val);
/* Operations on scalar constants */
LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, ulong N,
int SignExtend);
LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N);
LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, /*const*/ char *Text);
/* Operations on composite constants */
LLVMValueRef LLVMConstString(/*const*/ char *Str, uint Length,
int DontNullTerminate);
LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
LLVMValueRef *ConstantVals, uint Length);
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, uint Count,
int packed);
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, uint Size);
/* Constant expressions */
LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty);
LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal);
LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal);
LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstICmp(LLVMIntPredicate Predicate,
LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate,
LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal,
LLVMValueRef *ConstantIndices, uint NumIndices);
LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition,
LLVMValueRef ConstantIfTrue,
LLVMValueRef ConstantIfFalse);
LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant,
LLVMValueRef IndexConstant);
LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant,
LLVMValueRef ElementValueConstant,
LLVMValueRef IndexConstant);
LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant,
LLVMValueRef VectorBConstant,
LLVMValueRef MaskConstant);
/* Operations on global variables, functions, and aliases (globals) */
LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global);
int LLVMIsDeclaration(LLVMValueRef Global);
LLVMLinkage LLVMGetLinkage(LLVMValueRef Global);
void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage);
/*const*/ char *LLVMGetSection(LLVMValueRef Global);
void LLVMSetSection(LLVMValueRef Global, /*const*/ char *Section);
LLVMVisibility LLVMGetVisibility(LLVMValueRef Global);
void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz);
uint LLVMGetAlignment(LLVMValueRef Global);
void LLVMSetAlignment(LLVMValueRef Global, uint Bytes);
/* Operations on global variables */
LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, /*const*/ char *Name);
LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, /*const*/ char *Name);
LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M);
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);
void LLVMSetThreadLocal(LLVMValueRef GlobalVar, int IsThreadLocal);
int LLVMIsGlobalConstant(LLVMValueRef GlobalVar);
void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, int IsConstant);
/* Operations on functions */
LLVMValueRef LLVMAddFunction(LLVMModuleRef M, /*const*/ char *Name,
LLVMTypeRef FunctionTy);
LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, /*const*/ char *Name);
LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M);
LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M);
LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn);
LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn);
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);
/* Operations on parameters */
uint LLVMCountParams(LLVMValueRef Fn);
void LLVMGetParams(LLVMValueRef Fn, LLVMValueRef *Params);
LLVMValueRef LLVMGetParam(LLVMValueRef Fn, uint Index);
LLVMValueRef LLVMGetParamParent(LLVMValueRef Inst);
LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn);
LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn);
LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg);
LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg);
void LLVMAddParamAttr(LLVMValueRef Arg, LLVMParamAttr PA);
void LLVMRemoveParamAttr(LLVMValueRef Arg, LLVMParamAttr PA);
void LLVMSetParamAlignment(LLVMValueRef Arg, uint alignm);
/* Operations on basic blocks */
LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef Bb);
int LLVMValueIsBasicBlock(LLVMValueRef Val);
LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val);
LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB);
uint LLVMCountBasicBlocks(LLVMValueRef Fn);
void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks);
LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn);
LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn);
LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB);
LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB);
LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn);
LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, /*const*/ char *Name);
LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB,
/*const*/ char *Name);
void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB);
/* Operations on instructions */
LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB);
LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB);
LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst);
LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst);
/* Operations on call sites */
void LLVMSetInstructionCallConv(LLVMValueRef Instr, uint CC);
uint LLVMGetInstructionCallConv(LLVMValueRef Instr);
void LLVMAddInstrParamAttr(LLVMValueRef Instr, uint index, LLVMParamAttr);
void LLVMRemoveInstrParamAttr(LLVMValueRef Instr, uint index,
LLVMParamAttr);
void LLVMSetInstrParamAlignment(LLVMValueRef Instr, uint index,
uint alignm);
/* Operations on phi nodes */
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
LLVMBasicBlockRef *IncomingBlocks, uint Count);
uint LLVMCountIncoming(LLVMValueRef PhiNode);
LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, uint Index);
LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, uint Index);
/*===-- Instruction builders ----------------------------------------------===*/
/* An instruction builder represents a point within a basic block, and is the
* exclusive means of building instructions using the C interface.
*/
LLVMBuilderRef LLVMCreateBuilder();
void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block,
LLVMValueRef Instr);
void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr);
void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block);
LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder);
void LLVMDisposeBuilder(LLVMBuilderRef Builder);
/* Terminators */
LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef);
LLVMValueRef LLVMBuildRet(LLVMBuilderRef, LLVMValueRef V);
LLVMValueRef LLVMBuildBr(LLVMBuilderRef, LLVMBasicBlockRef Dest);
LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef If,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Else);
LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V,
LLVMBasicBlockRef Else, uint NumCases);
LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
LLVMValueRef *Args, uint NumArgs,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
/*const*/ char *Name);
LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef);
LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
/* Add a case to the switch instruction */
void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
LLVMBasicBlockRef Dest);
/* Arithmetic */
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildURem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildSRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildFRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildShl(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildLShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildAShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildAnd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildOr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildXor(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, /*const*/ char *Name);
LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, /*const*/ char *Name);
/* Memory */
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef Ty, /*const*/ char *Name);
LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty,
LLVMValueRef Val, /*const*/ char *Name);
LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef, LLVMTypeRef Ty, /*const*/ char *Name);
LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef, LLVMTypeRef Ty,
LLVMValueRef Val, /*const*/ char *Name);
LLVMValueRef LLVMBuildFree(LLVMBuilderRef, LLVMValueRef PointerVal);
LLVMValueRef LLVMBuildLoad(LLVMBuilderRef, LLVMValueRef PointerVal,
/*const*/ char *Name);
LLVMValueRef LLVMBuildStore(LLVMBuilderRef, LLVMValueRef Val, LLVMValueRef Ptr);
LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
LLVMValueRef *Indices, uint NumIndices,
/*const*/ char *Name);
/* Casts */
LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildZExt(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildSExt(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef, LLVMValueRef Val,
LLVMTypeRef DestTy, /*const*/ char *Name);
/* Comparisons */
LLVMValueRef LLVMBuildICmp(LLVMBuilderRef, LLVMIntPredicate Op,
LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef, LLVMRealPredicate Op,
LLVMValueRef LHS, LLVMValueRef RHS,
/*const*/ char *Name);
/* Miscellaneous instructions */
LLVMValueRef LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef Ty, /*const*/ char *Name);
LLVMValueRef LLVMBuildCall(LLVMBuilderRef, LLVMValueRef Fn,
LLVMValueRef *Args, uint NumArgs,
/*const*/ char *Name);
LLVMValueRef LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef If,
LLVMValueRef Then, LLVMValueRef Else,
/*const*/ char *Name);
LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef, LLVMValueRef List, LLVMTypeRef Ty,
/*const*/ char *Name);
LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef, LLVMValueRef VecVal,
LLVMValueRef Index, /*const*/ char *Name);
LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef, LLVMValueRef VecVal,
LLVMValueRef EltVal, LLVMValueRef Index,
/*const*/ char *Name);
LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1,
LLVMValueRef V2, LLVMValueRef Mask,
/*const*/ char *Name);
/*===-- Module providers --------------------------------------------------===*/
/* Encapsulates the module M in a module provider, taking ownership of the
* module.
* See the constructor llvm::ExistingModuleProvider::ExistingModuleProvider.
*/
LLVMModuleProviderRef
LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M);
/* Destroys the module provider MP as well as the contained module.
* See the destructor llvm::ModuleProvider::~ModuleProvider.
*/
void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP);
/*===-- Memory buffers ----------------------------------------------------===*/
int LLVMCreateMemoryBufferWithContentsOfFile(/*const*/ char *Path,
LLVMMemoryBufferRef *OutMemBuf,
char **OutMessage);
int LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
char **OutMessage);
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
/*===-- Pass Managers -----------------------------------------------------===*/
/** Constructs a new whole-module pass pipeline. This type of pipeline is
suitable for link-time optimization and whole-module transformations.
See llvm::PassManager::PassManager. */
LLVMPassManagerRef LLVMCreatePassManager();
/** Constructs a new function-by-function pass pipeline over the module
provider. It does not take ownership of the module provider. This type of
pipeline is suitable for code generation and JIT compilation tasks.
See llvm::FunctionPassManager::FunctionPassManager. */
LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP);
/** Initializes, executes on the provided module, and finalizes all of the
passes scheduled in the pass manager. Returns 1 if any of the passes
modified the module, 0 otherwise. See llvm::PassManager::run(Module&). */
int LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M);
/** Initializes all of the function passes scheduled in the function pass
manager. Returns 1 if any of the passes modified the module, 0 otherwise.
See llvm::FunctionPassManager::doInitialization. */
int LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM);
/** Executes all of the function passes scheduled in the function pass manager
on the provided function. Returns 1 if any of the passes modified the
function, false otherwise.
See llvm::FunctionPassManager::run(Function&). */
int LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F);
/** Finalizes all of the function passes scheduled in in the function pass
manager. Returns 1 if any of the passes modified the module, 0 otherwise.
See llvm::FunctionPassManager::doFinalization. */
int LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
/** Frees the memory of a pass pipeline. For function pipelines, does not free
the module provider.
See llvm::PassManagerBase::~PassManagerBase. */
void LLVMDisposePassManager(LLVMPassManagerRef PM);

View File

@@ -0,0 +1,94 @@
// Converted to the D programming language by Tomas Lindquist Olsen 2008
// Original file header:
/*===-- llvm-c/ExecutionEngine.h - ExecutionEngine Lib C Iface --*- C++ -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header declares the C interface to libLLVMExecutionEngine.o, which *|
|* implements various analyses of the LLVM IR. *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
\*===----------------------------------------------------------------------===*/
module llvm.c.ExecutionEngine;
import llvm.c.Core;
extern(C):
private
{
struct LLVM_OpaqueGenericValue {}
struct LLVM_OpaqueExecutionEngine {}
}
typedef LLVM_OpaqueGenericValue* LLVMGenericValueRef;
typedef LLVM_OpaqueExecutionEngine* LLVMExecutionEngineRef;
/*===-- Operations on generic values --------------------------------------===*/
LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
ulong N,
int IsSigned);
LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P);
LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef Ty, double N);
uint LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef);
ulong LLVMGenericValueToInt(LLVMGenericValueRef GenVal,
int IsSigned);
void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal);
double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal);
void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal);
/*===-- Operations on execution engines -----------------------------------===*/
int LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
LLVMModuleProviderRef MP,
char **OutError);
int LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
LLVMModuleProviderRef MP,
char **OutError);
int LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
LLVMModuleProviderRef MP,
char **OutError);
void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE);
void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE);
void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE);
int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
uint ArgC, /*const*/ char * /*const*/ *ArgV,
/*const*/ char * /*const*/ *EnvP);
LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
uint NumArgs,
LLVMGenericValueRef *Args);
void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F);
void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP);
int LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
LLVMModuleProviderRef MP,
LLVMModuleRef *OutMod, char **OutError);
int LLVMFindFunction(LLVMExecutionEngineRef EE, /*const*/ char *Name,
LLVMValueRef *OutFn);

View File

@@ -0,0 +1,62 @@
// Written in the D programming language by Tomas Lindquist Olsen 2008
// Extensions to the LLVM C interface for the D binding.
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
module llvm.c.Ext;
import llvm.c.Core;
// taken from llvm/Value.h
/// An enumeration for keeping track of the concrete subclass of Value that
/// is actually instantiated. Values of this enumeration are kept in the
/// Value classes SubclassID field. They are used for concrete type
/// identification.
enum LLVMValueKind : uint
{
Argument, /// This is an instance of Argument
BasicBlock, /// This is an instance of BasicBlock
Function, /// This is an instance of Function
GlobalAlias, /// This is an instance of GlobalAlias
GlobalVariable, /// This is an instance of GlobalVariable
UndefValue, /// This is an instance of UndefValue
ConstantExpr, /// This is an instance of ConstantExpr
ConstantAggregateZero, /// This is an instance of ConstantAggregateNull
ConstantInt, /// This is an instance of ConstantInt
ConstantFP, /// This is an instance of ConstantFP
ConstantArray, /// This is an instance of ConstantArray
ConstantStruct, /// This is an instance of ConstantStruct
ConstantVector, /// This is an instance of ConstantVector
ConstantPointerNull, /// This is an instance of ConstantPointerNull
InlineAsm, /// This is an instance of InlineAsm
Instruction /// This is an instance of Instruction
}
extern(C)
{
void LLVMEraseFromParent(LLVMValueRef I);
int LLVMIsTerminated(LLVMBasicBlockRef BB);
int LLVMHasPredecessors(LLVMBasicBlockRef BB);
int LLVMIsBasicBlockEmpty(LLVMBasicBlockRef BB);
void LLVMReplaceAllUsesWith(LLVMValueRef V, LLVMValueRef W);
void LLVMOptimizeModule(LLVMModuleRef M, int doinline);
void LLVMDumpType(LLVMTypeRef T);
LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, char* Name, LLVMTypeRef Type);
/// Return a strdup()ed string which must be free()ed
char* LLVMValueToString(LLVMValueRef v);
char* LLVMTypeToString(LLVMTypeRef ty); /// ditto
LLVMValueKind LLVMGetValueKind(LLVMValueRef Value);
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, char* Name);
int LLVMIsTypeAbstract(LLVMTypeRef T);
alias void function(void* handle, LLVMTypeRef newT) RefineCallback;
void LLVMRegisterAbstractTypeCallback(LLVMTypeRef T,
void* handle,
RefineCallback callback);
}

View File

@@ -0,0 +1,115 @@
// Converted to the D programming language by Tomas Lindquist Olsen 2008
// Original file header:
/*===-- llvm-c/Target.h - Target Lib C Iface --------------------*- C++ -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header declares the C interface to libLLVMTarget.a, which *|
|* implements target information. *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
\*===----------------------------------------------------------------------===*/
module llvm.c.Target;
import llvm.c.Core;
extern(C):
enum { LLVMBigEndian, LLVMLittleEndian };
alias int LLVMByteOrdering;
private
{
struct LLVM_OpaqueTargetData {}
struct LLVM_OpaqueStructLayout {}
}
typedef LLVM_OpaqueTargetData* LLVMTargetDataRef;
typedef LLVM_OpaqueStructLayout* LLVMStructLayoutRef;
/*===-- Target Data -------------------------------------------------------===*/
/** Creates target data from a target layout string.
See the constructor llvm::TargetData::TargetData. */
LLVMTargetDataRef LLVMCreateTargetData( /*const*/ char *StringRep);
/** Adds target data information to a pass manager. This does not take ownership
of the target data.
See the method llvm::PassManagerBase::add. */
void LLVMAddTargetData(LLVMTargetDataRef, LLVMPassManagerRef);
/** Converts target data to a target layout string. The string must be disposed
with LLVMDisposeMessage.
See the constructor llvm::TargetData::TargetData. */
char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
/** Returns the byte order of a target, either LLVMBigEndian or
LLVMLittleEndian.
See the method llvm::TargetData::isLittleEndian. */
LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
/** Returns the pointer size in bytes for a target.
See the method llvm::TargetData::getPointerSize. */
uint LLVMPointerSize(LLVMTargetDataRef);
/** Returns the integer type that is the same size as a pointer on a target.
See the method llvm::TargetData::getIntPtrType. */
LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef);
/** Computes the size of a type in bytes for a target.
See the method llvm::TargetData::getTypeSizeInBits. */
ulong LLVMSizeOfTypeInBits(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the storage size of a type in bytes for a target.
See the method llvm::TargetData::getTypeStoreSize. */
ulong LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI size of a type in bytes for a target.
See the method llvm::TargetData::getABITypeSize. */
ulong LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
uint LLVMABIAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the call frame alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
uint LLVMCallFrameAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
uint LLVMPreferredAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a global variable in bytes for a target.
See the method llvm::TargetData::getPreferredAlignment. */
uint LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef,
LLVMValueRef GlobalVar);
/** Computes the structure element that contains the byte offset for a target.
See the method llvm::StructLayout::getElementContainingOffset. */
uint LLVMElementAtOffset(LLVMTargetDataRef, LLVMTypeRef StructTy,
ulong Offset);
/** Computes the byte offset of the indexed struct element for a target.
See the method llvm::StructLayout::getElementContainingOffset. */
ulong LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
uint Element);
/** Struct layouts are speculatively cached. If a TargetDataRef is alive when
types are being refined and removed, this method must be called whenever a
struct type is removed to avoid a dangling pointer in this cache.
See the method llvm::TargetData::InvalidateStructLayoutInfo. */
void LLVMInvalidateStructLayout(LLVMTargetDataRef, LLVMTypeRef StructTy);
/** Deallocates a TargetData.
See the destructor llvm::TargetData::~TargetData. */
void LLVMDisposeTargetData(LLVMTargetDataRef);

View File

@@ -0,0 +1,216 @@
// Written in the D programming language by Frits van Bommel 2008
// Binding of llvm.c.ExecutionEngine for D.
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
module llvm.executionengine;
import llvm.c.Core;
import llvm.c.ExecutionEngine;
import llvm.llvm;
import llvm.util;
///
class GenericValue
{
///
private LLVMGenericValueRef value;
///
private this(LLVMGenericValueRef v)
{
value = v;
}
///
void dispose()
{
LLVMDisposeGenericValue(value);
value = null;
}
///
~this()
{
dispose(); // safe because value isn't on the GC heap and isn't exposed.
}
///
static GenericValue GetS(IntegerType ty, long N)
{
return new GenericValue(LLVMCreateGenericValueOfInt(ty.ll, N, true));
}
///
static GenericValue GetU(IntegerType ty, ulong N)
{
return new GenericValue(LLVMCreateGenericValueOfInt(ty.ll, N, false));
}
///
static GenericValue GetP(void* P)
{
return new GenericValue(LLVMCreateGenericValueOfPointer(P));
}
///
static GenericValue GetF(RealType ty, double N)
{
return new GenericValue(LLVMCreateGenericValueOfFloat(ty.ll, N));
}
///
uint intWidth()
{
return LLVMGenericValueIntWidth(value);
}
///
ulong toUInt()
{
return LLVMGenericValueToInt(value, false);
}
///
long toSInt()
{
return LLVMGenericValueToInt(value, true);
}
///
void* toPointer()
{
return LLVMGenericValueToPointer(value);
}
///
double toFloat(RealType ty)
{
return LLVMGenericValueToFloat(ty.ll, value);
}
}
///
class ExecutionEngine
{
///
private LLVMExecutionEngineRef ee;
///
private this(LLVMExecutionEngineRef ee)
{
this.ee = ee;
}
///
static ExecutionEngine Create(ModuleProvider mp)
{
LLVMExecutionEngineRef ee;
char* err;
if (LLVMCreateExecutionEngine(&ee, mp.ll, &err))
{
auto errmsg = from_stringz(err).dup;
LLVMDisposeMessage(err);
throw new LLVMException(errmsg);
}
return new ExecutionEngine(ee);
}
///
static ExecutionEngine CreateInterpreter(ModuleProvider mp)
{
LLVMExecutionEngineRef ee;
char* err;
if (LLVMCreateInterpreter(&ee, mp.ll, &err))
{
auto errmsg = from_stringz(err).dup;
LLVMDisposeMessage(err);
throw new LLVMException(errmsg);
}
return new ExecutionEngine(ee);
}
///
static ExecutionEngine CreateJIT(ModuleProvider mp)
{
LLVMExecutionEngineRef ee;
char* err;
if (LLVMCreateJITCompiler(&ee, mp.ll, &err))
{
auto errmsg = from_stringz(err).dup;
LLVMDisposeMessage(err);
throw new LLVMException(errmsg);
}
return new ExecutionEngine(ee);
}
///
void dispose()
{
LLVMDisposeExecutionEngine(ee);
ee = null;
}
///
~this()
{
dispose(); // safe because ee isn't on the GC heap and isn't exposed.
}
///
void runStaticConstructors()
{
LLVMRunStaticConstructors(ee);
}
///
void runStaticDestructors()
{
LLVMRunStaticDestructors(ee);
}
///
int runAsMain(Function f, char[][] args = null, char[][] env = null) {
auto argv = new char*[args.length];
foreach (size_t idx, ref arg; args)
{
argv[idx] = to_stringz(arg);
}
auto envp = new char*[env.length + 1];
foreach (size_t idx, ref envvar ; env)
{
envp[idx] = to_stringz(envvar);
}
envp[$-1] = null;
return LLVMRunFunctionAsMain(ee, f.value, argv.length, argv.ptr, envp.ptr);
}
///
GenericValue run(Function f, GenericValue[] args = null)
{
auto cargs = new LLVMGenericValueRef[args.length];
foreach (size_t idx, ref arg ; args)
{
cargs[idx] = arg.value;
}
auto result = LLVMRunFunction(ee, f.value, cargs.length, cargs.ptr);
return new GenericValue(result);
}
///
void freeMachineCodeForFunction(Function f)
{
LLVMFreeMachineCodeForFunction(ee, f.value);
}
///
void addModuleProvider(ModuleProvider mp)
{
LLVMAddModuleProvider(ee, mp.ll);
}
///
Module removeModuleProvider(ModuleProvider mp)
{
LLVMModuleRef mod;
char* err;
if (LLVMRemoveModuleProvider(ee, mp.ll, &mod, &err))
{
auto errmsg = from_stringz(err).dup;
LLVMDisposeMessage(err);
throw new LLVMException(errmsg);
}
return Module.GetExisting(mod);
}
///
Function findFunction(char[] name)
{
LLVMValueRef fn;
if (LLVMFindFunction(ee, to_stringz(name), &fn))
{
return null;
}
return new Function(fn, getTypeOf(fn));
}
}

996
tools/binding/llvm/llvm.d Normal file
View File

@@ -0,0 +1,996 @@
// Written in the D programming language by Tomas Lindquist Olsen 2008
// Binding of llvm.c.Core values for D.
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
module llvm.llvm;
import llvm.c.Core;
import llvm.c.Ext;
import llvm.c.BitWriter;
import llvm.c.BitReader;
import llvm.c.Analysis;
import llvm.c.Target;
public import llvm.type;
public import llvm.builder;
import llvm.util;
///
class LLVMException : Exception
{
this(char[] msg) {
super(msg);
}
}
version(Tango) {
import tango.stdc.stdlib;
}
else {
import std.c.stdlib;
}
///
alias LLVMLinkage Linkage;
///
alias LLVMIntPredicate IntPredicate;
///
alias LLVMRealPredicate RealPredicate;
///
alias LLVMCallConv CallConv;
///
alias LLVMVisibility Visibility;
///
alias LLVMValueKind ValueKind;
///
class Module
{
/// global registry for 1:1 mapping of ModuleRef's -> Module's
private static Module[LLVMModuleRef] registry;
///
private LLVMModuleRef mod;
const char[] name;
///
this(char[] nam)
{
name = nam;
mod = LLVMModuleCreateWithName(to_stringz(nam));
registry[mod] = this;
}
///
private this(LLVMModuleRef m)
{
name = null;
mod = m;
registry[m] = this;
}
///
static package Module GetExisting(LLVMModuleRef m)
{
if (auto p = m in registry)
{
return *p;
}
return new Module(m);
}
/// Create a module from bitcode. Returns the Module on success, null on failure.
static Module GetFromBitcode(char[] bitcodepath, ref char[] errmsg)
{
LLVMModuleRef mref;
LLVMMemoryBufferRef bref;
char* msg;
if (LLVMCreateMemoryBufferWithContentsOfFile(to_stringz(bitcodepath), &bref, &msg))
{
errmsg = from_stringz(msg).dup;
LLVMDisposeMessage(msg);
throw new LLVMException(errmsg);
}
scope(exit)
LLVMDisposeMemoryBuffer(bref);
if (LLVMParseBitcode(bref, &mref, &msg))
{
errmsg = from_stringz(msg).dup;
LLVMDisposeMessage(msg);
LLVMDisposeMemoryBuffer(bref);
throw new LLVMException(errmsg);
}
return new Module(mref);
}
/// important to call this when done
void dispose()
{
if (mod)
{
registry.remove(mod);
LLVMDisposeModule(mod);
mod = null;
}
}
///
char[] dataLayout()
{
assert(mod !is null);
return from_stringz(LLVMGetDataLayout(mod));
}
///
void dataLayout(char[] dl)
{
assert(mod !is null);
LLVMSetDataLayout(mod, to_stringz(dl));
}
///
char[] target()
{
assert(mod !is null);
return from_stringz(LLVMGetTarget(mod));
}
///
void target(char[] dl)
{
assert(mod !is null);
LLVMSetTarget(mod, to_stringz(dl));
}
///
bool addTypeName(char[] nam, Type t)
{
assert(mod !is null);
return LLVMAddTypeName(mod, to_stringz(nam), t.ll) != 0;
}
///
Type getTypeByName(char[] name) {
return getTypeOf(LLVMGetTypeByName(mod, to_stringz(name)));
}
///
void deleteTypeName(char[] nam)
{
assert(mod !is null);
LLVMDeleteTypeName(mod, to_stringz(nam));
}
///
GlobalVariable addGlobal(Type t, char[] nam)
{
assert(mod !is null);
auto c = LLVMAddGlobal(mod, t.ll, to_stringz(nam));
assert(c !is null);
return new GlobalVariable(c, getTypeOf(c));
}
/// Convenience method, type is taken to be that of the initializer
GlobalVariable addGlobal(Constant initializer, char[] name)
{
auto global = addGlobal(initializer.type, name);
global.initializer = initializer;
return global;
}
///
GlobalValue getNamedGlobal(char[] nam)
{
assert(mod !is null);
auto c = LLVMGetNamedGlobal(mod, to_stringz(nam));
if (c is null) return null;
return cast(GlobalValue)getValueOf(c);
}
///
Function addFunction(Type t, char[] nam)
{
assert(mod !is null);
auto c = LLVMAddFunction(mod, to_stringz(nam), t.ll);
assert(c !is null);
return new Function(c, getTypeOf(c));
}
///
Function getNamedFunction(char[] nam)
{
assert(mod !is null);
auto c = LLVMGetNamedFunction(mod, to_stringz(nam));
if (c is null) return null;
return cast(Function)getValueOf(c);
}
///
Function getOrInsertFunction(Type t, char[] nam)
{
assert(mod !is null);
auto c = LLVMGetOrInsertFunction(mod, to_stringz(nam), t.ll);
assert(c !is null);
return cast(Function)getValueOf(c);
}
/// Performs the same optimizations as `opt -std-compile-opts ...' would on the module.
/// If inline is true, function inlining will be performed.
void optimize(bool inline)
{
LLVMOptimizeModule(mod, inline);
}
/// Writes the module to an open file descriptor. Returns true on success.
bool writeBitcodeToFileHandle(int handle)
{
return (LLVMWriteBitcodeToFileHandle(mod, handle) == 0);
}
/// Writes the module to the specified path. Returns 0 on success.
bool writeBitcodeToFile(char[] path)
{
return (LLVMWriteBitcodeToFile(mod, to_stringz(path)) == 0);
}
/// Throws an exception if the module doesn't pass the LLVM verifier.
void verify()
{
char* msg;
if (LLVMVerifyModule(mod, LLVMVerifierFailureAction.ReturnStatus, &msg))
{
auto errmsg = from_stringz(msg).dup;
LLVMDisposeMessage(msg);
throw new LLVMException(errmsg);
}
}
}
class ModuleProvider
{
///
private LLVMModuleProviderRef mp;
///
private this(LLVMModuleProviderRef mp)
{
this.mp = mp;
}
/// Takes ownership of module, returns a ModuleProvider for it.
static ModuleProvider GetForModule(Module m)
{
auto mp = LLVMCreateModuleProviderForExistingModule(m.mod);
return new ModuleProvider(mp);
}
/// Destroys the provided module, unless this MP was passed to an ExecutionEngine.
void dispose()
{
LLVMDisposeModuleProvider(mp);
mp = null;
}
/// Returns a lazily-deserializing ModuleProvider
static ModuleProvider GetFromBitcode(char[] filename)
{
LLVMMemoryBufferRef buf;
char* msg;
if (LLVMCreateMemoryBufferWithContentsOfFile(to_stringz(filename), &buf, &msg))
{
auto errmsg = from_stringz(msg).dup;
LLVMDisposeMessage(msg);
throw new LLVMException(errmsg);
}
LLVMModuleProviderRef mp;
// Takes ownership of buffer ...
if (LLVMGetBitcodeModuleProvider(buf, &mp, &msg))
{
// ... unless it fails, in which case we need to clean it up ourselves
LLVMDisposeMemoryBuffer(buf);
auto errmsg = from_stringz(msg).dup;
LLVMDisposeMessage(msg);
throw new LLVMException(errmsg);
}
return new ModuleProvider(mp);
}
///
package LLVMModuleProviderRef ll()
{
return mp;
}
}
///
class Value
{
///
const LLVMValueRef value;
///
const Type type;
///
this(LLVMValueRef v, Type t=null) {
value = v;
if (t is null) t = getTypeOf(v);
type = t;
}
///
char[] toString() {
auto cstr = LLVMValueToString(value);
auto result = from_stringz(cstr).dup;
free(cstr);
return result;
}
///
ValueKind kind()
{
return LLVMGetValueKind(value);
}
///
char[] name()
{
return from_stringz(LLVMGetValueName(value));
}
///
void name(char[] s)
{
LLVMSetValueName(value, to_stringz(s));
}
///
void dump() {
LLVMDumpValue(value);
}
///
bool isConstant()
{
return LLVMIsConstant(value) != 0;
}
///
int opEquals(Object o)
{
auto v = cast(Value)o;
if (v is null) return 0;
if (value is v.value)
return 1;
return 0;
}
/// invalidates object
void eraseFromParent()
{
LLVMEraseFromParent(value);
}
/// ditto
void replaceAllUsesWith(Value newval)
{
LLVMReplaceAllUsesWith(value, newval.value);
}
/// only for call's
void callConv(uint CC)
{
LLVMSetInstructionCallConv(value, CC);
}
/// ditto
uint callConv()
{
return LLVMGetInstructionCallConv(value);
}
/// only for phi's
void addIncoming(Value[] inValues, BasicBlock[] inBlocks)
{
auto n = inValues.length;
assert(n == inBlocks.length);
auto v = new LLVMValueRef[n];
auto b = new LLVMBasicBlockRef[n];
for (size_t i=0; i<n; i++) {
v[i] = inValues[i].value;
b[i] = inBlocks[i].bb;
}
LLVMAddIncoming(value, v.ptr, b.ptr, n);
}
/// ditto
uint numIncoming()
{
return LLVMCountIncoming(value);
}
/// ditto
Value getIncomingValue(uint index)
{
return getValueOf(LLVMGetIncomingValue(value, index));
}
/// ditto
BasicBlock getIncomingBlock(uint index)
{
// TODO bb's should be unique as well
return new BasicBlock(LLVMGetIncomingBlock(value, index));
}
/// only for switch's
void addCase(Value onval, BasicBlock b)
{
LLVMAddCase(value, onval.value, b.bb);
}
}
///
Value getValueOf(LLVMValueRef v)
{
auto kind = LLVMGetValueKind(v);
switch(kind)
{
case ValueKind.Argument:
case ValueKind.InlineAsm:
case ValueKind.Instruction:
return new Value(v);
case ValueKind.Function:
return new Function(v, getTypeOf(v));
case ValueKind.GlobalVariable:
return new GlobalVariable(v, getTypeOf(v));
case ValueKind.GlobalAlias:
case ValueKind.UndefValue:
case ValueKind.ConstantExpr:
case ValueKind.ConstantAggregateZero:
case ValueKind.ConstantPointerNull:
return new Constant(v, getTypeOf(v));
case ValueKind.ConstantInt:
return new ConstantInt(v, getTypeOf(v));
case ValueKind.ConstantFP:
return new ConstantReal(v, getTypeOf(v));
case ValueKind.ConstantArray:
return new ConstantArray(v, getTypeOf(v));
case ValueKind.ConstantStruct:
return new ConstantStruct(v, getTypeOf(v));
case ValueKind.ConstantVector:
return new ConstantVector(v, getTypeOf(v));
case ValueKind.BasicBlock:
default:
assert(0);
}
}
private
{
template GenericConstUnaOp(char[] N)
{
const GenericConstUnaOp =
"Constant Get"~N~"(Constant v) {
auto c = LLVMConst"~N~"(v.value);
return cast(Constant)getValueOf(c);
}";
}
template GenericConstBinOp(char[] N)
{
const GenericConstBinOp =
"Constant Get"~N~"(Constant l, Constant r) {
auto c = LLVMConst"~N~"(l.value, r.value);
return cast(Constant)getValueOf(c);
}";
}
template GenericConstTriOp(char[] N)
{
const GenericConstTriOp =
"Constant Get"~N~"(Constant s, Constant t, Constant u) {
auto c = LLVMConst"~N~"(s.value, t.value, u.value);
return cast(Constant)getValueOf(c);
}";
}
template GenericConstCast(char[] N)
{
const GenericConstCast =
"Constant Get"~N~"(Constant v, Type t) {
auto c = LLVMConst"~N~"(v.value, t.ll);
return cast(Constant)getValueOf(c);
}";
}
template GenericConstCmp(char[] PRED, char[] N)
{
const GenericConstCmp =
"Constant Get"~N~"("~PRED~"Predicate p, Constant l, Constant r) {
auto c = LLVMConst"~N~"(p, l.value, r.value);
return cast(Constant)getValueOf(c);
}";
}
template StringDistribute(alias T, U...)
{
static if (!U.length)
const char[] StringDistribute="";
else
const char[] StringDistribute = T!(U[0]) ~ StringDistribute!(T, U[1..$]);
}
}
///
class Constant : Value
{
///
protected this(LLVMValueRef v, Type t)
{
super(v,t);
}
///
static Constant GetNull(Type t)
{
return cast(Constant)getValueOf(LLVMConstNull(t.ll));
}
/// only for int/vector
static Constant GetAllOnes(Type t)
{
return cast(Constant)getValueOf(LLVMConstAllOnes(t.ll));
}
///
static Constant GetUndef(Type t)
{
return cast(Constant)getValueOf(LLVMGetUndef(t.ll));
}
///
static ConstantInt GetTrue()
{
return ConstantInt.GetU(Type.Int1, 1);
}
///
static ConstantInt GetFalse()
{
return ConstantInt.GetU(Type.Int1, 0);
}
///
bool isNull()
{
return LLVMIsNull(value) != 0;
}
///
bool isUndef()
{
return LLVMIsUndef(value) != 0;
}
static
{
///
mixin(StringDistribute!(GenericConstUnaOp,
"Neg","Not"
));
///
mixin(StringDistribute!(GenericConstBinOp,
"Add","Sub","Mul","UDiv","SDiv","FDiv","URem","SRem","FRem",
"And","Or","Xor","Shl","LShr","AShr",
"ExtractElement"
));
///
mixin(StringDistribute!(GenericConstCast,
"Trunc","SExt","ZExt","FPTrunc","FPExt",
"UIToFP","SIToFP","FPToUI","FPToSI",
"PtrToInt","IntToPtr","BitCast"
));
///
mixin(StringDistribute!(GenericConstTriOp,
"Select",
"InsertElement",
"ShuffleVector"
));
///
mixin(GenericConstCmp!("Int","ICmp"));
///
mixin(GenericConstCmp!("Real","FCmp"));
///
Constant GetGEP(Constant ptr, Constant[] idxs)
{
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 GetSizeOf(Type t)
{
return cast(Constant)getValueOf(LLVMSizeOf(t.ll));
}
}
}
///
abstract class ScalarConstant : Constant
{
///
protected this(LLVMValueRef v, Type t)
{
super(v, t);
}
}
///
class ConstantInt : ScalarConstant
{
///
private this(LLVMValueRef v, Type t)
{
super(v, t);
}
///
static ConstantInt Get(Type t, ulong N, bool signExt)
{
auto c = LLVMConstInt(t.ll, N, signExt);
return new ConstantInt(c, t);
}
///
static ConstantInt GetS(Type t, long N)
{
return Get(t, cast(ulong)N, true);
}
///
static ConstantInt GetU(Type t, ulong N)
{
return Get(t, N, false);
}
}
///
class ConstantReal : ScalarConstant
{
///
private this(LLVMValueRef v, Type t)
{
super(v, t);
}
///
static ConstantReal Get(Type t, real N)
{
auto c = LLVMConstReal(t.ll, N);
return new ConstantReal(c, t);
}
}
///
abstract class CompositeConstant : Constant
{
///
protected this(LLVMValueRef v, Type t)
{
super(v, t);
}
}
///
class ConstantArray : CompositeConstant
{
///
private this(LLVMValueRef v, Type t)
{
super(v, t);
}
///
static ConstantArray Get(Type eltty, Constant[] vals)
{
auto p = new LLVMValueRef[vals.length];
foreach(i,v; vals) p[i] = v.value;
auto c = LLVMConstArray(eltty.ll, p.ptr, p.length);
return new ConstantArray(c, getTypeOf(c));
}
///
static ConstantArray GetString(char[] str, bool nullterm)
{
auto len = str.length + nullterm;
auto c = LLVMConstString(str.ptr, str.length, !nullterm);
return new ConstantArray(c, getTypeOf(c));
}
}
///
class ConstantStruct : CompositeConstant
{
///
private this(LLVMValueRef v, Type t)
{
super(v, t);
}
///
static ConstantStruct Get(Constant[] vals, bool packed=false)
{
auto p = new LLVMValueRef[vals.length];
foreach(i,v; vals) p[i] = v.value;
auto c = LLVMConstStruct(p.ptr, p.length, packed);
return new ConstantStruct(c, getTypeOf(c));
}
}
///
class ConstantVector : CompositeConstant
{
///
private this(LLVMValueRef v, Type t)
{
super(v, t);
}
///
static ConstantVector Get(ScalarConstant[] vals)
{
auto p = new LLVMValueRef[vals.length];
foreach(i,v; vals) p[i] = v.value;
auto c = LLVMConstVector(p.ptr, p.length);
return new ConstantVector(c, getTypeOf(c));
}
}
///
abstract class GlobalValue : Constant
{
///
private this(LLVMValueRef v, Type t) {
super(v, t);
}
///
bool isDeclaration()
{
return LLVMIsDeclaration(value) != 0;
}
///
Linkage linkage()
{
return LLVMGetLinkage(value);
}
///
void linkage(Linkage l)
{
LLVMSetLinkage(value, l);
}
///
char[] section()
{
return from_stringz(LLVMGetSection(value));
}
///
void section(char[] s)
{
LLVMSetSection(value, to_stringz(s));
}
///
Visibility visibility()
{
return LLVMGetVisibility(value);
}
///
void visibility(Visibility v)
{
LLVMSetVisibility(value, v);
}
///
uint alignment()
{
return LLVMGetAlignment(value);
}
///
void alignment(uint bytes)
{
LLVMSetAlignment(value, bytes);
}
}
///
class GlobalVariable : GlobalValue
{
/// TODO:
/// void DeleteGlobal(ValueRef GlobalVar);
///
private this(LLVMValueRef v, Type t) {
super(v, t);
}
///
bool hasInitializer()
{
return LLVMHasInitializer(value) != 0;
}
///
Constant initializer()
{
auto c = LLVMGetInitializer(value);
if (c is null) return null;
return cast(Constant)getValueOf(c);
}
///
void initializer(Constant c)
{
LLVMSetInitializer(value, c.value);
}
///
bool threadLocal()
{
return LLVMIsThreadLocal(value) != 0;
}
///
void threadLocal(bool b)
{
LLVMSetThreadLocal(value, b);
}
///
bool globalConstant()
{
return LLVMIsGlobalConstant(value) != 0;
}
///
void globalConstant(bool b)
{
LLVMSetGlobalConstant(value, b);
}
}
///
class Function : GlobalValue
{
/// TODO:
/// void GetParams(ValueRef Fn, ValueRef *Params);
/// void GetBasicBlocks(ValueRef Fn, BasicBlockRef *BasicBlocks);
///
package this(LLVMValueRef v, Type t) {
super(v, t);
}
///
void eraseFromParent()
{
LLVMDeleteFunction(value);
}
///
uint numParams()
{
return LLVMCountParams(value);
}
///
Value getParam(uint idx)
{
auto v = LLVMGetParam(value, idx);
assert(v !is null);
return getValueOf(v);
}
///
uint intrinsicID()
{
return LLVMGetIntrinsicID(value);
}
///
uint callConv()
{
return LLVMGetFunctionCallConv(value);
}
///
void callConv(uint cc)
{
LLVMSetFunctionCallConv(value, cc);
}
///
char[] collector()
{
return from_stringz(LLVMGetCollector(value));
}
///
void collector(char[] col)
{
LLVMSetCollector(value, to_stringz(col));
}
///
uint numBasicBlocks()
{
return LLVMCountBasicBlocks(value);
}
///
static BasicBlock InsertBasicBlock(BasicBlock bb, char[] name)
{
auto b = LLVMInsertBasicBlock(bb.bb, to_stringz(name));
assert(b !is null);
return new BasicBlock(b);
}
///
BasicBlock appendBasicBlock(char[] name)
{
auto b = LLVMAppendBasicBlock(value, to_stringz(name));
assert(b !is null);
return new BasicBlock(b);
}
///
BasicBlock getEntryBasicBlock()
{
auto b = LLVMGetEntryBasicBlock(value);
if (b is null) return null;
return new BasicBlock(b);
}
/// Throws an exception if the function doesn't pass the LLVM verifier.
void verify()
{
if (LLVMVerifyFunction(value, LLVMVerifierFailureAction.ReturnStatus))
{
auto exceptionmsg = "Function failed to verify (" ~ name ~ ")";
throw new LLVMException(exceptionmsg);
}
}
}
///
class BasicBlock
{
///
LLVMBasicBlockRef bb;
///
this(LLVMBasicBlockRef b)
{
assert(b !is null);
bb = b;
}
///
this(Value v)
{
assert(LLVMValueIsBasicBlock(v.value));
bb = LLVMValueAsBasicBlock(v.value);
}
///
override int opEquals(Object o) {
auto block = cast(BasicBlock) o;
if (!block)
return false;
return bb == block.bb;
}
///
void dispose()
{
LLVMDeleteBasicBlock(bb);
bb = null;
}
///
Function getParent() {
assert(bb !is null);
auto func = LLVMGetBasicBlockParent(bb);
if (!func) return null;
return new Function(func, getTypeOf(func));
}
///
Value asValue()
{
assert(bb !is null);
auto v = LLVMBasicBlockAsValue(bb);
return new Value(v, Type.Label);
}
///
bool terminated()
{
assert(bb !is null);
return (LLVMIsTerminated(bb) != 0);
}
///
bool hasPredecessors()
{
assert(bb !is null);
return (LLVMHasPredecessors(bb) != 0);
}
///
bool empty()
{
assert(bb !is null);
return (LLVMIsBasicBlockEmpty(bb) != 0);
}
}
///
class TargetData
{
///
private LLVMTargetDataRef target;
///
private this(LLVMTargetDataRef td)
{
target = td;
}
///
static TargetData Get(char[] str)
{
return new TargetData(LLVMCreateTargetData(to_stringz(str)));
}
///
static TargetData Get(Module M)
{
return new TargetData(LLVMCreateTargetData(to_stringz(M.dataLayout)));
}
/// invalidates object
void dispose()
{
LLVMDisposeTargetData(target);
target = null;
}
///
size_t getABITypeSize(Type T)
{
return LLVMABISizeOfType(target, T.ll);
}
}

587
tools/binding/llvm/type.d Normal file
View File

@@ -0,0 +1,587 @@
// Written in the D programming language by Tomas Lindquist Olsen 2008
// Binding of llvm.c.Core types for D.
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
module llvm.type;
import llvm.c.Core;
import llvm.c.Ext;
import llvm.util;
// we need free
version(Tango) {
import tango.stdc.stdlib;
}
else {
import std.c.stdlib;
}
/**
* Each value in the IR has a type, an instance of [lltype]. See the
* llvm::Type class.
*/
class Type
{
/// global registry for 1:1 mapping of LLVMTypeRef's -> Type's
private static Type[LLVMTypeRef] registry;
///
alias LLVMTypeKind Kind;
///
private LLVMTypeRef type;
// used to detect if the kind of type has changed after refinement
private const Kind cached_kind;
///
private this(LLVMTypeRef t) {
assert(t !is null);
type = t;
cached_kind = kind;
assert((t in registry) is null, "Duplicate type");
registry[t] = this;
if (isAbstract())
registerAbstractType();
}
///
void registerAbstractType() {
static extern(C) void onTypeRefine(void* old, LLVMTypeRef newTypeRef) {
Type T = cast(Type) old;
registry.remove(T.type);
if (LLVMGetTypeKind(newTypeRef) == T.cached_kind) {
// The kind of type didn't change, so try to update and
// recycle the Type by updating the LLVMTypeRef.
T.type = newTypeRef;
if (newTypeRef in registry) {
// We can't update the Type if it already exists
// but is abstract since doing so requires we pass
// a pointer to an object that will be stored where
// the GC can't see it. (If it's not in the registry
// it's safe because we'll put a reference in there
// for the GC to find, and if it's not abstract
// there's no need for the pointer to get out)
if (T.isAbstract())
T.type = null;
} else {
registry[newTypeRef] = T;
// This callback only gets called once per type. If
// we recycle the old Type object for another
// abstract type we need to re-register it with the
// new LLVMTypeRef.
if (T.isAbstract())
T.registerAbstractType();
}
} else {
// Kind of type has changed, invalidate the old object.
T.type = null;
// The new Type will get entered into the registry when
// it's first needed.
}
}
// Make sure we there's a reference to the passed object that
// the GC can see in the registry.
auto p = this.type in registry;
assert((p !is null) && (*p is this), "Can't safely register an abstract type that isn't in the registry");
LLVMRegisterAbstractTypeCallback(this.type,
cast(void*) *p,
&onTypeRefine);
}
///
char[] toString() {
auto cstr = LLVMTypeToString(type);
auto result = from_stringz(cstr).dup;
free(cstr);
return result;
}
///
Kind kind() {
return LLVMGetTypeKind(type);
}
///
bool isAbstract() {
return LLVMIsTypeAbstract(type) != 0;
}
/** Note: may invalidate the current object. Returns the refined Type
* if it can, or null otherwise.
*/
Type refineAbstractType(Type to) {
assert(isAbstract());
LLVMRefineAbstractType(type, to.type);
// Either type will do. Go through the registry to try to use the
// "canonical" Type object for the type.
if (type != null && to.type != null) {
assert(type == to.type, "After refinement they should be equal, right?");
return registry[type];
} else if (type != null) {
return registry[type];
} else if (to.type != null) {
return registry[to.type];
}
// Both types were invalidated. Is this even possible?
return null;
}
///
static IntegerType IntType(uint bits) {
return IntegerType.Get(bits);
}
///
static const Type Void,Label;
///
static const IntegerType Int1, Int8, Int16, Int32, Int64, Size_t;
///
static const RealType Float,Double,X86_FP80, FP128, PPC_FP128;
///
static this()
{
Void = new Type(LLVMVoidType());
Label = new Type(LLVMLabelType());
Int1 = new IntegerType(LLVMInt1Type());
Int8 = new IntegerType(LLVMInt8Type());
Int16 = new IntegerType(LLVMInt16Type());
Int32 = new IntegerType(LLVMInt32Type());
Int64 = new IntegerType(LLVMInt64Type());
if (size_t.sizeof == 4)
Size_t = Int32;
else
Size_t = Int64;
Float = new RealType(LLVMFloatType());
Double = new RealType(LLVMDoubleType());
X86_FP80 = new RealType(LLVMX86FP80Type());
FP128 = new RealType(LLVMFP128Type());
PPC_FP128 = new RealType(LLVMPPCFP128Type());
}
///
LLVMTypeRef ll()
{
return type;
}
///
void dump()
{
LLVMDumpType(type);
}
///
bool isBasic()
{
auto k = kind;
if (k == Kind.Struct || k == Kind.Array || k == Kind.Function)
return false;
return true;
}
}
///
class IntegerType : Type
{
///
private this(LLVMTypeRef t)
{
super(t);
}
///
static IntegerType Get(uint nbits)
{
if (nbits == 1)
return Type.Int1;
else if (nbits == 8)
return Type.Int8;
else if (nbits == 16)
return Type.Int16;
else if (nbits == 32)
return Type.Int32;
else if (nbits == 64)
return Type.Int64;
else
{
auto t = LLVMIntType(nbits);
auto ptr = t in registry;
if (ptr !is null)
return cast(IntegerType)*ptr;
auto it = new IntegerType(t);
return it;
}
}
///
uint numBits()
{
return LLVMGetIntTypeWidth(type);
}
}
///
class RealType : Type
{
///
private this(LLVMTypeRef t)
{
super(t);
}
}
///
class FunctionType : Type
{
///
private Type ret;
private const Type[] params;
///
protected this(LLVMTypeRef t, Type r, Type[] pars)
{
super(t);
ret = r;
params = pars;
}
///
static FunctionType Get(Type r, Type[] pars, bool vararg=false)
{
auto p = new LLVMTypeRef[pars.length];
foreach(i,v; pars) p[i] = v.ll;
auto t = LLVMFunctionType(r.ll, p.ptr, p.length, vararg);
auto ptr = t in registry;
if (ptr !is null)
return cast(FunctionType)*ptr;
auto ft = new FunctionType(t, r, pars);
return ft;
}
///
bool isVarArg()
{
return (LLVMIsFunctionVarArg(type) != 0);
}
///
Type returnType()
{
if (!ret.type)
ret = getTypeOf(LLVMGetReturnType(type));
return ret;
}
///
Type[] paramTypes()
{
foreach (par ; params) {
if (!par.type) {
updateParams();
}
}
return params;
}
///
Type getParamType(uint idx)
{
auto par = params[idx];
if (!par.type) {
updateParams();
par = params[idx];
}
return params[idx];
}
///
uint numParams()
{
return params.length;
}
/** Called when one or more of the parameter types have been
* invalidated.
*/
private void updateParams() {
assert (LLVMCountParamTypes(type) == params.length);
auto llparams = new LLVMTypeRef[params.length];
LLVMGetParamTypes(type, llparams.ptr);
foreach (idx, llpar ; llparams) {
params[idx] = getTypeOf(llpar);
}
}
}
///
class StructType : Type
{
///
private this(LLVMTypeRef t)
{
super(t);
}
///
static StructType Get(Type[] elems, bool packed=false)
{
auto tys = new LLVMTypeRef[elems.length];
foreach(i,e; elems) tys[i] = e.ll;
auto t = LLVMStructType(tys.ptr, tys.length, packed);
auto ptr = t in registry;
if (ptr !is null)
return cast(StructType)*ptr;
auto st = new StructType(t);
return st;
}
///
bool packed()
{
return (LLVMIsPackedStruct(type) != 0);
}
///
uint numElements()
{
return LLVMCountStructElementTypes(type);
}
///
Type[] elementTypes()
{
auto n = numElements();
auto dst = new LLVMTypeRef[n];
LLVMGetStructElementTypes(type, dst.ptr);
auto e = new Type[n];
for(auto i=0; i<n; i++)
e[i] = getTypeOf(dst[i]);
return e;
}
}
///
abstract class SequenceType : Type
{
///
private Type elemty;
///
private this(LLVMTypeRef t, Type elemty)
{
super(t);
this.elemty = elemty;
}
///
Type elementType()
{
if (!elemty.type)
elemty = getTypeOf(LLVMGetElementType(type));
return elemty;
}
}
///
class PointerType : SequenceType
{
///
private const uint addrSpace;
///
protected this(LLVMTypeRef t, Type e, uint as)
{
super(t, e);
addrSpace = as;
}
///
static PointerType Get(Type e, uint as=0)
{
auto t = LLVMPointerType(e.ll, as);
auto ptr = t in registry;
if (ptr !is null)
return cast(PointerType)*ptr;
auto pt = new PointerType(t, e, as);
return pt;
}
///
uint addressSpace()
{
return addrSpace;
}
}
///
class ArrayType : SequenceType
{
///
private const uint arrlen;
///
protected this(LLVMTypeRef t, Type e, uint l)
{
super(t, e);
arrlen = l;
}
///
static ArrayType Get(Type e, uint l)
{
auto t = LLVMArrayType(e.ll, l);
auto ptr = t in registry;
if (ptr !is null) return cast(ArrayType)*ptr;
auto at = new ArrayType(t, e, l);
return at;
}
///
uint length()
{
return arrlen;
}
}
///
class VectorType : SequenceType
{
///
private const uint vecsz;
///
protected this(LLVMTypeRef t, Type e, uint s)
{
super(t, e);
vecsz = s;
}
///
static VectorType Get(Type e, uint s)
{
auto t = LLVMVectorType(e.ll, s);
auto ptr = t in registry;
if (ptr !is null) return cast(VectorType)*ptr;
auto at = new VectorType(t, e, s);
return at;
}
///
uint vectorSize()
{
return vecsz;
}
}
///
class OpaqueType : Type
{
///
private this(LLVMTypeRef t)
{
super(t);
}
///
static OpaqueType Get()
{
auto t = LLVMOpaqueType();
auto ot = new OpaqueType(t);
return ot;
}
///
private static OpaqueType Get(LLVMTypeRef t)
{
auto ptr = t in registry;
if (ptr !is null)
return cast(OpaqueType)*ptr;
auto ot = new OpaqueType(t);
return ot;
}
}
///
class TypeHandle
{
///
private LLVMTypeHandleRef handle;
///
this()
{
handle = LLVMCreateTypeHandle(LLVMOpaqueType());
}
///
Type resolve()
{
assert(handle !is null);
auto t = LLVMResolveTypeHandle(handle);
return getTypeOf(t);
}
///
void refine(Type to)
{
assert(handle !is null);
auto t = LLVMResolveTypeHandle(handle);
LLVMRefineType(t, to.ll);
}
///
void dispose()
{
assert(handle !is null);
LLVMDisposeTypeHandle(handle);
handle = null;
}
///
~this()
{
if (handle)
{
// Safe because handle isn't on the GC heap and isn't exposed.
dispose();
}
}
}
///
Type getTypeOf(LLVMValueRef v)
{
return getTypeOf(LLVMTypeOf(v));
}
///
Type getTypeOf(LLVMTypeRef ty)
{
// first check the registry
auto ptr = ty in Type.registry;
if (ptr !is null) return *ptr;
// reconstruct D type from C type and query it
auto kind = LLVMGetTypeKind(ty);
switch(kind)
{
case Type.Kind.Integer:
auto bw = LLVMGetIntTypeWidth(ty);
return Type.IntType(bw);
case Type.Kind.Pointer:
auto e = LLVMGetElementType(ty);
auto a = LLVMGetPointerAddressSpace(ty);
return PointerType.Get(getTypeOf(e), a);
case Type.Kind.Struct:
auto t = new StructType(ty);
return t;
// was broken for recursive types ...
/*auto n = LLVMCountStructElementTypes(ty);
auto e = new LLVMTypeRef[n];
LLVMGetStructElementTypes(ty, e.ptr);
auto p = LLVMIsPackedStruct(ty);
auto t = new Type[n];
foreach(i,et; e) t[i] = getTypeOf(et);
return StructType.Get(t,p!=0);*/
case Type.Kind.Opaque:
return OpaqueType.Get(ty);
case Type.Kind.Function:
auto llr = LLVMGetReturnType(ty);
auto lla = new LLVMTypeRef[LLVMCountParamTypes(ty)];
LLVMGetParamTypes(ty, lla.ptr);
auto args = new Type[lla.length];
foreach(i,a; lla) args[i] = getTypeOf(a);
int isvararg = LLVMIsFunctionVarArg(ty);
return FunctionType.Get(getTypeOf(llr), args, isvararg!=0);
case Type.Kind.Array:
auto lle = LLVMGetElementType(ty);
auto len = LLVMGetArrayLength(ty);
return ArrayType.Get(getTypeOf(lle), len);
case Type.Kind.Vector:
auto lle = LLVMGetElementType(ty);
auto sz = LLVMGetVectorSize(ty);
return VectorType.Get(getTypeOf(lle), sz);
case Type.Kind.Void:
case Type.Kind.Float:
case Type.Kind.Double:
case Type.Kind.X86_FP80:
case Type.Kind.FP128:
case Type.Kind.PPC_FP128:
case Type.Kind.Label:
assert(0, "basic type not in registry");
}
}

30
tools/binding/llvm/util.d Normal file
View File

@@ -0,0 +1,30 @@
// Written in the D programming language by Tomas Lindquist Olsen 2008
// Binding of llvm.c.Core values for D.
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
module llvm.util;
//we need <cstring>
version(Tango) {
import tango.stdc.string;
}
else {
import std.c.string;
}
///
char[] from_stringz(char* p)
{
if (p is null)
return "";
return p[0..strlen(p)];
}
///
char* to_stringz(char[] s)
{
return (s~\0).ptr;
}

View File

@@ -0,0 +1,47 @@
// simple hello world sample of D LLVM
module llvmsample1;
import llvm.llvm;
void main()
{
// create module
auto m = new Module("sample1");
scope(exit) m.dispose();
// declare string
auto chello = ConstantArray.GetString("Hello World!\n", true);
auto hello = m.addGlobal(chello.type, "hellostring");
hello.initializer = chello;
hello.linkage = Linkage.Internal;
hello.globalConstant = true;
// declare printf
auto printfType = FunctionType.Get(Type.Int32, [ PointerType.Get(Type.Int8) ], true);
auto llprintf = m.addFunction(printfType, "printf");
// declare main
auto mainType = FunctionType.Get(Type.Int32, null);
auto llmain = m.addFunction(mainType, "main");
// create builder
auto b = new Builder;
scope(exit) b.dispose();
// create main body block
auto bb = llmain.appendBasicBlock("entry");
b.positionAtEnd(bb);
// call printf
auto zero = ConstantInt.GetU(Type.Int32, 0);
auto helloptr = b.buildGEP(hello, [ zero, zero ], "str");
helloptr.dump();
auto args = [ helloptr ];
auto call = b.buildCall(llprintf, args, "");
// return 0
b.buildRet(ConstantInt.GetS(Type.Int32, 0));
// write bitcode
m.writeBitcodeToFile("sample1.bc");
}

View File

@@ -0,0 +1,18 @@
// simple test of recursive types.
module llvmsample2;
import llvm.llvm;
void main()
{
auto th = new TypeHandle();
auto s = StructType.Get([ PointerType.Get(th.resolve) ], false);
th.refine(s);
s.dump();
th.dispose();
auto t = getTypeOf(s.ll);
t.dump();
assert(s is t);
}

View File

@@ -0,0 +1,35 @@
// simple example that shows off getting D wrappers from C values.
module llvmsample3;
import llvm.c.Core;
import llvm.llvm;
void main()
{
auto m = new Module("sample3");
// global int32
auto gi = m.addGlobal(Type.Int32, "myint");
gi.initializer = ConstantInt.GetU(Type.Int32, 42);
// this is not a cached value, it's recreated dynamically
auto _i = gi.initializer;
auto ci = cast(ConstantInt)_i;
assert(ci !is null);
ci.dump;
// global struct
auto st = StructType.Get([Type.Double,Type.Double,Type.Double]);
auto gs = m.addGlobal(st, "mystruct");
auto elems = new Constant[3];
foreach(i,ref e; elems)
e = ConstantReal.Get(Type.Double, i+1);
gs.initializer = ConstantStruct.Get(elems);
// again this is not a cached value.
auto s = gs.initializer;
auto cs = cast(ConstantStruct)s;
assert(cs !is null);
cs.dump;
}

View File

@@ -0,0 +1,9 @@
#!/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`
rm -f libllvm-c-ext.a
ar rc libllvm-c-ext.a llvm-ext.o llvm-opt.o llvm-typemonitor.o
ranlib libllvm-c-ext.a