mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-09-17 19:07:05 +02:00
Committing LLVM binding for D as it currently exists in the SVN repository.
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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