mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-20 14:53:14 +01:00
Committing LLVM binding for D as it currently exists in the SVN repository.
This commit is contained in:
72
tools/binding/LICENSE.TXT
Normal file
72
tools/binding/LICENSE.TXT
Normal 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
30
tools/binding/dsss.conf
Normal 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
|
||||
87
tools/binding/llvm-ext.cpp
Normal file
87
tools/binding/llvm-ext.cpp
Normal 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
|
||||
75
tools/binding/llvm-opt.cpp
Normal file
75
tools/binding/llvm-opt.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
45
tools/binding/llvm-typemonitor.cpp
Normal file
45
tools/binding/llvm-typemonitor.cpp
Normal 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);
|
||||
}
|
||||
192
tools/binding/llvm/builder.d
Normal file
192
tools/binding/llvm/builder.d
Normal 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)));
|
||||
}
|
||||
}
|
||||
42
tools/binding/llvm/c/Analysis.d
Normal file
42
tools/binding/llvm/c/Analysis.d
Normal 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);
|
||||
38
tools/binding/llvm/c/BitReader.d
Normal file
38
tools/binding/llvm/c/BitReader.d
Normal 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);
|
||||
33
tools/binding/llvm/c/BitWriter.d
Normal file
33
tools/binding/llvm/c/BitWriter.d
Normal 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
670
tools/binding/llvm/c/Core.d
Normal 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);
|
||||
94
tools/binding/llvm/c/ExecutionEngine.d
Normal file
94
tools/binding/llvm/c/ExecutionEngine.d
Normal 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);
|
||||
62
tools/binding/llvm/c/Ext.d
Normal file
62
tools/binding/llvm/c/Ext.d
Normal 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);
|
||||
}
|
||||
115
tools/binding/llvm/c/Target.d
Normal file
115
tools/binding/llvm/c/Target.d
Normal 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);
|
||||
216
tools/binding/llvm/executionengine.d
Normal file
216
tools/binding/llvm/executionengine.d
Normal 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
996
tools/binding/llvm/llvm.d
Normal 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
587
tools/binding/llvm/type.d
Normal 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
30
tools/binding/llvm/util.d
Normal 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;
|
||||
}
|
||||
|
||||
47
tools/binding/llvmsample1.d
Normal file
47
tools/binding/llvmsample1.d
Normal 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");
|
||||
}
|
||||
18
tools/binding/llvmsample2.d
Normal file
18
tools/binding/llvmsample2.d
Normal 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);
|
||||
}
|
||||
35
tools/binding/llvmsample3.d
Normal file
35
tools/binding/llvmsample3.d
Normal 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;
|
||||
}
|
||||
9
tools/binding/prebuild.sh
Normal file
9
tools/binding/prebuild.sh
Normal 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
|
||||
Reference in New Issue
Block a user