aboutsummaryrefslogtreecommitdiffstats
path: root/bindings
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-12-01 14:51:49 -0800
committerStephen Hines <srhines@google.com>2014-12-02 16:08:10 -0800
commit37ed9c199ca639565f6ce88105f9e39e898d82d0 (patch)
tree8fb36d3910e3ee4c4e1b7422f4f017108efc52f5 /bindings
parentd2327b22152ced7bc46dc629fc908959e8a52d03 (diff)
downloadexternal_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.zip
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.gz
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.bz2
Update aosp/master LLVM for rebase to r222494.
Change-Id: Ic787f5e0124df789bd26f3f24680f45e678eef2d
Diffstat (limited to 'bindings')
-rw-r--r--bindings/Makefile6
-rw-r--r--bindings/go/README.txt53
-rwxr-xr-xbindings/go/build.sh28
-rw-r--r--bindings/go/conftest.go16
-rw-r--r--bindings/go/llvm/DIBuilderBindings.cpp222
-rw-r--r--bindings/go/llvm/DIBuilderBindings.h123
-rw-r--r--bindings/go/llvm/IRBindings.cpp47
-rw-r--r--bindings/go/llvm/IRBindings.h37
-rw-r--r--bindings/go/llvm/InstrumentationBindings.cpp42
-rw-r--r--bindings/go/llvm/InstrumentationBindings.h38
-rw-r--r--bindings/go/llvm/SupportBindings.cpp27
-rw-r--r--bindings/go/llvm/SupportBindings.h30
-rw-r--r--bindings/go/llvm/analysis.go68
-rw-r--r--bindings/go/llvm/bitreader.go50
-rw-r--r--bindings/go/llvm/bitwriter.go39
-rw-r--r--bindings/go/llvm/dibuilder.go492
-rw-r--r--bindings/go/llvm/executionengine.go163
-rw-r--r--bindings/go/llvm/executionengine_test.go93
-rw-r--r--bindings/go/llvm/ir.go1824
-rw-r--r--bindings/go/llvm/ir_test.go95
-rw-r--r--bindings/go/llvm/linker.go39
-rw-r--r--bindings/go/llvm/llvm_config.go.in12
-rw-r--r--bindings/go/llvm/llvm_dep.go19
-rw-r--r--bindings/go/llvm/string.go105
-rw-r--r--bindings/go/llvm/string_test.go28
-rw-r--r--bindings/go/llvm/support.go54
-rw-r--r--bindings/go/llvm/target.go300
-rw-r--r--bindings/go/llvm/transforms_instrumentation.go43
-rw-r--r--bindings/go/llvm/transforms_ipo.go42
-rw-r--r--bindings/go/llvm/transforms_pmbuilder.go48
-rw-r--r--bindings/go/llvm/transforms_scalar.go45
-rw-r--r--bindings/go/llvm/version.go21
-rw-r--r--bindings/ocaml/Makefile4
-rw-r--r--bindings/ocaml/Makefile.ocaml121
-rw-r--r--bindings/ocaml/all_backends/Makefile4
-rw-r--r--bindings/ocaml/analysis/Makefile8
-rw-r--r--bindings/ocaml/analysis/analysis_ocaml.c9
-rw-r--r--bindings/ocaml/analysis/llvm_analysis.ml2
-rw-r--r--bindings/ocaml/analysis/llvm_analysis.mli2
-rw-r--r--bindings/ocaml/backends/META.llvm_backend.in1
-rw-r--r--bindings/ocaml/backends/backend_ocaml.c9
-rw-r--r--bindings/ocaml/bitreader/Makefile8
-rw-r--r--bindings/ocaml/bitreader/bitreader_ocaml.c56
-rw-r--r--bindings/ocaml/bitreader/llvm_bitreader.ml17
-rw-r--r--bindings/ocaml/bitreader/llvm_bitreader.mli3
-rw-r--r--bindings/ocaml/bitwriter/Makefile8
-rw-r--r--bindings/ocaml/bitwriter/bitwriter_ocaml.c23
-rw-r--r--bindings/ocaml/bitwriter/llvm_bitwriter.ml17
-rw-r--r--bindings/ocaml/bitwriter/llvm_bitwriter.mli19
-rw-r--r--bindings/ocaml/executionengine/Makefile13
-rw-r--r--bindings/ocaml/executionengine/executionengine_ocaml.c311
-rw-r--r--bindings/ocaml/executionengine/llvm_executionengine.ml151
-rw-r--r--bindings/ocaml/executionengine/llvm_executionengine.mli212
-rw-r--r--bindings/ocaml/irreader/irreader_ocaml.c30
-rw-r--r--bindings/ocaml/irreader/llvm_irreader.ml3
-rw-r--r--bindings/ocaml/linker/linker_ocaml.c30
-rw-r--r--bindings/ocaml/linker/llvm_linker.ml5
-rw-r--r--bindings/ocaml/llvm/META.llvm.in3
-rw-r--r--bindings/ocaml/llvm/Makefile11
-rw-r--r--bindings/ocaml/llvm/llvm.ml81
-rw-r--r--bindings/ocaml/llvm/llvm.mli204
-rw-r--r--bindings/ocaml/llvm/llvm_ocaml.c250
-rw-r--r--bindings/ocaml/target/llvm_target.ml5
-rw-r--r--bindings/ocaml/target/llvm_target.mli6
-rw-r--r--bindings/ocaml/target/target_ocaml.c68
-rw-r--r--bindings/ocaml/transforms/Makefile2
-rw-r--r--bindings/ocaml/transforms/ipo/Makefile4
-rw-r--r--bindings/ocaml/transforms/ipo/ipo_ocaml.c10
-rw-r--r--bindings/ocaml/transforms/ipo/llvm_ipo.ml70
-rw-r--r--bindings/ocaml/transforms/ipo/llvm_ipo.mli124
-rw-r--r--bindings/ocaml/transforms/passmgr_builder/llvm_passmgr_builder.mli20
-rw-r--r--bindings/ocaml/transforms/passmgr_builder/passmgr_builder_ocaml.c8
-rw-r--r--bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml114
-rw-r--r--bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli168
-rw-r--r--bindings/ocaml/transforms/scalar_opts/Makefile (renamed from bindings/ocaml/transforms/scalar/Makefile)2
-rw-r--r--bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.ml120
-rw-r--r--bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli198
-rw-r--r--bindings/ocaml/transforms/scalar_opts/scalar_opts_ocaml.c (renamed from bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c)130
-rw-r--r--bindings/ocaml/transforms/vectorize/Makefile2
-rw-r--r--bindings/ocaml/transforms/vectorize/llvm_vectorize.ml15
-rw-r--r--bindings/ocaml/transforms/vectorize/llvm_vectorize.mli17
81 files changed, 5570 insertions, 1377 deletions
diff --git a/bindings/Makefile b/bindings/Makefile
index c545b28..70e9e6c 100644
--- a/bindings/Makefile
+++ b/bindings/Makefile
@@ -11,6 +11,10 @@ LEVEL := ..
include $(LEVEL)/Makefile.config
-PARALLEL_DIRS = $(BINDINGS_TO_BUILD)
+PARALLEL_DIRS =
+
+ifneq (,$(filter ocaml,$(BINDINGS_TO_BUILD)))
+PARALLEL_DIRS += ocaml
+endif
include $(LEVEL)/Makefile.common
diff --git a/bindings/go/README.txt b/bindings/go/README.txt
new file mode 100644
index 0000000..2fc4afa
--- /dev/null
+++ b/bindings/go/README.txt
@@ -0,0 +1,53 @@
+This directory contains LLVM bindings for the Go programming language
+(http://golang.org).
+
+Prerequisites
+-------------
+
+* Go 1.2+.
+* CMake (to build LLVM).
+
+Using the bindings
+------------------
+
+The package path "llvm.org/llvm/bindings/go/llvm" can be used to
+import the latest development version of LLVM from SVN. Paths such as
+"llvm.org/llvm.v36/bindings/go/llvm" refer to released versions of LLVM.
+
+It is recommended to use the "-d" flag with "go get" to download the
+package or a dependency, as an additional step is required to build LLVM
+(see "Building LLVM" below).
+
+Building LLVM
+-------------
+
+The script "build.sh" in this directory can be used to build LLVM and prepare
+it to be used by the bindings. If you receive an error message from "go build"
+like this:
+
+ ./analysis.go:4:84: fatal error: llvm-c/Analysis.h: No such file or directory
+ #include <llvm-c/Analysis.h> // If you are getting an error here read bindings/go/README.txt
+
+or like this:
+
+ ./llvm_dep.go:5: undefined: run_build_sh
+
+it means that LLVM needs to be built or updated by running the script.
+
+ $ $GOPATH/src/llvm.org/llvm/bindings/go/build.sh
+
+Any command line arguments supplied to the script are passed to LLVM's CMake
+build system. A good set of arguments to use during development are:
+
+ $ $GOPATH/src/llvm.org/llvm/bindings/go/build.sh -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD=host -DBUILD_SHARED_LIBS=ON
+
+Note that CMake keeps a cache of build settings so once you have built
+LLVM there is no need to pass these arguments again after updating.
+
+Alternatively, you can build LLVM yourself, but you must then set the
+CGO_CPPFLAGS, CGO_CXXFLAGS and CGO_LDFLAGS environment variables:
+
+ $ export CGO_CPPFLAGS="`/path/to/llvm-build/bin/llvm-config --cppflags`"
+ $ export CGO_CXXFLAGS=-std=c++11
+ $ export CGO_LDFLAGS="`/path/to/llvm-build/bin/llvm-config --ldflags --libs --system-libs all`"
+ $ go build -tags byollvm
diff --git a/bindings/go/build.sh b/bindings/go/build.sh
new file mode 100755
index 0000000..3177852
--- /dev/null
+++ b/bindings/go/build.sh
@@ -0,0 +1,28 @@
+#!/bin/sh -xe
+
+gollvmdir=$(dirname "$0")/llvm
+
+workdir=$gollvmdir/workdir
+llvmdir=$gollvmdir/../../..
+llvm_builddir=$workdir/llvm_build
+
+mkdir -p $llvm_builddir
+
+cmake_flags="../../../../.. $@"
+llvm_config="$llvm_builddir/bin/llvm-config"
+llvm_go="$llvm_builddir/bin/llvm-go"
+
+if test -n "`which ninja`" ; then
+ # If Ninja is available, we can speed up the build by building only the
+ # required subset of LLVM.
+ (cd $llvm_builddir && cmake -G Ninja $cmake_flags)
+ ninja -C $llvm_builddir llvm-config llvm-go
+ llvm_components="$($llvm_go print-components)"
+ llvm_buildtargets="$($llvm_config --libs $llvm_components | sed -e 's/-l//g')"
+ ninja -C $llvm_builddir $llvm_buildtargets FileCheck
+else
+ (cd $llvm_builddir && cmake $cmake_flags)
+ make -C $llvm_builddir -j4
+fi
+
+$llvm_go print-config > $gollvmdir/llvm_config.go
diff --git a/bindings/go/conftest.go b/bindings/go/conftest.go
new file mode 100644
index 0000000..d97fb89
--- /dev/null
+++ b/bindings/go/conftest.go
@@ -0,0 +1,16 @@
+package main
+
+import (
+ "go/build"
+ "os"
+)
+
+// Tests that the Go compiler is at least version 1.2.
+func main() {
+ for _, tag := range build.Default.ReleaseTags {
+ if tag == "go1.2" {
+ os.Exit(0)
+ }
+ }
+ os.Exit(1)
+}
diff --git a/bindings/go/llvm/DIBuilderBindings.cpp b/bindings/go/llvm/DIBuilderBindings.cpp
new file mode 100644
index 0000000..94fa96f
--- /dev/null
+++ b/bindings/go/llvm/DIBuilderBindings.cpp
@@ -0,0 +1,222 @@
+//===- DIBuilderBindings.cpp - Bindings for DIBuilder ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C bindings for the DIBuilder class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DIBuilderBindings.h"
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/DIBuilder.h"
+
+using namespace llvm;
+
+namespace {
+template <typename T>
+T unwrapDI(LLVMValueRef v) {
+ return v ? T(unwrap<MDNode>(v)) : T();
+}
+}
+
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef)
+
+LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef mref) {
+ Module *m = unwrap(mref);
+ return wrap(new DIBuilder(*m));
+}
+
+void LLVMDIBuilderDestroy(LLVMDIBuilderRef dref) {
+ DIBuilder *d = unwrap(dref);
+ delete d;
+}
+
+void LLVMDIBuilderFinalize(LLVMDIBuilderRef dref) { unwrap(dref)->finalize(); }
+
+LLVMValueRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef Dref,
+ unsigned Lang, const char *File,
+ const char *Dir,
+ const char *Producer, int Optimized,
+ const char *Flags,
+ unsigned RuntimeVersion) {
+ DIBuilder *D = unwrap(Dref);
+ DICompileUnit CU = D->createCompileUnit(Lang, File, Dir, Producer, Optimized,
+ Flags, RuntimeVersion);
+ return wrap(CU);
+}
+
+LLVMValueRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Dref, const char *File,
+ const char *Dir) {
+ DIBuilder *D = unwrap(Dref);
+ DIFile F = D->createFile(File, Dir);
+ return wrap(F);
+}
+
+LLVMValueRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
+ LLVMValueRef Scope,
+ LLVMValueRef File, unsigned Line,
+ unsigned Column) {
+ DIBuilder *D = unwrap(Dref);
+ DILexicalBlock LB = D->createLexicalBlock(
+ unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Column);
+ return wrap(LB);
+}
+
+LLVMValueRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref,
+ LLVMValueRef Scope,
+ LLVMValueRef File,
+ unsigned Discriminator) {
+ DIBuilder *D = unwrap(Dref);
+ DILexicalBlockFile LBF = D->createLexicalBlockFile(
+ unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Discriminator);
+ return wrap(LBF);
+}
+
+LLVMValueRef LLVMDIBuilderCreateFunction(
+ LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name,
+ const char *LinkageName, LLVMValueRef File, unsigned Line,
+ LLVMValueRef CompositeType, int IsLocalToUnit, int IsDefinition,
+ unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Func) {
+ DIBuilder *D = unwrap(Dref);
+ DISubprogram SP = D->createFunction(
+ unwrapDI<DIDescriptor>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
+ Line, unwrapDI<DICompositeType>(CompositeType), IsLocalToUnit,
+ IsDefinition, ScopeLine, Flags, IsOptimized, unwrap<Function>(Func));
+ return wrap(SP);
+}
+
+LLVMValueRef LLVMDIBuilderCreateLocalVariable(
+ LLVMDIBuilderRef Dref, unsigned Tag, LLVMValueRef Scope, const char *Name,
+ LLVMValueRef File, unsigned Line, LLVMValueRef Ty, int AlwaysPreserve,
+ unsigned Flags, unsigned ArgNo) {
+ DIBuilder *D = unwrap(Dref);
+ DIVariable V = D->createLocalVariable(
+ Tag, unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
+ unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo);
+ return wrap(V);
+}
+
+LLVMValueRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref,
+ const char *Name, uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ unsigned Encoding) {
+ DIBuilder *D = unwrap(Dref);
+ DIBasicType T = D->createBasicType(Name, SizeInBits, AlignInBits, Encoding);
+ return wrap(T);
+}
+
+LLVMValueRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
+ LLVMValueRef PointeeType,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ const char *Name) {
+ DIBuilder *D = unwrap(Dref);
+ DIDerivedType T = D->createPointerType(unwrapDI<DIType>(PointeeType),
+ SizeInBits, AlignInBits, Name);
+ return wrap(T);
+}
+
+LLVMValueRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref,
+ LLVMValueRef File,
+ LLVMValueRef ParameterTypes) {
+ DIBuilder *D = unwrap(Dref);
+ DICompositeType CT = D->createSubroutineType(
+ unwrapDI<DIFile>(File), unwrapDI<DITypeArray>(ParameterTypes));
+ return wrap(CT);
+}
+
+LLVMValueRef LLVMDIBuilderCreateStructType(
+ LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name,
+ LLVMValueRef File, unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+ unsigned Flags, LLVMValueRef DerivedFrom, LLVMValueRef ElementTypes) {
+ DIBuilder *D = unwrap(Dref);
+ DICompositeType CT = D->createStructType(
+ unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
+ SizeInBits, AlignInBits, Flags, unwrapDI<DIType>(DerivedFrom),
+ unwrapDI<DIArray>(ElementTypes));
+ return wrap(CT);
+}
+
+LLVMValueRef LLVMDIBuilderCreateMemberType(
+ LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name,
+ LLVMValueRef File, unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags, LLVMValueRef Ty) {
+ DIBuilder *D = unwrap(Dref);
+ DIDerivedType DT = D->createMemberType(
+ unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
+ SizeInBits, AlignInBits, OffsetInBits, Flags, unwrapDI<DIType>(Ty));
+ return wrap(DT);
+}
+
+LLVMValueRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ LLVMValueRef ElementType,
+ LLVMValueRef Subscripts) {
+ DIBuilder *D = unwrap(Dref);
+ DICompositeType CT =
+ D->createArrayType(SizeInBits, AlignInBits, unwrapDI<DIType>(ElementType),
+ unwrapDI<DIArray>(Subscripts));
+ return wrap(CT);
+}
+
+LLVMValueRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref, LLVMValueRef Ty,
+ const char *Name, LLVMValueRef File,
+ unsigned Line, LLVMValueRef Context) {
+ DIBuilder *D = unwrap(Dref);
+ DIDerivedType DT =
+ D->createTypedef(unwrapDI<DIType>(Ty), Name, unwrapDI<DIFile>(File), Line,
+ unwrapDI<DIDescriptor>(Context));
+ return wrap(DT);
+}
+
+LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Dref, int64_t Lo,
+ int64_t Count) {
+ DIBuilder *D = unwrap(Dref);
+ DISubrange S = D->getOrCreateSubrange(Lo, Count);
+ return wrap(S);
+}
+
+LLVMValueRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref,
+ LLVMValueRef *Data, size_t Length) {
+ DIBuilder *D = unwrap(Dref);
+ Value **DataValue = unwrap(Data);
+ ArrayRef<Value *> Elements(DataValue, Length);
+ DIArray A = D->getOrCreateArray(Elements);
+ return wrap(A);
+}
+
+LLVMValueRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref,
+ LLVMValueRef *Data,
+ size_t Length) {
+ DIBuilder *D = unwrap(Dref);
+ Value **DataValue = unwrap(Data);
+ ArrayRef<Value *> Elements(DataValue, Length);
+ DITypeArray A = D->getOrCreateTypeArray(Elements);
+ return wrap(A);
+}
+
+LLVMValueRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, int64_t *Addr,
+ size_t Length) {
+ DIBuilder *D = unwrap(Dref);
+ DIExpression Expr = D->createExpression(ArrayRef<int64_t>(Addr, Length));
+ return wrap(Expr);
+}
+
+LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref,
+ LLVMValueRef Storage,
+ LLVMValueRef VarInfo,
+ LLVMValueRef Expr,
+ LLVMBasicBlockRef Block) {
+ DIBuilder *D = unwrap(Dref);
+ Instruction *Instr =
+ D->insertDeclare(unwrap(Storage), unwrapDI<DIVariable>(VarInfo),
+ unwrapDI<DIExpression>(Expr), unwrap(Block));
+ return wrap(Instr);
+}
diff --git a/bindings/go/llvm/DIBuilderBindings.h b/bindings/go/llvm/DIBuilderBindings.h
new file mode 100644
index 0000000..e6fe02a
--- /dev/null
+++ b/bindings/go/llvm/DIBuilderBindings.h
@@ -0,0 +1,123 @@
+//===- DIBuilderBindings.h - Bindings for DIBuilder -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C bindings for the DIBuilder class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H
+#define LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// FIXME: These bindings shouldn't be Go-specific and should eventually move to
+// a (somewhat) less stable collection of C APIs for use in creating bindings of
+// LLVM in other languages.
+
+typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef;
+
+LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef m);
+
+void LLVMDIBuilderDestroy(LLVMDIBuilderRef d);
+void LLVMDIBuilderFinalize(LLVMDIBuilderRef d);
+
+LLVMValueRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef D,
+ unsigned Language, const char *File,
+ const char *Dir,
+ const char *Producer, int Optimized,
+ const char *Flags,
+ unsigned RuntimeVersion);
+
+LLVMValueRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef D, const char *File,
+ const char *Dir);
+
+LLVMValueRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef D,
+ LLVMValueRef Scope,
+ LLVMValueRef File, unsigned Line,
+ unsigned Column);
+
+LLVMValueRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef D,
+ LLVMValueRef Scope,
+ LLVMValueRef File,
+ unsigned Discriminator);
+
+LLVMValueRef LLVMDIBuilderCreateFunction(
+ LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name,
+ const char *LinkageName, LLVMValueRef File, unsigned Line,
+ LLVMValueRef CompositeType, int IsLocalToUnit, int IsDefinition,
+ unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Function);
+
+LLVMValueRef LLVMDIBuilderCreateLocalVariable(
+ LLVMDIBuilderRef D, unsigned Tag, LLVMValueRef Scope, const char *Name,
+ LLVMValueRef File, unsigned Line, LLVMValueRef Ty, int AlwaysPreserve,
+ unsigned Flags, unsigned ArgNo);
+
+LLVMValueRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef D, const char *Name,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ unsigned Encoding);
+
+LLVMValueRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef D,
+ LLVMValueRef PointeeType,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ const char *Name);
+
+LLVMValueRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef D,
+ LLVMValueRef File,
+ LLVMValueRef ParameterTypes);
+
+LLVMValueRef LLVMDIBuilderCreateStructType(
+ LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name, LLVMValueRef File,
+ unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
+ LLVMValueRef DerivedFrom, LLVMValueRef ElementTypes);
+
+LLVMValueRef LLVMDIBuilderCreateMemberType(
+ LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name, LLVMValueRef File,
+ unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags, LLVMValueRef Ty);
+
+LLVMValueRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef D,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ LLVMValueRef ElementType,
+ LLVMValueRef Subscripts);
+
+LLVMValueRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef D, LLVMValueRef Ty,
+ const char *Name, LLVMValueRef File,
+ unsigned Line, LLVMValueRef Context);
+
+LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef D, int64_t Lo,
+ int64_t Count);
+
+LLVMValueRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef D,
+ LLVMValueRef *Data, size_t Length);
+
+LLVMValueRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef D,
+ LLVMValueRef *Data,
+ size_t Length);
+
+LLVMValueRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, int64_t *Addr,
+ size_t Length);
+
+LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef D,
+ LLVMValueRef Storage,
+ LLVMValueRef VarInfo,
+ LLVMValueRef Expr,
+ LLVMBasicBlockRef Block);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/bindings/go/llvm/IRBindings.cpp b/bindings/go/llvm/IRBindings.cpp
new file mode 100644
index 0000000..67a54a2
--- /dev/null
+++ b/bindings/go/llvm/IRBindings.cpp
@@ -0,0 +1,47 @@
+//===- IRBindings.cpp - Additional bindings for ir ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines additional C bindings for the ir component.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IRBindings.h"
+
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Function.h"
+
+using namespace llvm;
+
+void LLVMAddFunctionAttr2(LLVMValueRef Fn, uint64_t PA) {
+ Function *Func = unwrap<Function>(Fn);
+ const AttributeSet PAL = Func->getAttributes();
+ AttrBuilder B(PA);
+ const AttributeSet PALnew =
+ PAL.addAttributes(Func->getContext(), AttributeSet::FunctionIndex,
+ AttributeSet::get(Func->getContext(),
+ AttributeSet::FunctionIndex, B));
+ Func->setAttributes(PALnew);
+}
+
+uint64_t LLVMGetFunctionAttr2(LLVMValueRef Fn) {
+ Function *Func = unwrap<Function>(Fn);
+ const AttributeSet PAL = Func->getAttributes();
+ return PAL.Raw(AttributeSet::FunctionIndex);
+}
+
+void LLVMRemoveFunctionAttr2(LLVMValueRef Fn, uint64_t PA) {
+ Function *Func = unwrap<Function>(Fn);
+ const AttributeSet PAL = Func->getAttributes();
+ AttrBuilder B(PA);
+ const AttributeSet PALnew =
+ PAL.removeAttributes(Func->getContext(), AttributeSet::FunctionIndex,
+ AttributeSet::get(Func->getContext(),
+ AttributeSet::FunctionIndex, B));
+ Func->setAttributes(PALnew);
+}
diff --git a/bindings/go/llvm/IRBindings.h b/bindings/go/llvm/IRBindings.h
new file mode 100644
index 0000000..cc63e4e
--- /dev/null
+++ b/bindings/go/llvm/IRBindings.h
@@ -0,0 +1,37 @@
+//===- IRBindings.h - Additional bindings for IR ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines additional C bindings for the IR component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H
+#define LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H
+
+#include "llvm-c/Core.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// These functions duplicate the LLVM*FunctionAttr functions in the stable C
+// API. We cannot use the existing functions because they take 32-bit attribute
+// values, and the Go bindings expose all of the LLVM attributes, some of which
+// have values >= 1<<32.
+
+void LLVMAddFunctionAttr2(LLVMValueRef Fn, uint64_t PA);
+uint64_t LLVMGetFunctionAttr2(LLVMValueRef Fn);
+void LLVMRemoveFunctionAttr2(LLVMValueRef Fn, uint64_t PA);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bindings/go/llvm/InstrumentationBindings.cpp b/bindings/go/llvm/InstrumentationBindings.cpp
new file mode 100644
index 0000000..b604abb
--- /dev/null
+++ b/bindings/go/llvm/InstrumentationBindings.cpp
@@ -0,0 +1,42 @@
+//===- InstrumentationBindings.cpp - instrumentation bindings -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C bindings for the instrumentation component.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InstrumentationBindings.h"
+
+#include "llvm-c/Core.h"
+#include "llvm/IR/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Transforms/Instrumentation.h"
+
+using namespace llvm;
+
+void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM) {
+ unwrap(PM)->add(createAddressSanitizerFunctionPass());
+}
+
+void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM) {
+ unwrap(PM)->add(createAddressSanitizerModulePass());
+}
+
+void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) {
+ unwrap(PM)->add(createThreadSanitizerPass());
+}
+
+void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM) {
+ unwrap(PM)->add(createMemorySanitizerPass());
+}
+
+void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM,
+ const char *ABIListFile) {
+ unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFile));
+}
diff --git a/bindings/go/llvm/InstrumentationBindings.h b/bindings/go/llvm/InstrumentationBindings.h
new file mode 100644
index 0000000..e8dbd59
--- /dev/null
+++ b/bindings/go/llvm/InstrumentationBindings.h
@@ -0,0 +1,38 @@
+//===- InstrumentationBindings.h - instrumentation bindings -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C bindings for the Transforms/Instrumentation component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINDINGS_GO_LLVM_INSTRUMENTATIONBINDINGS_H
+#define LLVM_BINDINGS_GO_LLVM_INSTRUMENTATIONBINDINGS_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// FIXME: These bindings shouldn't be Go-specific and should eventually move to
+// a (somewhat) less stable collection of C APIs for use in creating bindings of
+// LLVM in other languages.
+
+void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM);
+void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM);
+void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM);
+void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM);
+void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM,
+ const char *ABIListFile);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bindings/go/llvm/SupportBindings.cpp b/bindings/go/llvm/SupportBindings.cpp
new file mode 100644
index 0000000..df5f865
--- /dev/null
+++ b/bindings/go/llvm/SupportBindings.cpp
@@ -0,0 +1,27 @@
+//===- SupportBindings.cpp - Additional bindings for support --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines additional C bindings for the support component.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SupportBindings.h"
+
+#include "llvm/Support/DynamicLibrary.h"
+#include <stdlib.h>
+#include <string.h>
+
+void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg) {
+ std::string ErrMsgStr;
+ if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename, &ErrMsgStr)) {
+ *ErrMsg = static_cast<char *>(malloc(ErrMsgStr.size() + 1));
+ memcpy(static_cast<void *>(*ErrMsg),
+ static_cast<const void *>(ErrMsgStr.c_str()), ErrMsgStr.size() + 1);
+ }
+}
diff --git a/bindings/go/llvm/SupportBindings.h b/bindings/go/llvm/SupportBindings.h
new file mode 100644
index 0000000..efcd667
--- /dev/null
+++ b/bindings/go/llvm/SupportBindings.h
@@ -0,0 +1,30 @@
+//===- SupportBindings.h - Additional bindings for Support ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines additional C bindings for the Support component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINDINGS_GO_LLVM_SUPPORTBINDINGS_H
+#define LLVM_BINDINGS_GO_LLVM_SUPPORTBINDINGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// This function duplicates the LLVMLoadLibraryPermanently function in the
+// stable C API and adds an extra ErrMsg parameter to retrieve the error
+// message.
+void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bindings/go/llvm/analysis.go b/bindings/go/llvm/analysis.go
new file mode 100644
index 0000000..7b0d8e3
--- /dev/null
+++ b/bindings/go/llvm/analysis.go
@@ -0,0 +1,68 @@
+//===- analysis.go - Bindings for analysis --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the analysis component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Analysis.h" // If you are getting an error here read bindings/go/README.txt
+#include <stdlib.h>
+*/
+import "C"
+import "errors"
+
+type VerifierFailureAction C.LLVMVerifierFailureAction
+
+const (
+ // verifier will print to stderr and abort()
+ AbortProcessAction VerifierFailureAction = C.LLVMAbortProcessAction
+ // verifier will print to stderr and return 1
+ PrintMessageAction VerifierFailureAction = C.LLVMPrintMessageAction
+ // verifier will just return 1
+ ReturnStatusAction VerifierFailureAction = C.LLVMReturnStatusAction
+)
+
+// Verifies that a module is valid, taking the specified action if not.
+// Optionally returns a human-readable description of any invalid constructs.
+func VerifyModule(m Module, a VerifierFailureAction) error {
+ var cmsg *C.char
+ broken := C.LLVMVerifyModule(m.C, C.LLVMVerifierFailureAction(a), &cmsg)
+
+ // C++'s verifyModule means isModuleBroken, so it returns false if
+ // there are no errors
+ if broken != 0 {
+ err := errors.New(C.GoString(cmsg))
+ C.LLVMDisposeMessage(cmsg)
+ return err
+ }
+ return nil
+}
+
+var verifyFunctionError = errors.New("Function is broken")
+
+// Verifies that a single function is valid, taking the specified action.
+// Useful for debugging.
+func VerifyFunction(f Value, a VerifierFailureAction) error {
+ broken := C.LLVMVerifyFunction(f.C, C.LLVMVerifierFailureAction(a))
+
+ // C++'s verifyFunction means isFunctionBroken, so it returns false if
+ // there are no errors
+ if broken != 0 {
+ return verifyFunctionError
+ }
+ return nil
+}
+
+// Open up a ghostview window that displays the CFG of the current function.
+// Useful for debugging.
+func ViewFunctionCFG(f Value) { C.LLVMViewFunctionCFG(f.C) }
+func ViewFunctionCFGOnly(f Value) { C.LLVMViewFunctionCFGOnly(f.C) }
diff --git a/bindings/go/llvm/bitreader.go b/bindings/go/llvm/bitreader.go
new file mode 100644
index 0000000..98112a9
--- /dev/null
+++ b/bindings/go/llvm/bitreader.go
@@ -0,0 +1,50 @@
+//===- bitreader.go - Bindings for bitreader ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the bitreader component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/BitReader.h"
+#include <stdlib.h>
+*/
+import "C"
+
+import (
+ "errors"
+ "unsafe"
+)
+
+// ParseBitcodeFile parses the LLVM IR (bitcode) in the file with the
+// specified name, and returns a new LLVM module.
+func ParseBitcodeFile(name string) (Module, error) {
+ var buf C.LLVMMemoryBufferRef
+ var errmsg *C.char
+ var cfilename *C.char = C.CString(name)
+ defer C.free(unsafe.Pointer(cfilename))
+ result := C.LLVMCreateMemoryBufferWithContentsOfFile(cfilename, &buf, &errmsg)
+ if result != 0 {
+ err := errors.New(C.GoString(errmsg))
+ C.free(unsafe.Pointer(errmsg))
+ return Module{}, err
+ }
+ defer C.LLVMDisposeMemoryBuffer(buf)
+
+ var m Module
+ if C.LLVMParseBitcode(buf, &m.C, &errmsg) == 0 {
+ return m, nil
+ }
+
+ err := errors.New(C.GoString(errmsg))
+ C.free(unsafe.Pointer(errmsg))
+ return Module{}, err
+}
diff --git a/bindings/go/llvm/bitwriter.go b/bindings/go/llvm/bitwriter.go
new file mode 100644
index 0000000..e03699c
--- /dev/null
+++ b/bindings/go/llvm/bitwriter.go
@@ -0,0 +1,39 @@
+//===- bitwriter.go - Bindings for bitwriter ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the bitwriter component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/BitWriter.h"
+#include <stdlib.h>
+*/
+import "C"
+import "os"
+import "errors"
+
+var writeBitcodeToFileErr = errors.New("Failed to write bitcode to file")
+
+func WriteBitcodeToFile(m Module, file *os.File) error {
+ fail := C.LLVMWriteBitcodeToFD(m.C, C.int(file.Fd()), C.int(0), C.int(0))
+ if fail != 0 {
+ return writeBitcodeToFileErr
+ }
+ return nil
+}
+
+func WriteBitcodeToMemoryBuffer(m Module) MemoryBuffer {
+ mb := C.LLVMWriteBitcodeToMemoryBuffer(m.C)
+ return MemoryBuffer{mb}
+}
+
+// TODO(nsf): Figure out way how to make it work with io.Writer
diff --git a/bindings/go/llvm/dibuilder.go b/bindings/go/llvm/dibuilder.go
new file mode 100644
index 0000000..1d07e98
--- /dev/null
+++ b/bindings/go/llvm/dibuilder.go
@@ -0,0 +1,492 @@
+//===- dibuilder.go - Bindings for DIBuilder ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the DIBuilder class.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "DIBuilderBindings.h"
+#include <stdlib.h>
+*/
+import "C"
+
+import (
+ "debug/dwarf"
+ "unsafe"
+)
+
+type DwarfTag uint32
+
+const (
+ DW_TAG_lexical_block DwarfTag = 0x0b
+ DW_TAG_compile_unit DwarfTag = 0x11
+ DW_TAG_variable DwarfTag = 0x34
+ DW_TAG_base_type DwarfTag = 0x24
+ DW_TAG_pointer_type DwarfTag = 0x0F
+ DW_TAG_structure_type DwarfTag = 0x13
+ DW_TAG_subroutine_type DwarfTag = 0x15
+ DW_TAG_file_type DwarfTag = 0x29
+ DW_TAG_subprogram DwarfTag = 0x2E
+ DW_TAG_auto_variable DwarfTag = 0x100
+ DW_TAG_arg_variable DwarfTag = 0x101
+)
+
+const (
+ FlagPrivate = 1 << iota
+ FlagProtected
+ FlagFwdDecl
+ FlagAppleBlock
+ FlagBlockByrefStruct
+ FlagVirtual
+ FlagArtificial
+ FlagExplicit
+ FlagPrototyped
+ FlagObjcClassComplete
+ FlagObjectPointer
+ FlagVector
+ FlagStaticMember
+ FlagIndirectVariable
+)
+
+type DwarfLang uint32
+
+const (
+ // http://dwarfstd.org/ShowIssue.php?issue=101014.1&type=open
+ DW_LANG_Go DwarfLang = 0x0016
+)
+
+type DwarfTypeEncoding uint32
+
+const (
+ DW_ATE_address DwarfTypeEncoding = 0x01
+ DW_ATE_boolean DwarfTypeEncoding = 0x02
+ DW_ATE_complex_float DwarfTypeEncoding = 0x03
+ DW_ATE_float DwarfTypeEncoding = 0x04
+ DW_ATE_signed DwarfTypeEncoding = 0x05
+ DW_ATE_signed_char DwarfTypeEncoding = 0x06
+ DW_ATE_unsigned DwarfTypeEncoding = 0x07
+ DW_ATE_unsigned_char DwarfTypeEncoding = 0x08
+ DW_ATE_imaginary_float DwarfTypeEncoding = 0x09
+ DW_ATE_packed_decimal DwarfTypeEncoding = 0x0a
+ DW_ATE_numeric_string DwarfTypeEncoding = 0x0b
+ DW_ATE_edited DwarfTypeEncoding = 0x0c
+ DW_ATE_signed_fixed DwarfTypeEncoding = 0x0d
+ DW_ATE_unsigned_fixed DwarfTypeEncoding = 0x0e
+ DW_ATE_decimal_float DwarfTypeEncoding = 0x0f
+ DW_ATE_UTF DwarfTypeEncoding = 0x10
+ DW_ATE_lo_user DwarfTypeEncoding = 0x80
+ DW_ATE_hi_user DwarfTypeEncoding = 0xff
+)
+
+// DIBuilder is a wrapper for the LLVM DIBuilder class.
+type DIBuilder struct {
+ ref C.LLVMDIBuilderRef
+ m Module
+}
+
+// NewDIBuilder creates a new DIBuilder, associated with the given module.
+func NewDIBuilder(m Module) *DIBuilder {
+ d := C.LLVMNewDIBuilder(m.C)
+ return &DIBuilder{ref: d, m: m}
+}
+
+// Destroy destroys the DIBuilder.
+func (d *DIBuilder) Destroy() {
+ C.LLVMDIBuilderDestroy(d.ref)
+}
+
+// FInalize finalizes the debug information generated by the DIBuilder.
+func (d *DIBuilder) Finalize() {
+ C.LLVMDIBuilderFinalize(d.ref)
+}
+
+// DICompileUnit holds the values for creating compile unit debug metadata.
+type DICompileUnit struct {
+ Language DwarfLang
+ File string
+ Dir string
+ Producer string
+ Optimized bool
+ Flags string
+ RuntimeVersion int
+}
+
+// CreateCompileUnit creates compile unit debug metadata.
+func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Value {
+ file := C.CString(cu.File)
+ defer C.free(unsafe.Pointer(file))
+ dir := C.CString(cu.Dir)
+ defer C.free(unsafe.Pointer(dir))
+ producer := C.CString(cu.Producer)
+ defer C.free(unsafe.Pointer(producer))
+ flags := C.CString(cu.Flags)
+ defer C.free(unsafe.Pointer(flags))
+ result := C.LLVMDIBuilderCreateCompileUnit(
+ d.ref,
+ C.unsigned(cu.Language),
+ file, dir,
+ producer,
+ boolToCInt(cu.Optimized),
+ flags,
+ C.unsigned(cu.RuntimeVersion),
+ )
+ return Value{C: result}
+}
+
+// CreateCompileUnit creates file debug metadata.
+func (d *DIBuilder) CreateFile(filename, dir string) Value {
+ cfilename := C.CString(filename)
+ defer C.free(unsafe.Pointer(cfilename))
+ cdir := C.CString(dir)
+ defer C.free(unsafe.Pointer(cdir))
+ result := C.LLVMDIBuilderCreateFile(d.ref, cfilename, cdir)
+ return Value{C: result}
+}
+
+// DILexicalBlock holds the values for creating lexical block debug metadata.
+type DILexicalBlock struct {
+ File Value
+ Line int
+ Column int
+}
+
+// CreateCompileUnit creates lexical block debug metadata.
+func (d *DIBuilder) CreateLexicalBlock(diScope Value, b DILexicalBlock) Value {
+ result := C.LLVMDIBuilderCreateLexicalBlock(
+ d.ref,
+ diScope.C,
+ b.File.C,
+ C.unsigned(b.Line),
+ C.unsigned(b.Column),
+ )
+ return Value{C: result}
+}
+
+func (d *DIBuilder) CreateLexicalBlockFile(diScope Value, diFile Value, discriminator int) Value {
+ result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
+ C.unsigned(discriminator))
+ return Value{C: result}
+}
+
+// DIFunction holds the values for creating function debug metadata.
+type DIFunction struct {
+ Name string
+ LinkageName string
+ File Value
+ Line int
+ Type Value
+ LocalToUnit bool
+ IsDefinition bool
+ ScopeLine int
+ Flags int
+ Optimized bool
+ Function Value
+}
+
+// CreateCompileUnit creates function debug metadata.
+func (d *DIBuilder) CreateFunction(diScope Value, f DIFunction) Value {
+ name := C.CString(f.Name)
+ defer C.free(unsafe.Pointer(name))
+ linkageName := C.CString(f.LinkageName)
+ defer C.free(unsafe.Pointer(linkageName))
+ result := C.LLVMDIBuilderCreateFunction(
+ d.ref,
+ diScope.C,
+ name,
+ linkageName,
+ f.File.C,
+ C.unsigned(f.Line),
+ f.Type.C,
+ boolToCInt(f.LocalToUnit),
+ boolToCInt(f.IsDefinition),
+ C.unsigned(f.ScopeLine),
+ C.unsigned(f.Flags),
+ boolToCInt(f.Optimized),
+ f.Function.C,
+ )
+ return Value{C: result}
+}
+
+// DILocalVariable holds the values for creating local variable debug metadata.
+type DILocalVariable struct {
+ Tag dwarf.Tag
+ Name string
+ File Value
+ Line int
+ Type Value
+ AlwaysPreserve bool
+ Flags int
+
+ // ArgNo is the 1-based index of the argument in the function's
+ // parameter list if it is an argument, or 0 otherwise.
+ ArgNo int
+}
+
+// CreateLocalVariable creates local variable debug metadata.
+func (d *DIBuilder) CreateLocalVariable(scope Value, v DILocalVariable) Value {
+ name := C.CString(v.Name)
+ defer C.free(unsafe.Pointer(name))
+ result := C.LLVMDIBuilderCreateLocalVariable(
+ d.ref,
+ C.unsigned(v.Tag),
+ scope.C,
+ name,
+ v.File.C,
+ C.unsigned(v.Line),
+ v.Type.C,
+ boolToCInt(v.AlwaysPreserve),
+ C.unsigned(v.Flags),
+ C.unsigned(v.ArgNo),
+ )
+ return Value{C: result}
+}
+
+// DIBasicType holds the values for creating basic type debug metadata.
+type DIBasicType struct {
+ Name string
+ SizeInBits uint64
+ AlignInBits uint64
+ Encoding DwarfTypeEncoding
+}
+
+// CreateBasicType creates basic type debug metadata.
+func (d *DIBuilder) CreateBasicType(t DIBasicType) Value {
+ name := C.CString(t.Name)
+ defer C.free(unsafe.Pointer(name))
+ result := C.LLVMDIBuilderCreateBasicType(
+ d.ref,
+ name,
+ C.uint64_t(t.SizeInBits),
+ C.uint64_t(t.AlignInBits),
+ C.unsigned(t.Encoding),
+ )
+ return Value{C: result}
+}
+
+// DIPointerType holds the values for creating pointer type debug metadata.
+type DIPointerType struct {
+ Pointee Value
+ SizeInBits uint64
+ AlignInBits uint64 // optional
+ Name string // optional
+}
+
+// CreateBasicType creates basic type debug metadata.
+func (d *DIBuilder) CreatePointerType(t DIPointerType) Value {
+ name := C.CString(t.Name)
+ defer C.free(unsafe.Pointer(name))
+ result := C.LLVMDIBuilderCreatePointerType(
+ d.ref,
+ t.Pointee.C,
+ C.uint64_t(t.SizeInBits),
+ C.uint64_t(t.AlignInBits),
+ name,
+ )
+ return Value{C: result}
+}
+
+// DISubroutineType holds the values for creating subroutine type debug metadata.
+type DISubroutineType struct {
+ // File is the file in which the subroutine type is defined.
+ File Value
+
+ // Parameters contains the subroutine parameter types,
+ // including the return type at the 0th index.
+ Parameters []Value
+}
+
+// CreateSubroutineType creates subroutine type debug metadata.
+func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Value {
+ params := d.getOrCreateTypeArray(t.Parameters)
+ result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C)
+ return Value{C: result}
+}
+
+// DIStructType holds the values for creating struct type debug metadata.
+type DIStructType struct {
+ Name string
+ File Value
+ Line int
+ SizeInBits uint64
+ AlignInBits uint64
+ Flags int
+ DerivedFrom Value
+ Elements []Value
+}
+
+// CreateStructType creates struct type debug metadata.
+func (d *DIBuilder) CreateStructType(scope Value, t DIStructType) Value {
+ elements := d.getOrCreateArray(t.Elements)
+ name := C.CString(t.Name)
+ defer C.free(unsafe.Pointer(name))
+ result := C.LLVMDIBuilderCreateStructType(
+ d.ref,
+ scope.C,
+ name,
+ t.File.C,
+ C.unsigned(t.Line),
+ C.uint64_t(t.SizeInBits),
+ C.uint64_t(t.AlignInBits),
+ C.unsigned(t.Flags),
+ t.DerivedFrom.C,
+ elements.C,
+ )
+ return Value{C: result}
+}
+
+// DIMemberType holds the values for creating member type debug metadata.
+type DIMemberType struct {
+ Name string
+ File Value
+ Line int
+ SizeInBits uint64
+ AlignInBits uint64
+ OffsetInBits uint64
+ Flags int
+ Type Value
+}
+
+// CreateMemberType creates struct type debug metadata.
+func (d *DIBuilder) CreateMemberType(scope Value, t DIMemberType) Value {
+ name := C.CString(t.Name)
+ defer C.free(unsafe.Pointer(name))
+ result := C.LLVMDIBuilderCreateMemberType(
+ d.ref,
+ scope.C,
+ name,
+ t.File.C,
+ C.unsigned(t.Line),
+ C.uint64_t(t.SizeInBits),
+ C.uint64_t(t.AlignInBits),
+ C.uint64_t(t.OffsetInBits),
+ C.unsigned(t.Flags),
+ t.Type.C,
+ )
+ return Value{C: result}
+}
+
+// DISubrange describes an integer value range.
+type DISubrange struct {
+ Lo int64
+ Count int64
+}
+
+// DIArrayType holds the values for creating array type debug metadata.
+type DIArrayType struct {
+ SizeInBits uint64
+ AlignInBits uint64
+ ElementType Value
+ Subscripts []DISubrange
+}
+
+// CreateArrayType creates struct type debug metadata.
+func (d *DIBuilder) CreateArrayType(t DIArrayType) Value {
+ subscriptsSlice := make([]Value, len(t.Subscripts))
+ for i, s := range t.Subscripts {
+ subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
+ }
+ subscripts := d.getOrCreateArray(subscriptsSlice)
+ result := C.LLVMDIBuilderCreateArrayType(
+ d.ref,
+ C.uint64_t(t.SizeInBits),
+ C.uint64_t(t.AlignInBits),
+ t.ElementType.C,
+ subscripts.C,
+ )
+ return Value{C: result}
+}
+
+// DITypedef holds the values for creating typedef type debug metadata.
+type DITypedef struct {
+ Type Value
+ Name string
+ File Value
+ Line int
+ Context Value
+}
+
+// CreateTypedef creates typedef type debug metadata.
+func (d *DIBuilder) CreateTypedef(t DITypedef) Value {
+ name := C.CString(t.Name)
+ defer C.free(unsafe.Pointer(name))
+ result := C.LLVMDIBuilderCreateTypedef(
+ d.ref,
+ t.Type.C,
+ name,
+ t.File.C,
+ C.unsigned(t.Line),
+ t.Context.C,
+ )
+ return Value{C: result}
+}
+
+// getOrCreateSubrange gets a metadata node for the specified subrange,
+// creating if required.
+func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Value {
+ result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
+ return Value{C: result}
+}
+
+// getOrCreateArray gets a metadata node containing the specified values,
+// creating if required.
+func (d *DIBuilder) getOrCreateArray(values []Value) Value {
+ if len(values) == 0 {
+ return Value{}
+ }
+ var data *C.LLVMValueRef
+ length := len(values)
+ if length > 0 {
+ data = &values[0].C
+ }
+ result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
+ return Value{C: result}
+}
+
+// getOrCreateTypeArray gets a metadata node for a type array containing the
+// specified values, creating if required.
+func (d *DIBuilder) getOrCreateTypeArray(values []Value) Value {
+ if len(values) == 0 {
+ return Value{}
+ }
+ var data *C.LLVMValueRef
+ length := len(values)
+ if length > 0 {
+ data = &values[0].C
+ }
+ result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
+ return Value{C: result}
+}
+
+// CreateExpression creates a new descriptor for the specified
+// variable which has a complex address expression for its address.
+func (d *DIBuilder) CreateExpression(addr []int64) Value {
+ var data *C.int64_t
+ if len(addr) > 0 {
+ data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
+ }
+ result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
+ return Value{C: result}
+}
+
+// InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
+// specified basic block for the given value and associated debug metadata.
+func (d *DIBuilder) InsertDeclareAtEnd(v, diVarInfo, expr Value, bb BasicBlock) Value {
+ result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
+ return Value{C: result}
+}
+
+func boolToCInt(v bool) C.int {
+ if v {
+ return 1
+ }
+ return 0
+}
diff --git a/bindings/go/llvm/executionengine.go b/bindings/go/llvm/executionengine.go
new file mode 100644
index 0000000..26b7524
--- /dev/null
+++ b/bindings/go/llvm/executionengine.go
@@ -0,0 +1,163 @@
+//===- executionengine.go - Bindings for executionengine ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the executionengine component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/ExecutionEngine.h"
+#include <stdlib.h>
+*/
+import "C"
+import "unsafe"
+import "errors"
+
+func LinkInMCJIT() { C.LLVMLinkInMCJIT() }
+func LinkInInterpreter() { C.LLVMLinkInInterpreter() }
+
+type GenericValue struct {
+ C C.LLVMGenericValueRef
+}
+type ExecutionEngine struct {
+ C C.LLVMExecutionEngineRef
+}
+type MCJITCompilerOptions struct {
+ OptLevel uint
+ CodeModel CodeModel
+ NoFramePointerElim bool
+ EnableFastISel bool
+}
+
+// helpers
+func llvmGenericValueRefPtr(t *GenericValue) *C.LLVMGenericValueRef {
+ return (*C.LLVMGenericValueRef)(unsafe.Pointer(t))
+}
+
+//-------------------------------------------------------------------------
+// llvm.GenericValue
+//-------------------------------------------------------------------------
+
+func NewGenericValueFromInt(t Type, n uint64, signed bool) (g GenericValue) {
+ g.C = C.LLVMCreateGenericValueOfInt(t.C, C.ulonglong(n), boolToLLVMBool(signed))
+ return
+}
+func NewGenericValueFromPointer(p unsafe.Pointer) (g GenericValue) {
+ g.C = C.LLVMCreateGenericValueOfPointer(p)
+ return
+}
+func NewGenericValueFromFloat(t Type, n float64) (g GenericValue) {
+ g.C = C.LLVMCreateGenericValueOfFloat(t.C, C.double(n))
+ return
+}
+func (g GenericValue) IntWidth() int { return int(C.LLVMGenericValueIntWidth(g.C)) }
+func (g GenericValue) Int(signed bool) uint64 {
+ return uint64(C.LLVMGenericValueToInt(g.C, boolToLLVMBool(signed)))
+}
+func (g GenericValue) Float(t Type) float64 {
+ return float64(C.LLVMGenericValueToFloat(t.C, g.C))
+}
+func (g GenericValue) Pointer() unsafe.Pointer {
+ return C.LLVMGenericValueToPointer(g.C)
+}
+func (g GenericValue) Dispose() { C.LLVMDisposeGenericValue(g.C) }
+
+//-------------------------------------------------------------------------
+// llvm.ExecutionEngine
+//-------------------------------------------------------------------------
+
+func NewExecutionEngine(m Module) (ee ExecutionEngine, err error) {
+ var cmsg *C.char
+ fail := C.LLVMCreateExecutionEngineForModule(&ee.C, m.C, &cmsg)
+ if fail != 0 {
+ ee.C = nil
+ err = errors.New(C.GoString(cmsg))
+ C.LLVMDisposeMessage(cmsg)
+ }
+ return
+}
+
+func NewInterpreter(m Module) (ee ExecutionEngine, err error) {
+ var cmsg *C.char
+ fail := C.LLVMCreateInterpreterForModule(&ee.C, m.C, &cmsg)
+ if fail != 0 {
+ ee.C = nil
+ err = errors.New(C.GoString(cmsg))
+ C.LLVMDisposeMessage(cmsg)
+ }
+ return
+}
+
+func NewMCJITCompiler(m Module, options MCJITCompilerOptions) (ee ExecutionEngine, err error) {
+ var cmsg *C.char
+ copts := C.struct_LLVMMCJITCompilerOptions{
+ OptLevel: C.unsigned(options.OptLevel),
+ CodeModel: C.LLVMCodeModel(options.CodeModel),
+ NoFramePointerElim: boolToLLVMBool(options.NoFramePointerElim),
+ EnableFastISel: boolToLLVMBool(options.EnableFastISel),
+ }
+ fail := C.LLVMCreateMCJITCompilerForModule(&ee.C, m.C, &copts, C.size_t(unsafe.Sizeof(copts)), &cmsg)
+ if fail != 0 {
+ ee.C = nil
+ err = errors.New(C.GoString(cmsg))
+ C.LLVMDisposeMessage(cmsg)
+ }
+ return
+}
+
+func (ee ExecutionEngine) Dispose() { C.LLVMDisposeExecutionEngine(ee.C) }
+func (ee ExecutionEngine) RunStaticConstructors() { C.LLVMRunStaticConstructors(ee.C) }
+func (ee ExecutionEngine) RunStaticDestructors() { C.LLVMRunStaticDestructors(ee.C) }
+
+func (ee ExecutionEngine) RunFunction(f Value, args []GenericValue) (g GenericValue) {
+ nargs := len(args)
+ var argptr *GenericValue
+ if nargs > 0 {
+ argptr = &args[0]
+ }
+ g.C = C.LLVMRunFunction(ee.C, f.C,
+ C.unsigned(nargs), llvmGenericValueRefPtr(argptr))
+ return
+}
+
+func (ee ExecutionEngine) FreeMachineCodeForFunction(f Value) {
+ C.LLVMFreeMachineCodeForFunction(ee.C, f.C)
+}
+func (ee ExecutionEngine) AddModule(m Module) { C.LLVMAddModule(ee.C, m.C) }
+
+func (ee ExecutionEngine) RemoveModule(m Module) {
+ var modtmp C.LLVMModuleRef
+ C.LLVMRemoveModule(ee.C, m.C, &modtmp, nil)
+}
+
+func (ee ExecutionEngine) FindFunction(name string) (f Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ C.LLVMFindFunction(ee.C, cname, &f.C)
+ return
+}
+
+func (ee ExecutionEngine) RecompileAndRelinkFunction(f Value) unsafe.Pointer {
+ return C.LLVMRecompileAndRelinkFunction(ee.C, f.C)
+}
+
+func (ee ExecutionEngine) TargetData() (td TargetData) {
+ td.C = C.LLVMGetExecutionEngineTargetData(ee.C)
+ return
+}
+
+func (ee ExecutionEngine) AddGlobalMapping(global Value, addr unsafe.Pointer) {
+ C.LLVMAddGlobalMapping(ee.C, global.C, addr)
+}
+
+func (ee ExecutionEngine) PointerToGlobal(global Value) unsafe.Pointer {
+ return C.LLVMGetPointerToGlobal(ee.C, global.C)
+}
diff --git a/bindings/go/llvm/executionengine_test.go b/bindings/go/llvm/executionengine_test.go
new file mode 100644
index 0000000..1a3fd45
--- /dev/null
+++ b/bindings/go/llvm/executionengine_test.go
@@ -0,0 +1,93 @@
+//===- executionengine_test.go - Tests for executionengine ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests bindings for the executionengine component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+import (
+ "testing"
+)
+
+func TestFactorial(t *testing.T) {
+ LinkInMCJIT()
+ InitializeNativeTarget()
+ InitializeNativeAsmPrinter()
+
+ mod := NewModule("fac_module")
+
+ fac_args := []Type{Int32Type()}
+ fac_type := FunctionType(Int32Type(), fac_args, false)
+ fac := AddFunction(mod, "fac", fac_type)
+ fac.SetFunctionCallConv(CCallConv)
+ n := fac.Param(0)
+
+ entry := AddBasicBlock(fac, "entry")
+ iftrue := AddBasicBlock(fac, "iftrue")
+ iffalse := AddBasicBlock(fac, "iffalse")
+ end := AddBasicBlock(fac, "end")
+
+ builder := NewBuilder()
+ defer builder.Dispose()
+
+ builder.SetInsertPointAtEnd(entry)
+ If := builder.CreateICmp(IntEQ, n, ConstInt(Int32Type(), 0, false), "cmptmp")
+ builder.CreateCondBr(If, iftrue, iffalse)
+
+ builder.SetInsertPointAtEnd(iftrue)
+ res_iftrue := ConstInt(Int32Type(), 1, false)
+ builder.CreateBr(end)
+
+ builder.SetInsertPointAtEnd(iffalse)
+ n_minus := builder.CreateSub(n, ConstInt(Int32Type(), 1, false), "subtmp")
+ call_fac_args := []Value{n_minus}
+ call_fac := builder.CreateCall(fac, call_fac_args, "calltmp")
+ res_iffalse := builder.CreateMul(n, call_fac, "multmp")
+ builder.CreateBr(end)
+
+ builder.SetInsertPointAtEnd(end)
+ res := builder.CreatePHI(Int32Type(), "result")
+ phi_vals := []Value{res_iftrue, res_iffalse}
+ phi_blocks := []BasicBlock{iftrue, iffalse}
+ res.AddIncoming(phi_vals, phi_blocks)
+ builder.CreateRet(res)
+
+ err := VerifyModule(mod, ReturnStatusAction)
+ if err != nil {
+ t.Errorf("Error verifying module: %s", err)
+ return
+ }
+
+ engine, err := NewMCJITCompiler(mod, MCJITCompilerOptions{OptLevel: 2})
+ if err != nil {
+ t.Errorf("Error creating JIT: %s", err)
+ return
+ }
+ defer engine.Dispose()
+
+ pass := NewPassManager()
+ defer pass.Dispose()
+
+ pass.Add(engine.TargetData())
+ pass.AddConstantPropagationPass()
+ pass.AddInstructionCombiningPass()
+ pass.AddPromoteMemoryToRegisterPass()
+ pass.AddGVNPass()
+ pass.AddCFGSimplificationPass()
+ pass.Run(mod)
+
+ exec_args := []GenericValue{NewGenericValueFromInt(Int32Type(), 10, false)}
+ exec_res := engine.RunFunction(fac, exec_args)
+ var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
+ if exec_res.Int(false) != fac10 {
+ t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false))
+ }
+}
diff --git a/bindings/go/llvm/ir.go b/bindings/go/llvm/ir.go
new file mode 100644
index 0000000..7834f5c
--- /dev/null
+++ b/bindings/go/llvm/ir.go
@@ -0,0 +1,1824 @@
+//===- ir.go - Bindings for ir --------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the ir component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Core.h"
+#include "IRBindings.h"
+#include <stdlib.h>
+*/
+import "C"
+import "unsafe"
+import "errors"
+
+type (
+ // We use these weird structs here because *Ref types are pointers and
+ // Go's spec says that a pointer cannot be used as a receiver base type.
+ Context struct {
+ C C.LLVMContextRef
+ }
+ Module struct {
+ C C.LLVMModuleRef
+ }
+ Type struct {
+ C C.LLVMTypeRef
+ }
+ Value struct {
+ C C.LLVMValueRef
+ }
+ BasicBlock struct {
+ C C.LLVMBasicBlockRef
+ }
+ Builder struct {
+ C C.LLVMBuilderRef
+ }
+ ModuleProvider struct {
+ C C.LLVMModuleProviderRef
+ }
+ MemoryBuffer struct {
+ C C.LLVMMemoryBufferRef
+ }
+ PassManager struct {
+ C C.LLVMPassManagerRef
+ }
+ Use struct {
+ C C.LLVMUseRef
+ }
+ Attribute uint64
+ Opcode C.LLVMOpcode
+ TypeKind C.LLVMTypeKind
+ Linkage C.LLVMLinkage
+ Visibility C.LLVMVisibility
+ CallConv C.LLVMCallConv
+ IntPredicate C.LLVMIntPredicate
+ FloatPredicate C.LLVMRealPredicate
+ LandingPadClause C.LLVMLandingPadClauseTy
+)
+
+func (c Context) IsNil() bool { return c.C == nil }
+func (c Module) IsNil() bool { return c.C == nil }
+func (c Type) IsNil() bool { return c.C == nil }
+func (c Value) IsNil() bool { return c.C == nil }
+func (c BasicBlock) IsNil() bool { return c.C == nil }
+func (c Builder) IsNil() bool { return c.C == nil }
+func (c ModuleProvider) IsNil() bool { return c.C == nil }
+func (c MemoryBuffer) IsNil() bool { return c.C == nil }
+func (c PassManager) IsNil() bool { return c.C == nil }
+func (c Use) IsNil() bool { return c.C == nil }
+
+// helpers
+func llvmTypeRefPtr(t *Type) *C.LLVMTypeRef { return (*C.LLVMTypeRef)(unsafe.Pointer(t)) }
+func llvmValueRefPtr(t *Value) *C.LLVMValueRef { return (*C.LLVMValueRef)(unsafe.Pointer(t)) }
+func llvmBasicBlockRefPtr(t *BasicBlock) *C.LLVMBasicBlockRef {
+ return (*C.LLVMBasicBlockRef)(unsafe.Pointer(t))
+}
+func boolToLLVMBool(b bool) C.LLVMBool {
+ if b {
+ return C.LLVMBool(1)
+ }
+ return C.LLVMBool(0)
+}
+
+func llvmValueRefs(values []Value) (*C.LLVMValueRef, C.unsigned) {
+ var pt *C.LLVMValueRef
+ ptlen := C.unsigned(len(values))
+ if ptlen > 0 {
+ pt = llvmValueRefPtr(&values[0])
+ }
+ return pt, ptlen
+}
+
+//-------------------------------------------------------------------------
+// llvm.Attribute
+//-------------------------------------------------------------------------
+
+const (
+ NoneAttribute Attribute = 0
+ ZExtAttribute Attribute = C.LLVMZExtAttribute
+ SExtAttribute Attribute = C.LLVMSExtAttribute
+ NoReturnAttribute Attribute = C.LLVMNoReturnAttribute
+ InRegAttribute Attribute = C.LLVMInRegAttribute
+ StructRetAttribute Attribute = C.LLVMStructRetAttribute
+ NoUnwindAttribute Attribute = C.LLVMNoUnwindAttribute
+ NoAliasAttribute Attribute = C.LLVMNoAliasAttribute
+ ByValAttribute Attribute = C.LLVMByValAttribute
+ NestAttribute Attribute = C.LLVMNestAttribute
+ ReadNoneAttribute Attribute = C.LLVMReadNoneAttribute
+ ReadOnlyAttribute Attribute = C.LLVMReadOnlyAttribute
+ NoInlineAttribute Attribute = C.LLVMNoInlineAttribute
+ AlwaysInlineAttribute Attribute = C.LLVMAlwaysInlineAttribute
+ OptimizeForSizeAttribute Attribute = C.LLVMOptimizeForSizeAttribute
+ StackProtectAttribute Attribute = C.LLVMStackProtectAttribute
+ StackProtectReqAttribute Attribute = C.LLVMStackProtectReqAttribute
+ Alignment Attribute = C.LLVMAlignment
+ NoCaptureAttribute Attribute = C.LLVMNoCaptureAttribute
+ NoRedZoneAttribute Attribute = C.LLVMNoRedZoneAttribute
+ NoImplicitFloatAttribute Attribute = C.LLVMNoImplicitFloatAttribute
+ NakedAttribute Attribute = C.LLVMNakedAttribute
+ InlineHintAttribute Attribute = C.LLVMInlineHintAttribute
+ StackAlignment Attribute = C.LLVMStackAlignment
+ ReturnsTwiceAttribute Attribute = C.LLVMReturnsTwice
+ UWTableAttribute Attribute = C.LLVMUWTable
+ NonLazyBindAttribute Attribute = 1 << 31
+ SanitizeAddressAttribute Attribute = 1 << 32
+ MinSizeAttribute Attribute = 1 << 33
+ NoDuplicateAttribute Attribute = 1 << 34
+ StackProtectStrongAttribute Attribute = 1 << 35
+ SanitizeThreadAttribute Attribute = 1 << 36
+ SanitizeMemoryAttribute Attribute = 1 << 37
+ NoBuiltinAttribute Attribute = 1 << 38
+ ReturnedAttribute Attribute = 1 << 39
+ ColdAttribute Attribute = 1 << 40
+ BuiltinAttribute Attribute = 1 << 41
+ OptimizeNoneAttribute Attribute = 1 << 42
+ InAllocaAttribute Attribute = 1 << 43
+ NonNullAttribute Attribute = 1 << 44
+ JumpTableAttribute Attribute = 1 << 45
+)
+
+//-------------------------------------------------------------------------
+// llvm.Opcode
+//-------------------------------------------------------------------------
+
+const (
+ Ret Opcode = C.LLVMRet
+ Br Opcode = C.LLVMBr
+ Switch Opcode = C.LLVMSwitch
+ IndirectBr Opcode = C.LLVMIndirectBr
+ Invoke Opcode = C.LLVMInvoke
+ Unreachable Opcode = C.LLVMUnreachable
+
+ // Standard Binary Operators
+ Add Opcode = C.LLVMAdd
+ FAdd Opcode = C.LLVMFAdd
+ Sub Opcode = C.LLVMSub
+ FSub Opcode = C.LLVMFSub
+ Mul Opcode = C.LLVMMul
+ FMul Opcode = C.LLVMFMul
+ UDiv Opcode = C.LLVMUDiv
+ SDiv Opcode = C.LLVMSDiv
+ FDiv Opcode = C.LLVMFDiv
+ URem Opcode = C.LLVMURem
+ SRem Opcode = C.LLVMSRem
+ FRem Opcode = C.LLVMFRem
+
+ // Logical Operators
+ Shl Opcode = C.LLVMShl
+ LShr Opcode = C.LLVMLShr
+ AShr Opcode = C.LLVMAShr
+ And Opcode = C.LLVMAnd
+ Or Opcode = C.LLVMOr
+ Xor Opcode = C.LLVMXor
+
+ // Memory Operators
+ Alloca Opcode = C.LLVMAlloca
+ Load Opcode = C.LLVMLoad
+ Store Opcode = C.LLVMStore
+ GetElementPtr Opcode = C.LLVMGetElementPtr
+
+ // Cast Operators
+ Trunc Opcode = C.LLVMTrunc
+ ZExt Opcode = C.LLVMZExt
+ SExt Opcode = C.LLVMSExt
+ FPToUI Opcode = C.LLVMFPToUI
+ FPToSI Opcode = C.LLVMFPToSI
+ UIToFP Opcode = C.LLVMUIToFP
+ SIToFP Opcode = C.LLVMSIToFP
+ FPTrunc Opcode = C.LLVMFPTrunc
+ FPExt Opcode = C.LLVMFPExt
+ PtrToInt Opcode = C.LLVMPtrToInt
+ IntToPtr Opcode = C.LLVMIntToPtr
+ BitCast Opcode = C.LLVMBitCast
+
+ // Other Operators
+ ICmp Opcode = C.LLVMICmp
+ FCmp Opcode = C.LLVMFCmp
+ PHI Opcode = C.LLVMPHI
+ Call Opcode = C.LLVMCall
+ Select Opcode = C.LLVMSelect
+ // UserOp1
+ // UserOp2
+ VAArg Opcode = C.LLVMVAArg
+ ExtractElement Opcode = C.LLVMExtractElement
+ InsertElement Opcode = C.LLVMInsertElement
+ ShuffleVector Opcode = C.LLVMShuffleVector
+ ExtractValue Opcode = C.LLVMExtractValue
+ InsertValue Opcode = C.LLVMInsertValue
+)
+
+//-------------------------------------------------------------------------
+// llvm.TypeKind
+//-------------------------------------------------------------------------
+
+const (
+ VoidTypeKind TypeKind = C.LLVMVoidTypeKind
+ FloatTypeKind TypeKind = C.LLVMFloatTypeKind
+ DoubleTypeKind TypeKind = C.LLVMDoubleTypeKind
+ X86_FP80TypeKind TypeKind = C.LLVMX86_FP80TypeKind
+ FP128TypeKind TypeKind = C.LLVMFP128TypeKind
+ PPC_FP128TypeKind TypeKind = C.LLVMPPC_FP128TypeKind
+ LabelTypeKind TypeKind = C.LLVMLabelTypeKind
+ IntegerTypeKind TypeKind = C.LLVMIntegerTypeKind
+ FunctionTypeKind TypeKind = C.LLVMFunctionTypeKind
+ StructTypeKind TypeKind = C.LLVMStructTypeKind
+ ArrayTypeKind TypeKind = C.LLVMArrayTypeKind
+ PointerTypeKind TypeKind = C.LLVMPointerTypeKind
+ VectorTypeKind TypeKind = C.LLVMVectorTypeKind
+ MetadataTypeKind TypeKind = C.LLVMMetadataTypeKind
+)
+
+//-------------------------------------------------------------------------
+// llvm.Linkage
+//-------------------------------------------------------------------------
+
+const (
+ ExternalLinkage Linkage = C.LLVMExternalLinkage
+ AvailableExternallyLinkage Linkage = C.LLVMAvailableExternallyLinkage
+ LinkOnceAnyLinkage Linkage = C.LLVMLinkOnceAnyLinkage
+ LinkOnceODRLinkage Linkage = C.LLVMLinkOnceODRLinkage
+ WeakAnyLinkage Linkage = C.LLVMWeakAnyLinkage
+ WeakODRLinkage Linkage = C.LLVMWeakODRLinkage
+ AppendingLinkage Linkage = C.LLVMAppendingLinkage
+ InternalLinkage Linkage = C.LLVMInternalLinkage
+ PrivateLinkage Linkage = C.LLVMPrivateLinkage
+ ExternalWeakLinkage Linkage = C.LLVMExternalWeakLinkage
+ CommonLinkage Linkage = C.LLVMCommonLinkage
+)
+
+//-------------------------------------------------------------------------
+// llvm.Visibility
+//-------------------------------------------------------------------------
+
+const (
+ DefaultVisibility Visibility = C.LLVMDefaultVisibility
+ HiddenVisibility Visibility = C.LLVMHiddenVisibility
+ ProtectedVisibility Visibility = C.LLVMProtectedVisibility
+)
+
+//-------------------------------------------------------------------------
+// llvm.CallConv
+//-------------------------------------------------------------------------
+
+const (
+ CCallConv CallConv = C.LLVMCCallConv
+ FastCallConv CallConv = C.LLVMFastCallConv
+ ColdCallConv CallConv = C.LLVMColdCallConv
+ X86StdcallCallConv CallConv = C.LLVMX86StdcallCallConv
+ X86FastcallCallConv CallConv = C.LLVMX86FastcallCallConv
+)
+
+//-------------------------------------------------------------------------
+// llvm.IntPredicate
+//-------------------------------------------------------------------------
+
+const (
+ IntEQ IntPredicate = C.LLVMIntEQ
+ IntNE IntPredicate = C.LLVMIntNE
+ IntUGT IntPredicate = C.LLVMIntUGT
+ IntUGE IntPredicate = C.LLVMIntUGE
+ IntULT IntPredicate = C.LLVMIntULT
+ IntULE IntPredicate = C.LLVMIntULE
+ IntSGT IntPredicate = C.LLVMIntSGT
+ IntSGE IntPredicate = C.LLVMIntSGE
+ IntSLT IntPredicate = C.LLVMIntSLT
+ IntSLE IntPredicate = C.LLVMIntSLE
+)
+
+//-------------------------------------------------------------------------
+// llvm.FloatPredicate
+//-------------------------------------------------------------------------
+
+const (
+ FloatPredicateFalse FloatPredicate = C.LLVMRealPredicateFalse
+ FloatOEQ FloatPredicate = C.LLVMRealOEQ
+ FloatOGT FloatPredicate = C.LLVMRealOGT
+ FloatOGE FloatPredicate = C.LLVMRealOGE
+ FloatOLT FloatPredicate = C.LLVMRealOLT
+ FloatOLE FloatPredicate = C.LLVMRealOLE
+ FloatONE FloatPredicate = C.LLVMRealONE
+ FloatORD FloatPredicate = C.LLVMRealORD
+ FloatUNO FloatPredicate = C.LLVMRealUNO
+ FloatUEQ FloatPredicate = C.LLVMRealUEQ
+ FloatUGT FloatPredicate = C.LLVMRealUGT
+ FloatUGE FloatPredicate = C.LLVMRealUGE
+ FloatULT FloatPredicate = C.LLVMRealULT
+ FloatULE FloatPredicate = C.LLVMRealULE
+ FloatUNE FloatPredicate = C.LLVMRealUNE
+ FloatPredicateTrue FloatPredicate = C.LLVMRealPredicateTrue
+)
+
+//-------------------------------------------------------------------------
+// llvm.LandingPadClause
+//-------------------------------------------------------------------------
+
+const (
+ LandingPadCatch LandingPadClause = C.LLVMLandingPadCatch
+ LandingPadFilter LandingPadClause = C.LLVMLandingPadFilter
+)
+
+//-------------------------------------------------------------------------
+// llvm.Context
+//-------------------------------------------------------------------------
+
+func NewContext() Context { return Context{C.LLVMContextCreate()} }
+func GlobalContext() Context { return Context{C.LLVMGetGlobalContext()} }
+func (c Context) Dispose() { C.LLVMContextDispose(c.C) }
+
+func (c Context) MDKindID(name string) (id int) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ id = int(C.LLVMGetMDKindIDInContext(c.C, cname, C.unsigned(len(name))))
+ return
+}
+
+func MDKindID(name string) (id int) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ id = int(C.LLVMGetMDKindID(cname, C.unsigned(len(name))))
+ return
+}
+
+//-------------------------------------------------------------------------
+// llvm.Module
+//-------------------------------------------------------------------------
+
+// Create and destroy modules.
+// See llvm::Module::Module.
+func NewModule(name string) (m Module) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ m.C = C.LLVMModuleCreateWithName(cname)
+ return
+}
+
+func (c Context) NewModule(name string) (m Module) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ m.C = C.LLVMModuleCreateWithNameInContext(cname, c.C)
+ return
+}
+
+// See llvm::Module::~Module
+func (m Module) Dispose() { C.LLVMDisposeModule(m.C) }
+
+// Data layout. See Module::getDataLayout.
+func (m Module) DataLayout() string {
+ clayout := C.LLVMGetDataLayout(m.C)
+ return C.GoString(clayout)
+}
+
+func (m Module) SetDataLayout(layout string) {
+ clayout := C.CString(layout)
+ defer C.free(unsafe.Pointer(clayout))
+ C.LLVMSetDataLayout(m.C, clayout)
+}
+
+// Target triple. See Module::getTargetTriple.
+func (m Module) Target() string {
+ ctarget := C.LLVMGetTarget(m.C)
+ return C.GoString(ctarget)
+}
+func (m Module) SetTarget(target string) {
+ ctarget := C.CString(target)
+ defer C.free(unsafe.Pointer(ctarget))
+ C.LLVMSetTarget(m.C, ctarget)
+}
+
+func (m Module) GetTypeByName(name string) (t Type) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ t.C = C.LLVMGetTypeByName(m.C, cname)
+ return
+}
+
+// See Module::dump.
+func (m Module) Dump() {
+ C.LLVMDumpModule(m.C)
+}
+
+func (m Module) String() string {
+ cir := C.LLVMPrintModuleToString(m.C)
+ defer C.free(unsafe.Pointer(cir))
+ ir := C.GoString(cir)
+ return ir
+}
+
+// See Module::setModuleInlineAsm.
+func (m Module) SetInlineAsm(asm string) {
+ casm := C.CString(asm)
+ defer C.free(unsafe.Pointer(casm))
+ C.LLVMSetModuleInlineAsm(m.C, casm)
+}
+
+func (m Module) AddNamedMetadataOperand(name string, operand Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ C.LLVMAddNamedMetadataOperand(m.C, cname, operand.C)
+}
+
+func (m Module) Context() (c Context) {
+ c.C = C.LLVMGetModuleContext(m.C)
+ return
+}
+
+//-------------------------------------------------------------------------
+// llvm.Type
+//-------------------------------------------------------------------------
+
+// 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
+
+// See llvm::LLVMTypeKind::getTypeID.
+func (t Type) TypeKind() TypeKind { return TypeKind(C.LLVMGetTypeKind(t.C)) }
+
+// See llvm::LLVMType::getContext.
+func (t Type) Context() (c Context) {
+ c.C = C.LLVMGetTypeContext(t.C)
+ return
+}
+
+// Operations on integer types
+func (c Context) Int1Type() (t Type) { t.C = C.LLVMInt1TypeInContext(c.C); return }
+func (c Context) Int8Type() (t Type) { t.C = C.LLVMInt8TypeInContext(c.C); return }
+func (c Context) Int16Type() (t Type) { t.C = C.LLVMInt16TypeInContext(c.C); return }
+func (c Context) Int32Type() (t Type) { t.C = C.LLVMInt32TypeInContext(c.C); return }
+func (c Context) Int64Type() (t Type) { t.C = C.LLVMInt64TypeInContext(c.C); return }
+func (c Context) IntType(numbits int) (t Type) {
+ t.C = C.LLVMIntTypeInContext(c.C, C.unsigned(numbits))
+ return
+}
+
+func Int1Type() (t Type) { t.C = C.LLVMInt1Type(); return }
+func Int8Type() (t Type) { t.C = C.LLVMInt8Type(); return }
+func Int16Type() (t Type) { t.C = C.LLVMInt16Type(); return }
+func Int32Type() (t Type) { t.C = C.LLVMInt32Type(); return }
+func Int64Type() (t Type) { t.C = C.LLVMInt64Type(); return }
+
+func IntType(numbits int) (t Type) {
+ t.C = C.LLVMIntType(C.unsigned(numbits))
+ return
+}
+
+func (t Type) IntTypeWidth() int {
+ return int(C.LLVMGetIntTypeWidth(t.C))
+}
+
+// Operations on real types
+func (c Context) FloatType() (t Type) { t.C = C.LLVMFloatTypeInContext(c.C); return }
+func (c Context) DoubleType() (t Type) { t.C = C.LLVMDoubleTypeInContext(c.C); return }
+func (c Context) X86FP80Type() (t Type) { t.C = C.LLVMX86FP80TypeInContext(c.C); return }
+func (c Context) FP128Type() (t Type) { t.C = C.LLVMFP128TypeInContext(c.C); return }
+func (c Context) PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128TypeInContext(c.C); return }
+
+func FloatType() (t Type) { t.C = C.LLVMFloatType(); return }
+func DoubleType() (t Type) { t.C = C.LLVMDoubleType(); return }
+func X86FP80Type() (t Type) { t.C = C.LLVMX86FP80Type(); return }
+func FP128Type() (t Type) { t.C = C.LLVMFP128Type(); return }
+func PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128Type(); return }
+
+// Operations on function types
+func FunctionType(returnType Type, paramTypes []Type, isVarArg bool) (t Type) {
+ var pt *C.LLVMTypeRef
+ var ptlen C.unsigned
+ if len(paramTypes) > 0 {
+ pt = llvmTypeRefPtr(&paramTypes[0])
+ ptlen = C.unsigned(len(paramTypes))
+ }
+ t.C = C.LLVMFunctionType(returnType.C,
+ pt,
+ ptlen,
+ boolToLLVMBool(isVarArg))
+ return
+}
+
+func (t Type) IsFunctionVarArg() bool { return C.LLVMIsFunctionVarArg(t.C) != 0 }
+func (t Type) ReturnType() (rt Type) { rt.C = C.LLVMGetReturnType(t.C); return }
+func (t Type) ParamTypesCount() int { return int(C.LLVMCountParamTypes(t.C)) }
+func (t Type) ParamTypes() []Type {
+ count := t.ParamTypesCount()
+ if count > 0 {
+ out := make([]Type, count)
+ C.LLVMGetParamTypes(t.C, llvmTypeRefPtr(&out[0]))
+ return out
+ }
+ return nil
+}
+
+// Operations on struct types
+func (c Context) StructType(elementTypes []Type, packed bool) (t Type) {
+ var pt *C.LLVMTypeRef
+ var ptlen C.unsigned
+ if len(elementTypes) > 0 {
+ pt = llvmTypeRefPtr(&elementTypes[0])
+ ptlen = C.unsigned(len(elementTypes))
+ }
+ t.C = C.LLVMStructTypeInContext(c.C,
+ pt,
+ ptlen,
+ boolToLLVMBool(packed))
+ return
+}
+
+func StructType(elementTypes []Type, packed bool) (t Type) {
+ var pt *C.LLVMTypeRef
+ var ptlen C.unsigned
+ if len(elementTypes) > 0 {
+ pt = llvmTypeRefPtr(&elementTypes[0])
+ ptlen = C.unsigned(len(elementTypes))
+ }
+ t.C = C.LLVMStructType(pt, ptlen, boolToLLVMBool(packed))
+ return
+}
+
+func (c Context) StructCreateNamed(name string) (t Type) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ t.C = C.LLVMStructCreateNamed(c.C, cname)
+ return
+}
+
+func (t Type) StructName() string {
+ return C.GoString(C.LLVMGetStructName(t.C))
+}
+
+func (t Type) StructSetBody(elementTypes []Type, packed bool) {
+ var pt *C.LLVMTypeRef
+ var ptlen C.unsigned
+ if len(elementTypes) > 0 {
+ pt = llvmTypeRefPtr(&elementTypes[0])
+ ptlen = C.unsigned(len(elementTypes))
+ }
+ C.LLVMStructSetBody(t.C, pt, ptlen, boolToLLVMBool(packed))
+}
+
+func (t Type) IsStructPacked() bool { return C.LLVMIsPackedStruct(t.C) != 0 }
+func (t Type) StructElementTypesCount() int { return int(C.LLVMCountStructElementTypes(t.C)) }
+func (t Type) StructElementTypes() []Type {
+ out := make([]Type, t.StructElementTypesCount())
+ if len(out) > 0 {
+ C.LLVMGetStructElementTypes(t.C, llvmTypeRefPtr(&out[0]))
+ }
+ return out
+}
+
+// Operations on array, pointer, and vector types (sequence types)
+func ArrayType(elementType Type, elementCount int) (t Type) {
+ t.C = C.LLVMArrayType(elementType.C, C.unsigned(elementCount))
+ return
+}
+func PointerType(elementType Type, addressSpace int) (t Type) {
+ t.C = C.LLVMPointerType(elementType.C, C.unsigned(addressSpace))
+ return
+}
+func VectorType(elementType Type, elementCount int) (t Type) {
+ t.C = C.LLVMVectorType(elementType.C, C.unsigned(elementCount))
+ return
+}
+
+func (t Type) ElementType() (rt Type) { rt.C = C.LLVMGetElementType(t.C); return }
+func (t Type) ArrayLength() int { return int(C.LLVMGetArrayLength(t.C)) }
+func (t Type) PointerAddressSpace() int { return int(C.LLVMGetPointerAddressSpace(t.C)) }
+func (t Type) VectorSize() int { return int(C.LLVMGetVectorSize(t.C)) }
+
+// Operations on other types
+func (c Context) VoidType() (t Type) { t.C = C.LLVMVoidTypeInContext(c.C); return }
+func (c Context) LabelType() (t Type) { t.C = C.LLVMLabelTypeInContext(c.C); return }
+
+func VoidType() (t Type) { t.C = C.LLVMVoidType(); return }
+func LabelType() (t Type) { t.C = C.LLVMLabelType(); return }
+
+//-------------------------------------------------------------------------
+// llvm.Value
+//-------------------------------------------------------------------------
+
+// Operations on all values
+func (v Value) Type() (t Type) { t.C = C.LLVMTypeOf(v.C); return }
+func (v Value) Name() string { return C.GoString(C.LLVMGetValueName(v.C)) }
+func (v Value) SetName(name string) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ C.LLVMSetValueName(v.C, cname)
+}
+func (v Value) Dump() { C.LLVMDumpValue(v.C) }
+func (v Value) ReplaceAllUsesWith(nv Value) { C.LLVMReplaceAllUsesWith(v.C, nv.C) }
+func (v Value) HasMetadata() bool { return C.LLVMHasMetadata(v.C) != 0 }
+func (v Value) Metadata(kind int) (rv Value) {
+ rv.C = C.LLVMGetMetadata(v.C, C.unsigned(kind))
+ return
+}
+func (v Value) SetMetadata(kind int, node Value) {
+ C.LLVMSetMetadata(v.C, C.unsigned(kind), node.C)
+}
+
+// Conversion functions.
+// Return the input value if it is an instance of the specified class, otherwise NULL.
+// See llvm::dyn_cast_or_null<>.
+func (v Value) IsAArgument() (rv Value) { rv.C = C.LLVMIsAArgument(v.C); return }
+func (v Value) IsABasicBlock() (rv Value) { rv.C = C.LLVMIsABasicBlock(v.C); return }
+func (v Value) IsAInlineAsm() (rv Value) { rv.C = C.LLVMIsAInlineAsm(v.C); return }
+func (v Value) IsAUser() (rv Value) { rv.C = C.LLVMIsAUser(v.C); return }
+func (v Value) IsAConstant() (rv Value) { rv.C = C.LLVMIsAConstant(v.C); return }
+func (v Value) IsAConstantAggregateZero() (rv Value) {
+ rv.C = C.LLVMIsAConstantAggregateZero(v.C)
+ return
+}
+func (v Value) IsAConstantArray() (rv Value) { rv.C = C.LLVMIsAConstantArray(v.C); return }
+func (v Value) IsAConstantExpr() (rv Value) { rv.C = C.LLVMIsAConstantExpr(v.C); return }
+func (v Value) IsAConstantFP() (rv Value) { rv.C = C.LLVMIsAConstantFP(v.C); return }
+func (v Value) IsAConstantInt() (rv Value) { rv.C = C.LLVMIsAConstantInt(v.C); return }
+func (v Value) IsAConstantPointerNull() (rv Value) { rv.C = C.LLVMIsAConstantPointerNull(v.C); return }
+func (v Value) IsAConstantStruct() (rv Value) { rv.C = C.LLVMIsAConstantStruct(v.C); return }
+func (v Value) IsAConstantVector() (rv Value) { rv.C = C.LLVMIsAConstantVector(v.C); return }
+func (v Value) IsAGlobalValue() (rv Value) { rv.C = C.LLVMIsAGlobalValue(v.C); return }
+func (v Value) IsAFunction() (rv Value) { rv.C = C.LLVMIsAFunction(v.C); return }
+func (v Value) IsAGlobalAlias() (rv Value) { rv.C = C.LLVMIsAGlobalAlias(v.C); return }
+func (v Value) IsAGlobalVariable() (rv Value) { rv.C = C.LLVMIsAGlobalVariable(v.C); return }
+func (v Value) IsAUndefValue() (rv Value) { rv.C = C.LLVMIsAUndefValue(v.C); return }
+func (v Value) IsAInstruction() (rv Value) { rv.C = C.LLVMIsAInstruction(v.C); return }
+func (v Value) IsABinaryOperator() (rv Value) { rv.C = C.LLVMIsABinaryOperator(v.C); return }
+func (v Value) IsACallInst() (rv Value) { rv.C = C.LLVMIsACallInst(v.C); return }
+func (v Value) IsAIntrinsicInst() (rv Value) { rv.C = C.LLVMIsAIntrinsicInst(v.C); return }
+func (v Value) IsADbgInfoIntrinsic() (rv Value) { rv.C = C.LLVMIsADbgInfoIntrinsic(v.C); return }
+func (v Value) IsADbgDeclareInst() (rv Value) { rv.C = C.LLVMIsADbgDeclareInst(v.C); return }
+func (v Value) IsAMemIntrinsic() (rv Value) { rv.C = C.LLVMIsAMemIntrinsic(v.C); return }
+func (v Value) IsAMemCpyInst() (rv Value) { rv.C = C.LLVMIsAMemCpyInst(v.C); return }
+func (v Value) IsAMemMoveInst() (rv Value) { rv.C = C.LLVMIsAMemMoveInst(v.C); return }
+func (v Value) IsAMemSetInst() (rv Value) { rv.C = C.LLVMIsAMemSetInst(v.C); return }
+func (v Value) IsACmpInst() (rv Value) { rv.C = C.LLVMIsACmpInst(v.C); return }
+func (v Value) IsAFCmpInst() (rv Value) { rv.C = C.LLVMIsAFCmpInst(v.C); return }
+func (v Value) IsAICmpInst() (rv Value) { rv.C = C.LLVMIsAICmpInst(v.C); return }
+func (v Value) IsAExtractElementInst() (rv Value) { rv.C = C.LLVMIsAExtractElementInst(v.C); return }
+func (v Value) IsAGetElementPtrInst() (rv Value) { rv.C = C.LLVMIsAGetElementPtrInst(v.C); return }
+func (v Value) IsAInsertElementInst() (rv Value) { rv.C = C.LLVMIsAInsertElementInst(v.C); return }
+func (v Value) IsAInsertValueInst() (rv Value) { rv.C = C.LLVMIsAInsertValueInst(v.C); return }
+func (v Value) IsAPHINode() (rv Value) { rv.C = C.LLVMIsAPHINode(v.C); return }
+func (v Value) IsASelectInst() (rv Value) { rv.C = C.LLVMIsASelectInst(v.C); return }
+func (v Value) IsAShuffleVectorInst() (rv Value) { rv.C = C.LLVMIsAShuffleVectorInst(v.C); return }
+func (v Value) IsAStoreInst() (rv Value) { rv.C = C.LLVMIsAStoreInst(v.C); return }
+func (v Value) IsATerminatorInst() (rv Value) { rv.C = C.LLVMIsATerminatorInst(v.C); return }
+func (v Value) IsABranchInst() (rv Value) { rv.C = C.LLVMIsABranchInst(v.C); return }
+func (v Value) IsAInvokeInst() (rv Value) { rv.C = C.LLVMIsAInvokeInst(v.C); return }
+func (v Value) IsAReturnInst() (rv Value) { rv.C = C.LLVMIsAReturnInst(v.C); return }
+func (v Value) IsASwitchInst() (rv Value) { rv.C = C.LLVMIsASwitchInst(v.C); return }
+func (v Value) IsAUnreachableInst() (rv Value) { rv.C = C.LLVMIsAUnreachableInst(v.C); return }
+func (v Value) IsAUnaryInstruction() (rv Value) { rv.C = C.LLVMIsAUnaryInstruction(v.C); return }
+func (v Value) IsAAllocaInst() (rv Value) { rv.C = C.LLVMIsAAllocaInst(v.C); return }
+func (v Value) IsACastInst() (rv Value) { rv.C = C.LLVMIsACastInst(v.C); return }
+func (v Value) IsABitCastInst() (rv Value) { rv.C = C.LLVMIsABitCastInst(v.C); return }
+func (v Value) IsAFPExtInst() (rv Value) { rv.C = C.LLVMIsAFPExtInst(v.C); return }
+func (v Value) IsAFPToSIInst() (rv Value) { rv.C = C.LLVMIsAFPToSIInst(v.C); return }
+func (v Value) IsAFPToUIInst() (rv Value) { rv.C = C.LLVMIsAFPToUIInst(v.C); return }
+func (v Value) IsAFPTruncInst() (rv Value) { rv.C = C.LLVMIsAFPTruncInst(v.C); return }
+func (v Value) IsAIntToPtrInst() (rv Value) { rv.C = C.LLVMIsAIntToPtrInst(v.C); return }
+func (v Value) IsAPtrToIntInst() (rv Value) { rv.C = C.LLVMIsAPtrToIntInst(v.C); return }
+func (v Value) IsASExtInst() (rv Value) { rv.C = C.LLVMIsASExtInst(v.C); return }
+func (v Value) IsASIToFPInst() (rv Value) { rv.C = C.LLVMIsASIToFPInst(v.C); return }
+func (v Value) IsATruncInst() (rv Value) { rv.C = C.LLVMIsATruncInst(v.C); return }
+func (v Value) IsAUIToFPInst() (rv Value) { rv.C = C.LLVMIsAUIToFPInst(v.C); return }
+func (v Value) IsAZExtInst() (rv Value) { rv.C = C.LLVMIsAZExtInst(v.C); return }
+func (v Value) IsAExtractValueInst() (rv Value) { rv.C = C.LLVMIsAExtractValueInst(v.C); return }
+func (v Value) IsALoadInst() (rv Value) { rv.C = C.LLVMIsALoadInst(v.C); return }
+func (v Value) IsAVAArgInst() (rv Value) { rv.C = C.LLVMIsAVAArgInst(v.C); return }
+
+// Operations on Uses
+func (v Value) FirstUse() (u Use) { u.C = C.LLVMGetFirstUse(v.C); return }
+func (u Use) NextUse() (ru Use) { ru.C = C.LLVMGetNextUse(u.C); return }
+func (u Use) User() (v Value) { v.C = C.LLVMGetUser(u.C); return }
+func (u Use) UsedValue() (v Value) { v.C = C.LLVMGetUsedValue(u.C); return }
+
+// Operations on Users
+func (v Value) Operand(i int) (rv Value) { rv.C = C.LLVMGetOperand(v.C, C.unsigned(i)); return }
+func (v Value) SetOperand(i int, op Value) { C.LLVMSetOperand(v.C, C.unsigned(i), op.C) }
+func (v Value) OperandsCount() int { return int(C.LLVMGetNumOperands(v.C)) }
+
+// Operations on constants of any type
+func ConstNull(t Type) (v Value) { v.C = C.LLVMConstNull(t.C); return }
+func ConstAllOnes(t Type) (v Value) { v.C = C.LLVMConstAllOnes(t.C); return }
+func Undef(t Type) (v Value) { v.C = C.LLVMGetUndef(t.C); return }
+func (v Value) IsConstant() bool { return C.LLVMIsConstant(v.C) != 0 }
+func (v Value) IsNull() bool { return C.LLVMIsNull(v.C) != 0 }
+func (v Value) IsUndef() bool { return C.LLVMIsUndef(v.C) != 0 }
+func ConstPointerNull(t Type) (v Value) { v.C = C.LLVMConstPointerNull(t.C); return }
+
+// Operations on metadata
+func (c Context) MDString(str string) (v Value) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ v.C = C.LLVMMDStringInContext(c.C, cstr, C.unsigned(len(str)))
+ return
+}
+func MDString(str string) (v Value) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ v.C = C.LLVMMDString(cstr, C.unsigned(len(str)))
+ return
+}
+func (c Context) MDNode(vals []Value) (v Value) {
+ ptr, nvals := llvmValueRefs(vals)
+ v.C = C.LLVMMDNodeInContext(c.C, ptr, nvals)
+ return
+}
+func MDNode(vals []Value) (v Value) {
+ ptr, nvals := llvmValueRefs(vals)
+ v.C = C.LLVMMDNode(ptr, nvals)
+ return
+}
+
+// Operations on scalar constants
+func ConstInt(t Type, n uint64, signExtend bool) (v Value) {
+ v.C = C.LLVMConstInt(t.C,
+ C.ulonglong(n),
+ boolToLLVMBool(signExtend))
+ return
+}
+func ConstIntFromString(t Type, str string, radix int) (v Value) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ v.C = C.LLVMConstIntOfString(t.C, cstr, C.uint8_t(radix))
+ return
+}
+func ConstFloat(t Type, n float64) (v Value) {
+ v.C = C.LLVMConstReal(t.C, C.double(n))
+ return
+}
+func ConstFloatFromString(t Type, str string) (v Value) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ v.C = C.LLVMConstRealOfString(t.C, cstr)
+ return
+}
+
+func (v Value) ZExtValue() uint64 { return uint64(C.LLVMConstIntGetZExtValue(v.C)) }
+func (v Value) SExtValue() int64 { return int64(C.LLVMConstIntGetSExtValue(v.C)) }
+
+// Operations on composite constants
+func (c Context) ConstString(str string, addnull bool) (v Value) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ v.C = C.LLVMConstStringInContext(c.C, cstr,
+ C.unsigned(len(str)), boolToLLVMBool(!addnull))
+ return
+}
+func (c Context) ConstStruct(constVals []Value, packed bool) (v Value) {
+ ptr, nvals := llvmValueRefs(constVals)
+ v.C = C.LLVMConstStructInContext(c.C, ptr, nvals,
+ boolToLLVMBool(packed))
+ return
+}
+func ConstNamedStruct(t Type, constVals []Value) (v Value) {
+ ptr, nvals := llvmValueRefs(constVals)
+ v.C = C.LLVMConstNamedStruct(t.C, ptr, nvals)
+ return
+}
+func ConstString(str string, addnull bool) (v Value) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ v.C = C.LLVMConstString(cstr,
+ C.unsigned(len(str)), boolToLLVMBool(!addnull))
+ return
+}
+func ConstArray(t Type, constVals []Value) (v Value) {
+ ptr, nvals := llvmValueRefs(constVals)
+ v.C = C.LLVMConstArray(t.C, ptr, nvals)
+ return
+}
+func ConstStruct(constVals []Value, packed bool) (v Value) {
+ ptr, nvals := llvmValueRefs(constVals)
+ v.C = C.LLVMConstStruct(ptr, nvals, boolToLLVMBool(packed))
+ return
+}
+func ConstVector(scalarConstVals []Value, packed bool) (v Value) {
+ ptr, nvals := llvmValueRefs(scalarConstVals)
+ v.C = C.LLVMConstVector(ptr, nvals)
+ return
+}
+
+// Constant expressions
+func (v Value) Opcode() Opcode { return Opcode(C.LLVMGetConstOpcode(v.C)) }
+func (v Value) InstructionOpcode() Opcode { return Opcode(C.LLVMGetInstructionOpcode(v.C)) }
+func AlignOf(t Type) (v Value) { v.C = C.LLVMAlignOf(t.C); return }
+func SizeOf(t Type) (v Value) { v.C = C.LLVMSizeOf(t.C); return }
+func ConstNeg(v Value) (rv Value) { rv.C = C.LLVMConstNeg(v.C); return }
+func ConstNSWNeg(v Value) (rv Value) { rv.C = C.LLVMConstNSWNeg(v.C); return }
+func ConstNUWNeg(v Value) (rv Value) { rv.C = C.LLVMConstNUWNeg(v.C); return }
+func ConstFNeg(v Value) (rv Value) { rv.C = C.LLVMConstFNeg(v.C); return }
+func ConstNot(v Value) (rv Value) { rv.C = C.LLVMConstNot(v.C); return }
+func ConstAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAdd(lhs.C, rhs.C); return }
+func ConstNSWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWAdd(lhs.C, rhs.C); return }
+func ConstNUWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWAdd(lhs.C, rhs.C); return }
+func ConstFAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFAdd(lhs.C, rhs.C); return }
+func ConstSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSub(lhs.C, rhs.C); return }
+func ConstNSWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWSub(lhs.C, rhs.C); return }
+func ConstNUWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWSub(lhs.C, rhs.C); return }
+func ConstFSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFSub(lhs.C, rhs.C); return }
+func ConstMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstMul(lhs.C, rhs.C); return }
+func ConstNSWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWMul(lhs.C, rhs.C); return }
+func ConstNUWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWMul(lhs.C, rhs.C); return }
+func ConstFMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFMul(lhs.C, rhs.C); return }
+func ConstUDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstUDiv(lhs.C, rhs.C); return }
+func ConstSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSDiv(lhs.C, rhs.C); return }
+func ConstExactSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstExactSDiv(lhs.C, rhs.C); return }
+func ConstFDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFDiv(lhs.C, rhs.C); return }
+func ConstURem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstURem(lhs.C, rhs.C); return }
+func ConstSRem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSRem(lhs.C, rhs.C); return }
+func ConstFRem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFRem(lhs.C, rhs.C); return }
+func ConstAnd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAnd(lhs.C, rhs.C); return }
+func ConstOr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstOr(lhs.C, rhs.C); return }
+func ConstXor(lhs, rhs Value) (v Value) { v.C = C.LLVMConstXor(lhs.C, rhs.C); return }
+
+func ConstICmp(pred IntPredicate, lhs, rhs Value) (v Value) {
+ v.C = C.LLVMConstICmp(C.LLVMIntPredicate(pred), lhs.C, rhs.C)
+ return
+}
+func ConstFCmp(pred FloatPredicate, lhs, rhs Value) (v Value) {
+ v.C = C.LLVMConstFCmp(C.LLVMRealPredicate(pred), lhs.C, rhs.C)
+ return
+}
+
+func ConstShl(lhs, rhs Value) (v Value) { v.C = C.LLVMConstShl(lhs.C, rhs.C); return }
+func ConstLShr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstLShr(lhs.C, rhs.C); return }
+func ConstAShr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAShr(lhs.C, rhs.C); return }
+
+func ConstGEP(v Value, indices []Value) (rv Value) {
+ ptr, nvals := llvmValueRefs(indices)
+ rv.C = C.LLVMConstGEP(v.C, ptr, nvals)
+ return
+}
+func ConstInBoundsGEP(v Value, indices []Value) (rv Value) {
+ ptr, nvals := llvmValueRefs(indices)
+ rv.C = C.LLVMConstInBoundsGEP(v.C, ptr, nvals)
+ return
+}
+func ConstTrunc(v Value, t Type) (rv Value) { rv.C = C.LLVMConstTrunc(v.C, t.C); return }
+func ConstSExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSExt(v.C, t.C); return }
+func ConstZExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstZExt(v.C, t.C); return }
+func ConstFPTrunc(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPTrunc(v.C, t.C); return }
+func ConstFPExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPExt(v.C, t.C); return }
+func ConstUIToFP(v Value, t Type) (rv Value) { rv.C = C.LLVMConstUIToFP(v.C, t.C); return }
+func ConstSIToFP(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSIToFP(v.C, t.C); return }
+func ConstFPToUI(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPToUI(v.C, t.C); return }
+func ConstFPToSI(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPToSI(v.C, t.C); return }
+func ConstPtrToInt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPtrToInt(v.C, t.C); return }
+func ConstIntToPtr(v Value, t Type) (rv Value) { rv.C = C.LLVMConstIntToPtr(v.C, t.C); return }
+func ConstBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstBitCast(v.C, t.C); return }
+func ConstZExtOrBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstZExtOrBitCast(v.C, t.C); return }
+func ConstSExtOrBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSExtOrBitCast(v.C, t.C); return }
+func ConstTruncOrBitCast(v Value, t Type) (rv Value) {
+ rv.C = C.LLVMConstTruncOrBitCast(v.C, t.C)
+ return
+}
+func ConstPointerCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPointerCast(v.C, t.C); return }
+func ConstIntCast(v Value, t Type, signed bool) (rv Value) {
+ rv.C = C.LLVMConstIntCast(v.C, t.C, boolToLLVMBool(signed))
+ return
+}
+func ConstFPCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPCast(v.C, t.C); return }
+func ConstSelect(cond, iftrue, iffalse Value) (rv Value) {
+ rv.C = C.LLVMConstSelect(cond.C, iftrue.C, iffalse.C)
+ return
+}
+func ConstExtractElement(vec, i Value) (rv Value) {
+ rv.C = C.LLVMConstExtractElement(vec.C, i.C)
+ return
+}
+func ConstInsertElement(vec, elem, i Value) (rv Value) {
+ rv.C = C.LLVMConstInsertElement(vec.C, elem.C, i.C)
+ return
+}
+func ConstShuffleVector(veca, vecb, mask Value) (rv Value) {
+ rv.C = C.LLVMConstShuffleVector(veca.C, vecb.C, mask.C)
+ return
+}
+
+//TODO
+//LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
+// unsigned NumIdx);
+
+func ConstExtractValue(agg Value, indices []uint32) (rv Value) {
+ n := len(indices)
+ if n == 0 {
+ panic("one or more indices are required")
+ }
+ ptr := (*C.unsigned)(&indices[0])
+ rv.C = C.LLVMConstExtractValue(agg.C, ptr, C.unsigned(n))
+ return
+}
+
+func ConstInsertValue(agg, val Value, indices []uint32) (rv Value) {
+ n := len(indices)
+ if n == 0 {
+ panic("one or more indices are required")
+ }
+ ptr := (*C.unsigned)(&indices[0])
+ rv.C = C.LLVMConstInsertValue(agg.C, val.C, ptr, C.unsigned(n))
+ return
+}
+
+func BlockAddress(f Value, bb BasicBlock) (v Value) {
+ v.C = C.LLVMBlockAddress(f.C, bb.C)
+ return
+}
+
+// Operations on global variables, functions, and aliases (globals)
+func (v Value) GlobalParent() (m Module) { m.C = C.LLVMGetGlobalParent(v.C); return }
+func (v Value) IsDeclaration() bool { return C.LLVMIsDeclaration(v.C) != 0 }
+func (v Value) Linkage() Linkage { return Linkage(C.LLVMGetLinkage(v.C)) }
+func (v Value) SetLinkage(l Linkage) { C.LLVMSetLinkage(v.C, C.LLVMLinkage(l)) }
+func (v Value) Section() string { return C.GoString(C.LLVMGetSection(v.C)) }
+func (v Value) SetSection(str string) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ C.LLVMSetSection(v.C, cstr)
+}
+func (v Value) Visibility() Visibility { return Visibility(C.LLVMGetVisibility(v.C)) }
+func (v Value) SetVisibility(vi Visibility) { C.LLVMSetVisibility(v.C, C.LLVMVisibility(vi)) }
+func (v Value) Alignment() int { return int(C.LLVMGetAlignment(v.C)) }
+func (v Value) SetAlignment(a int) { C.LLVMSetAlignment(v.C, C.unsigned(a)) }
+func (v Value) SetUnnamedAddr(ua bool) { C.LLVMSetUnnamedAddr(v.C, boolToLLVMBool(ua)) }
+
+// Operations on global variables
+func AddGlobal(m Module, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMAddGlobal(m.C, t.C, cname)
+ return
+}
+func AddGlobalInAddressSpace(m Module, t Type, name string, addressSpace int) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMAddGlobalInAddressSpace(m.C, t.C, cname, C.unsigned(addressSpace))
+ return
+}
+func (m Module) NamedGlobal(name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMGetNamedGlobal(m.C, cname)
+ return
+}
+
+func (m Module) FirstGlobal() (v Value) { v.C = C.LLVMGetFirstGlobal(m.C); return }
+func (m Module) LastGlobal() (v Value) { v.C = C.LLVMGetLastGlobal(m.C); return }
+func NextGlobal(v Value) (rv Value) { rv.C = C.LLVMGetNextGlobal(v.C); return }
+func PrevGlobal(v Value) (rv Value) { rv.C = C.LLVMGetPreviousGlobal(v.C); return }
+func (v Value) EraseFromParentAsGlobal() { C.LLVMDeleteGlobal(v.C) }
+func (v Value) Initializer() (rv Value) { rv.C = C.LLVMGetInitializer(v.C); return }
+func (v Value) SetInitializer(cv Value) { C.LLVMSetInitializer(v.C, cv.C) }
+func (v Value) IsThreadLocal() bool { return C.LLVMIsThreadLocal(v.C) != 0 }
+func (v Value) SetThreadLocal(tl bool) { C.LLVMSetThreadLocal(v.C, boolToLLVMBool(tl)) }
+func (v Value) IsGlobalConstant() bool { return C.LLVMIsGlobalConstant(v.C) != 0 }
+func (v Value) SetGlobalConstant(gc bool) { C.LLVMSetGlobalConstant(v.C, boolToLLVMBool(gc)) }
+
+// Operations on aliases
+func AddAlias(m Module, t Type, aliasee Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMAddAlias(m.C, t.C, aliasee.C, cname)
+ return
+}
+
+// Operations on functions
+func AddFunction(m Module, name string, ft Type) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMAddFunction(m.C, cname, ft.C)
+ return
+}
+
+func (m Module) NamedFunction(name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMGetNamedFunction(m.C, cname)
+ return
+}
+
+func (m Module) FirstFunction() (v Value) { v.C = C.LLVMGetFirstFunction(m.C); return }
+func (m Module) LastFunction() (v Value) { v.C = C.LLVMGetLastFunction(m.C); return }
+func NextFunction(v Value) (rv Value) { rv.C = C.LLVMGetNextFunction(v.C); return }
+func PrevFunction(v Value) (rv Value) { rv.C = C.LLVMGetPreviousFunction(v.C); return }
+func (v Value) EraseFromParentAsFunction() { C.LLVMDeleteFunction(v.C) }
+func (v Value) IntrinsicID() int { return int(C.LLVMGetIntrinsicID(v.C)) }
+func (v Value) FunctionCallConv() CallConv {
+ return CallConv(C.LLVMCallConv(C.LLVMGetFunctionCallConv(v.C)))
+}
+func (v Value) SetFunctionCallConv(cc CallConv) { C.LLVMSetFunctionCallConv(v.C, C.unsigned(cc)) }
+func (v Value) GC() string { return C.GoString(C.LLVMGetGC(v.C)) }
+func (v Value) SetGC(name string) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ C.LLVMSetGC(v.C, cname)
+}
+func (v Value) AddFunctionAttr(a Attribute) { C.LLVMAddFunctionAttr2(v.C, C.uint64_t(a)) }
+func (v Value) FunctionAttr() Attribute { return Attribute(C.LLVMGetFunctionAttr2(v.C)) }
+func (v Value) RemoveFunctionAttr(a Attribute) { C.LLVMRemoveFunctionAttr2(v.C, C.uint64_t(a)) }
+func (v Value) AddTargetDependentFunctionAttr(attr, value string) {
+ cattr := C.CString(attr)
+ defer C.free(unsafe.Pointer(cattr))
+ cvalue := C.CString(value)
+ defer C.free(unsafe.Pointer(cvalue))
+ C.LLVMAddTargetDependentFunctionAttr(v.C, cattr, cvalue)
+}
+
+// Operations on parameters
+func (v Value) ParamsCount() int { return int(C.LLVMCountParams(v.C)) }
+func (v Value) Params() []Value {
+ out := make([]Value, v.ParamsCount())
+ if len(out) > 0 {
+ C.LLVMGetParams(v.C, llvmValueRefPtr(&out[0]))
+ }
+ return out
+}
+func (v Value) Param(i int) (rv Value) { rv.C = C.LLVMGetParam(v.C, C.unsigned(i)); return }
+func (v Value) ParamParent() (rv Value) { rv.C = C.LLVMGetParamParent(v.C); return }
+func (v Value) FirstParam() (rv Value) { rv.C = C.LLVMGetFirstParam(v.C); return }
+func (v Value) LastParam() (rv Value) { rv.C = C.LLVMGetLastParam(v.C); return }
+func NextParam(v Value) (rv Value) { rv.C = C.LLVMGetNextParam(v.C); return }
+func PrevParam(v Value) (rv Value) { rv.C = C.LLVMGetPreviousParam(v.C); return }
+func (v Value) AddAttribute(a Attribute) {
+ if a >= 1<<32 {
+ panic("attribute value currently unsupported")
+ }
+ C.LLVMAddAttribute(v.C, C.LLVMAttribute(a))
+}
+func (v Value) RemoveAttribute(a Attribute) {
+ if a >= 1<<32 {
+ panic("attribute value currently unsupported")
+ }
+ C.LLVMRemoveAttribute(v.C, C.LLVMAttribute(a))
+}
+func (v Value) Attribute() Attribute { return Attribute(C.LLVMGetAttribute(v.C)) }
+func (v Value) SetParamAlignment(align int) { C.LLVMSetParamAlignment(v.C, C.unsigned(align)) }
+
+// Operations on basic blocks
+func (bb BasicBlock) AsValue() (v Value) { v.C = C.LLVMBasicBlockAsValue(bb.C); return }
+func (v Value) IsBasicBlock() bool { return C.LLVMValueIsBasicBlock(v.C) != 0 }
+func (v Value) AsBasicBlock() (bb BasicBlock) { bb.C = C.LLVMValueAsBasicBlock(v.C); return }
+func (bb BasicBlock) Parent() (v Value) { v.C = C.LLVMGetBasicBlockParent(bb.C); return }
+func (v Value) BasicBlocksCount() int { return int(C.LLVMCountBasicBlocks(v.C)) }
+func (v Value) BasicBlocks() []BasicBlock {
+ out := make([]BasicBlock, v.BasicBlocksCount())
+ C.LLVMGetBasicBlocks(v.C, llvmBasicBlockRefPtr(&out[0]))
+ return out
+}
+func (v Value) FirstBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetFirstBasicBlock(v.C); return }
+func (v Value) LastBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetLastBasicBlock(v.C); return }
+func NextBasicBlock(bb BasicBlock) (rbb BasicBlock) { rbb.C = C.LLVMGetNextBasicBlock(bb.C); return }
+func PrevBasicBlock(bb BasicBlock) (rbb BasicBlock) { rbb.C = C.LLVMGetPreviousBasicBlock(bb.C); return }
+func (v Value) EntryBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetEntryBasicBlock(v.C); return }
+func (c Context) AddBasicBlock(f Value, name string) (bb BasicBlock) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ bb.C = C.LLVMAppendBasicBlockInContext(c.C, f.C, cname)
+ return
+}
+func (c Context) InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ bb.C = C.LLVMInsertBasicBlockInContext(c.C, ref.C, cname)
+ return
+}
+func AddBasicBlock(f Value, name string) (bb BasicBlock) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ bb.C = C.LLVMAppendBasicBlock(f.C, cname)
+ return
+}
+func InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ bb.C = C.LLVMInsertBasicBlock(ref.C, cname)
+ return
+}
+func (bb BasicBlock) EraseFromParent() { C.LLVMDeleteBasicBlock(bb.C) }
+func (bb BasicBlock) MoveBefore(pos BasicBlock) { C.LLVMMoveBasicBlockBefore(bb.C, pos.C) }
+func (bb BasicBlock) MoveAfter(pos BasicBlock) { C.LLVMMoveBasicBlockAfter(bb.C, pos.C) }
+
+// Operations on instructions
+func (v Value) InstructionParent() (bb BasicBlock) { bb.C = C.LLVMGetInstructionParent(v.C); return }
+func (bb BasicBlock) FirstInstruction() (v Value) { v.C = C.LLVMGetFirstInstruction(bb.C); return }
+func (bb BasicBlock) LastInstruction() (v Value) { v.C = C.LLVMGetLastInstruction(bb.C); return }
+func NextInstruction(v Value) (rv Value) { rv.C = C.LLVMGetNextInstruction(v.C); return }
+func PrevInstruction(v Value) (rv Value) { rv.C = C.LLVMGetPreviousInstruction(v.C); return }
+
+// Operations on call sites
+func (v Value) SetInstructionCallConv(cc CallConv) {
+ C.LLVMSetInstructionCallConv(v.C, C.unsigned(cc))
+}
+func (v Value) InstructionCallConv() CallConv {
+ return CallConv(C.LLVMCallConv(C.LLVMGetInstructionCallConv(v.C)))
+}
+func (v Value) AddInstrAttribute(i int, a Attribute) {
+ if a >= 1<<32 {
+ panic("attribute value currently unsupported")
+ }
+ C.LLVMAddInstrAttribute(v.C, C.unsigned(i), C.LLVMAttribute(a))
+}
+func (v Value) RemoveInstrAttribute(i int, a Attribute) {
+ if a >= 1<<32 {
+ panic("attribute value currently unsupported")
+ }
+ C.LLVMRemoveInstrAttribute(v.C, C.unsigned(i), C.LLVMAttribute(a))
+}
+func (v Value) SetInstrParamAlignment(i int, align int) {
+ C.LLVMSetInstrParamAlignment(v.C, C.unsigned(i), C.unsigned(align))
+}
+
+// Operations on call instructions (only)
+func (v Value) IsTailCall() bool { return C.LLVMIsTailCall(v.C) != 0 }
+func (v Value) SetTailCall(is bool) { C.LLVMSetTailCall(v.C, boolToLLVMBool(is)) }
+
+// Operations on phi nodes
+func (v Value) AddIncoming(vals []Value, blocks []BasicBlock) {
+ ptr, nvals := llvmValueRefs(vals)
+ C.LLVMAddIncoming(v.C, ptr, llvmBasicBlockRefPtr(&blocks[0]), nvals)
+}
+func (v Value) IncomingCount() int { return int(C.LLVMCountIncoming(v.C)) }
+func (v Value) IncomingValue(i int) (rv Value) {
+ rv.C = C.LLVMGetIncomingValue(v.C, C.unsigned(i))
+ return
+}
+func (v Value) IncomingBlock(i int) (bb BasicBlock) {
+ bb.C = C.LLVMGetIncomingBlock(v.C, C.unsigned(i))
+ return
+}
+
+//-------------------------------------------------------------------------
+// llvm.Builder
+//-------------------------------------------------------------------------
+
+// An instruction builder represents a point within a basic block, and is the
+// exclusive means of building instructions using the C interface.
+
+func (c Context) NewBuilder() (b Builder) { b.C = C.LLVMCreateBuilderInContext(c.C); return }
+func NewBuilder() (b Builder) { b.C = C.LLVMCreateBuilder(); return }
+func (b Builder) SetInsertPoint(block BasicBlock, instr Value) {
+ C.LLVMPositionBuilder(b.C, block.C, instr.C)
+}
+func (b Builder) SetInsertPointBefore(instr Value) { C.LLVMPositionBuilderBefore(b.C, instr.C) }
+func (b Builder) SetInsertPointAtEnd(block BasicBlock) { C.LLVMPositionBuilderAtEnd(b.C, block.C) }
+func (b Builder) GetInsertBlock() (bb BasicBlock) { bb.C = C.LLVMGetInsertBlock(b.C); return }
+func (b Builder) ClearInsertionPoint() { C.LLVMClearInsertionPosition(b.C) }
+func (b Builder) Insert(instr Value) { C.LLVMInsertIntoBuilder(b.C, instr.C) }
+func (b Builder) InsertWithName(instr Value, name string) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ C.LLVMInsertIntoBuilderWithName(b.C, instr.C, cname)
+}
+func (b Builder) Dispose() { C.LLVMDisposeBuilder(b.C) }
+
+// Metadata
+func (b Builder) SetCurrentDebugLocation(v Value) { C.LLVMSetCurrentDebugLocation(b.C, v.C) }
+func (b Builder) CurrentDebugLocation() (v Value) { v.C = C.LLVMGetCurrentDebugLocation(b.C); return }
+func (b Builder) SetInstDebugLocation(v Value) { C.LLVMSetInstDebugLocation(b.C, v.C) }
+func (b Builder) InsertDeclare(module Module, storage Value, md Value) Value {
+ f := module.NamedFunction("llvm.dbg.declare")
+ if f.IsNil() {
+ ftyp := FunctionType(VoidType(), []Type{storage.Type(), md.Type()}, false)
+ f = AddFunction(module, "llvm.dbg.declare", ftyp)
+ }
+ return b.CreateCall(f, []Value{storage, md}, "")
+}
+
+// Terminators
+func (b Builder) CreateRetVoid() (rv Value) { rv.C = C.LLVMBuildRetVoid(b.C); return }
+func (b Builder) CreateRet(v Value) (rv Value) { rv.C = C.LLVMBuildRet(b.C, v.C); return }
+func (b Builder) CreateAggregateRet(vs []Value) (rv Value) {
+ ptr, nvals := llvmValueRefs(vs)
+ rv.C = C.LLVMBuildAggregateRet(b.C, ptr, nvals)
+ return
+}
+func (b Builder) CreateBr(bb BasicBlock) (rv Value) { rv.C = C.LLVMBuildBr(b.C, bb.C); return }
+func (b Builder) CreateCondBr(ifv Value, thenb, elseb BasicBlock) (rv Value) {
+ rv.C = C.LLVMBuildCondBr(b.C, ifv.C, thenb.C, elseb.C)
+ return
+}
+func (b Builder) CreateSwitch(v Value, elseb BasicBlock, numCases int) (rv Value) {
+ rv.C = C.LLVMBuildSwitch(b.C, v.C, elseb.C, C.unsigned(numCases))
+ return
+}
+func (b Builder) CreateIndirectBr(addr Value, numDests int) (rv Value) {
+ rv.C = C.LLVMBuildIndirectBr(b.C, addr.C, C.unsigned(numDests))
+ return
+}
+func (b Builder) CreateInvoke(fn Value, args []Value, then, catch BasicBlock, name string) (rv Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ ptr, nvals := llvmValueRefs(args)
+ rv.C = C.LLVMBuildInvoke(b.C, fn.C, ptr, nvals, then.C, catch.C, cname)
+ return
+}
+func (b Builder) CreateUnreachable() (rv Value) { rv.C = C.LLVMBuildUnreachable(b.C); return }
+
+// Add a case to the switch instruction
+func (v Value) AddCase(on Value, dest BasicBlock) { C.LLVMAddCase(v.C, on.C, dest.C) }
+
+// Add a destination to the indirectbr instruction
+func (v Value) AddDest(dest BasicBlock) { C.LLVMAddDestination(v.C, dest.C) }
+
+// Arithmetic
+func (b Builder) CreateAdd(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildAdd(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateNSWAdd(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildNSWAdd(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateNUWAdd(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildNUWAdd(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateFAdd(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFAdd(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateSub(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildSub(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateNSWSub(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildNSWSub(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateNUWSub(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildNUWSub(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateFSub(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ v.C = C.LLVMBuildFSub(b.C, lhs.C, rhs.C, cname)
+ C.free(unsafe.Pointer(cname))
+ return
+}
+func (b Builder) CreateMul(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildMul(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateNSWMul(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildNSWMul(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateNUWMul(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildNUWMul(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateFMul(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFMul(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateUDiv(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildUDiv(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateSDiv(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildSDiv(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateExactSDiv(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildExactSDiv(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateFDiv(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFDiv(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateURem(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildURem(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateSRem(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildSRem(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateFRem(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFRem(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateShl(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildShl(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateLShr(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildLShr(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateAShr(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildAShr(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateAnd(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildAnd(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateOr(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildOr(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateXor(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildXor(b.C, lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateBinOp(op Opcode, lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildBinOp(b.C, C.LLVMOpcode(op), lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateNeg(v Value, name string) (rv Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ rv.C = C.LLVMBuildNeg(b.C, v.C, cname)
+ return
+}
+func (b Builder) CreateNSWNeg(v Value, name string) (rv Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ rv.C = C.LLVMBuildNSWNeg(b.C, v.C, cname)
+ return
+}
+func (b Builder) CreateNUWNeg(v Value, name string) (rv Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ rv.C = C.LLVMBuildNUWNeg(b.C, v.C, cname)
+ return
+}
+func (b Builder) CreateFNeg(v Value, name string) (rv Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ rv.C = C.LLVMBuildFNeg(b.C, v.C, cname)
+ return
+}
+func (b Builder) CreateNot(v Value, name string) (rv Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ rv.C = C.LLVMBuildNot(b.C, v.C, cname)
+ return
+}
+
+// Memory
+
+func (b Builder) CreateMalloc(t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildMalloc(b.C, t.C, cname)
+ return
+}
+func (b Builder) CreateArrayMalloc(t Type, val Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildArrayMalloc(b.C, t.C, val.C, cname)
+ return
+}
+func (b Builder) CreateAlloca(t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildAlloca(b.C, t.C, cname)
+ return
+}
+func (b Builder) CreateArrayAlloca(t Type, val Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildArrayAlloca(b.C, t.C, val.C, cname)
+ return
+}
+func (b Builder) CreateFree(p Value) (v Value) {
+ v.C = C.LLVMBuildFree(b.C, p.C)
+ return
+}
+func (b Builder) CreateLoad(p Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildLoad(b.C, p.C, cname)
+ return
+}
+func (b Builder) CreateStore(val Value, p Value) (v Value) {
+ v.C = C.LLVMBuildStore(b.C, val.C, p.C)
+ return
+}
+func (b Builder) CreateGEP(p Value, indices []Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ ptr, nvals := llvmValueRefs(indices)
+ v.C = C.LLVMBuildGEP(b.C, p.C, ptr, nvals, cname)
+ return
+}
+func (b Builder) CreateInBoundsGEP(p Value, indices []Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ ptr, nvals := llvmValueRefs(indices)
+ v.C = C.LLVMBuildInBoundsGEP(b.C, p.C, ptr, nvals, cname)
+ return
+}
+func (b Builder) CreateStructGEP(p Value, i int, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildStructGEP(b.C, p.C, C.unsigned(i), cname)
+ return
+}
+func (b Builder) CreateGlobalString(str, name string) (v Value) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildGlobalString(b.C, cstr, cname)
+ return
+}
+func (b Builder) CreateGlobalStringPtr(str, name string) (v Value) {
+ cstr := C.CString(str)
+ defer C.free(unsafe.Pointer(cstr))
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildGlobalStringPtr(b.C, cstr, cname)
+ return
+}
+
+// Casts
+func (b Builder) CreateTrunc(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildTrunc(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateZExt(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildZExt(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateSExt(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildSExt(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateFPToUI(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFPToUI(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateFPToSI(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFPToSI(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateUIToFP(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildUIToFP(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateSIToFP(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildSIToFP(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateFPTrunc(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFPTrunc(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateFPExt(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFPExt(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreatePtrToInt(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildPtrToInt(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateIntToPtr(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildIntToPtr(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateBitCast(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildBitCast(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateZExtOrBitCast(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildZExtOrBitCast(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateSExtOrBitCast(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildSExtOrBitCast(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateTruncOrBitCast(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildTruncOrBitCast(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateCast(val Value, op Opcode, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildCast(b.C, C.LLVMOpcode(op), val.C, t.C, cname)
+ return
+} //
+func (b Builder) CreatePointerCast(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildPointerCast(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateIntCast(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildIntCast(b.C, val.C, t.C, cname)
+ return
+}
+func (b Builder) CreateFPCast(val Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFPCast(b.C, val.C, t.C, cname)
+ return
+}
+
+// Comparisons
+func (b Builder) CreateICmp(pred IntPredicate, lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildICmp(b.C, C.LLVMIntPredicate(pred), lhs.C, rhs.C, cname)
+ return
+}
+func (b Builder) CreateFCmp(pred FloatPredicate, lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildFCmp(b.C, C.LLVMRealPredicate(pred), lhs.C, rhs.C, cname)
+ return
+}
+
+// Miscellaneous instructions
+func (b Builder) CreatePHI(t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildPhi(b.C, t.C, cname)
+ return
+}
+func (b Builder) CreateCall(fn Value, args []Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ ptr, nvals := llvmValueRefs(args)
+ v.C = C.LLVMBuildCall(b.C, fn.C, ptr, nvals, cname)
+ return
+}
+
+func (b Builder) CreateSelect(ifv, thenv, elsev Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildSelect(b.C, ifv.C, thenv.C, elsev.C, cname)
+ return
+}
+
+func (b Builder) CreateVAArg(list Value, t Type, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildVAArg(b.C, list.C, t.C, cname)
+ return
+}
+func (b Builder) CreateExtractElement(vec, i Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildExtractElement(b.C, vec.C, i.C, cname)
+ return
+}
+func (b Builder) CreateInsertElement(vec, elt, i Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildInsertElement(b.C, vec.C, elt.C, i.C, cname)
+ return
+}
+func (b Builder) CreateShuffleVector(v1, v2, mask Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildShuffleVector(b.C, v1.C, v2.C, mask.C, cname)
+ return
+}
+func (b Builder) CreateExtractValue(agg Value, i int, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildExtractValue(b.C, agg.C, C.unsigned(i), cname)
+ return
+}
+func (b Builder) CreateInsertValue(agg, elt Value, i int, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildInsertValue(b.C, agg.C, elt.C, C.unsigned(i), cname)
+ return
+}
+
+func (b Builder) CreateIsNull(val Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildIsNull(b.C, val.C, cname)
+ return
+}
+func (b Builder) CreateIsNotNull(val Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildIsNotNull(b.C, val.C, cname)
+ return
+}
+func (b Builder) CreatePtrDiff(lhs, rhs Value, name string) (v Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ v.C = C.LLVMBuildPtrDiff(b.C, lhs.C, rhs.C, cname)
+ return
+}
+
+func (b Builder) CreateLandingPad(t Type, personality Value, nclauses int, name string) (l Value) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ l.C = C.LLVMBuildLandingPad(b.C, t.C, personality.C, C.unsigned(nclauses), cname)
+ return l
+}
+
+func (l Value) AddClause(v Value) {
+ C.LLVMAddClause(l.C, v.C)
+}
+
+func (l Value) SetCleanup(cleanup bool) {
+ C.LLVMSetCleanup(l.C, boolToLLVMBool(cleanup))
+}
+
+func (b Builder) CreateResume(ex Value) (v Value) {
+ v.C = C.LLVMBuildResume(b.C, ex.C)
+ return
+}
+
+//-------------------------------------------------------------------------
+// llvm.ModuleProvider
+//-------------------------------------------------------------------------
+
+// Changes the type of M so it can be passed to FunctionPassManagers and the
+// JIT. They take ModuleProviders for historical reasons.
+func NewModuleProviderForModule(m Module) (mp ModuleProvider) {
+ mp.C = C.LLVMCreateModuleProviderForExistingModule(m.C)
+ return
+}
+
+// Destroys the module M.
+func (mp ModuleProvider) Dispose() { C.LLVMDisposeModuleProvider(mp.C) }
+
+//-------------------------------------------------------------------------
+// llvm.MemoryBuffer
+//-------------------------------------------------------------------------
+
+func NewMemoryBufferFromFile(path string) (b MemoryBuffer, err error) {
+ var cmsg *C.char
+ cpath := C.CString(path)
+ defer C.free(unsafe.Pointer(cpath))
+ fail := C.LLVMCreateMemoryBufferWithContentsOfFile(cpath, &b.C, &cmsg)
+ if fail != 0 {
+ b.C = nil
+ err = errors.New(C.GoString(cmsg))
+ C.LLVMDisposeMessage(cmsg)
+ }
+ return
+}
+
+func NewMemoryBufferFromStdin() (b MemoryBuffer, err error) {
+ var cmsg *C.char
+ fail := C.LLVMCreateMemoryBufferWithSTDIN(&b.C, &cmsg)
+ if fail != 0 {
+ b.C = nil
+ err = errors.New(C.GoString(cmsg))
+ C.LLVMDisposeMessage(cmsg)
+ }
+ return
+}
+
+func (b MemoryBuffer) Bytes() []byte {
+ cstart := C.LLVMGetBufferStart(b.C)
+ csize := C.LLVMGetBufferSize(b.C)
+ return C.GoBytes(unsafe.Pointer(cstart), C.int(csize))
+}
+
+func (b MemoryBuffer) Dispose() { C.LLVMDisposeMemoryBuffer(b.C) }
+
+//-------------------------------------------------------------------------
+// llvm.PassManager
+//-------------------------------------------------------------------------
+
+// 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.
+func NewPassManager() (pm PassManager) { pm.C = C.LLVMCreatePassManager(); return }
+
+// 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.
+func NewFunctionPassManagerForModule(m Module) (pm PassManager) {
+ pm.C = C.LLVMCreateFunctionPassManagerForModule(m.C)
+ return
+}
+
+// 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&).
+func (pm PassManager) Run(m Module) bool { return C.LLVMRunPassManager(pm.C, m.C) != 0 }
+
+// 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.
+func (pm PassManager) InitializeFunc() bool { return C.LLVMInitializeFunctionPassManager(pm.C) != 0 }
+
+// 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&).
+func (pm PassManager) RunFunc(f Value) bool { return C.LLVMRunFunctionPassManager(pm.C, f.C) != 0 }
+
+// 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.
+func (pm PassManager) FinalizeFunc() bool { return C.LLVMFinalizeFunctionPassManager(pm.C) != 0 }
+
+// Frees the memory of a pass pipeline. For function pipelines, does not free
+// the module provider.
+// See llvm::PassManagerBase::~PassManagerBase.
+func (pm PassManager) Dispose() { C.LLVMDisposePassManager(pm.C) }
diff --git a/bindings/go/llvm/ir_test.go b/bindings/go/llvm/ir_test.go
new file mode 100644
index 0000000..981c94a
--- /dev/null
+++ b/bindings/go/llvm/ir_test.go
@@ -0,0 +1,95 @@
+//===- ir_test.go - Tests for ir ------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests bindings for the ir component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+import (
+ "strings"
+ "testing"
+)
+
+func testAttribute(t *testing.T, attr Attribute, name string) {
+ mod := NewModule("")
+ defer mod.Dispose()
+
+ ftyp := FunctionType(VoidType(), nil, false)
+ fn := AddFunction(mod, "foo", ftyp)
+
+ fn.AddFunctionAttr(attr)
+ newattr := fn.FunctionAttr()
+ if attr != newattr {
+ t.Errorf("got attribute mask %d, want %d", newattr, attr)
+ }
+
+ text := mod.String()
+ if !strings.Contains(text, " "+name+" ") {
+ t.Errorf("expected attribute '%s', got:\n%s", name, text)
+ }
+
+ fn.RemoveFunctionAttr(attr)
+ newattr = fn.FunctionAttr()
+ if newattr != 0 {
+ t.Errorf("got attribute mask %d, want 0", newattr)
+ }
+}
+
+func TestAttributes(t *testing.T) {
+ // Tests that our attribute constants haven't drifted from LLVM's.
+ attrTests := []struct {
+ attr Attribute
+ name string
+ }{
+ {SanitizeAddressAttribute, "sanitize_address"},
+ {AlwaysInlineAttribute, "alwaysinline"},
+ {BuiltinAttribute, "builtin"},
+ {ByValAttribute, "byval"},
+ {InAllocaAttribute, "inalloca"},
+ {InlineHintAttribute, "inlinehint"},
+ {InRegAttribute, "inreg"},
+ {JumpTableAttribute, "jumptable"},
+ {MinSizeAttribute, "minsize"},
+ {NakedAttribute, "naked"},
+ {NestAttribute, "nest"},
+ {NoAliasAttribute, "noalias"},
+ {NoBuiltinAttribute, "nobuiltin"},
+ {NoCaptureAttribute, "nocapture"},
+ {NoDuplicateAttribute, "noduplicate"},
+ {NoImplicitFloatAttribute, "noimplicitfloat"},
+ {NoInlineAttribute, "noinline"},
+ {NonLazyBindAttribute, "nonlazybind"},
+ {NonNullAttribute, "nonnull"},
+ {NoRedZoneAttribute, "noredzone"},
+ {NoReturnAttribute, "noreturn"},
+ {NoUnwindAttribute, "nounwind"},
+ {OptimizeNoneAttribute, "optnone"},
+ {OptimizeForSizeAttribute, "optsize"},
+ {ReadNoneAttribute, "readnone"},
+ {ReadOnlyAttribute, "readonly"},
+ {ReturnedAttribute, "returned"},
+ {ReturnsTwiceAttribute, "returns_twice"},
+ {SExtAttribute, "signext"},
+ {StackProtectAttribute, "ssp"},
+ {StackProtectReqAttribute, "sspreq"},
+ {StackProtectStrongAttribute, "sspstrong"},
+ {StructRetAttribute, "sret"},
+ {SanitizeThreadAttribute, "sanitize_thread"},
+ {SanitizeMemoryAttribute, "sanitize_memory"},
+ {UWTableAttribute, "uwtable"},
+ {ZExtAttribute, "zeroext"},
+ {ColdAttribute, "cold"},
+ }
+
+ for _, a := range attrTests {
+ testAttribute(t, a.attr, a.name)
+ }
+}
diff --git a/bindings/go/llvm/linker.go b/bindings/go/llvm/linker.go
new file mode 100644
index 0000000..31e9ad2
--- /dev/null
+++ b/bindings/go/llvm/linker.go
@@ -0,0 +1,39 @@
+//===- linker.go - Bindings for linker ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the linker component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Linker.h"
+#include <stdlib.h>
+*/
+import "C"
+import "errors"
+
+type LinkerMode C.LLVMLinkerMode
+
+const (
+ LinkerDestroySource = C.LLVMLinkerDestroySource
+ LinkerPreserveSource = C.LLVMLinkerPreserveSource
+)
+
+func LinkModules(Dest, Src Module, Mode LinkerMode) error {
+ var cmsg *C.char
+ failed := C.LLVMLinkModules(Dest.C, Src.C, C.LLVMLinkerMode(Mode), &cmsg)
+ if failed != 0 {
+ err := errors.New(C.GoString(cmsg))
+ C.LLVMDisposeMessage(cmsg)
+ return err
+ }
+ return nil
+}
diff --git a/bindings/go/llvm/llvm_config.go.in b/bindings/go/llvm/llvm_config.go.in
new file mode 100644
index 0000000..41854fa
--- /dev/null
+++ b/bindings/go/llvm/llvm_config.go.in
@@ -0,0 +1,12 @@
+// +build !byollvm
+
+package llvm
+
+/*
+#cgo CXXFLAGS: -std=c++11
+#cgo CPPFLAGS: @LLVM_CFLAGS@
+#cgo LDFLAGS: @LLVM_LDFLAGS@
+*/
+import "C"
+
+type (run_build_sh int)
diff --git a/bindings/go/llvm/llvm_dep.go b/bindings/go/llvm/llvm_dep.go
new file mode 100644
index 0000000..39b4675
--- /dev/null
+++ b/bindings/go/llvm/llvm_dep.go
@@ -0,0 +1,19 @@
+//===- llvm_dep.go - creates LLVM dependency ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file ensures that the LLVM libraries are built before using the
+// bindings.
+//
+//===----------------------------------------------------------------------===//
+
+// +build !byollvm
+
+package llvm
+
+var _ run_build_sh
diff --git a/bindings/go/llvm/string.go b/bindings/go/llvm/string.go
new file mode 100644
index 0000000..bfe869d
--- /dev/null
+++ b/bindings/go/llvm/string.go
@@ -0,0 +1,105 @@
+//===- string.go - Stringer implementation for Type -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Stringer interface for the Type type.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+import "fmt"
+
+func (t TypeKind) String() string {
+ switch t {
+ case VoidTypeKind:
+ return "VoidTypeKind"
+ case FloatTypeKind:
+ return "FloatTypeKind"
+ case DoubleTypeKind:
+ return "DoubleTypeKind"
+ case X86_FP80TypeKind:
+ return "X86_FP80TypeKind"
+ case FP128TypeKind:
+ return "FP128TypeKind"
+ case PPC_FP128TypeKind:
+ return "PPC_FP128TypeKind"
+ case LabelTypeKind:
+ return "LabelTypeKind"
+ case IntegerTypeKind:
+ return "IntegerTypeKind"
+ case FunctionTypeKind:
+ return "FunctionTypeKind"
+ case StructTypeKind:
+ return "StructTypeKind"
+ case ArrayTypeKind:
+ return "ArrayTypeKind"
+ case PointerTypeKind:
+ return "PointerTypeKind"
+ case VectorTypeKind:
+ return "VectorTypeKind"
+ case MetadataTypeKind:
+ return "MetadataTypeKind"
+ }
+ panic("unreachable")
+}
+
+func (t Type) String() string {
+ ts := typeStringer{s: make(map[Type]string)}
+ return ts.typeString(t)
+}
+
+type typeStringer struct {
+ s map[Type]string
+}
+
+func (ts *typeStringer) typeString(t Type) string {
+ if s, ok := ts.s[t]; ok {
+ return s
+ }
+
+ k := t.TypeKind()
+ s := k.String()
+ s = s[:len(s)-len("Kind")]
+
+ switch k {
+ case ArrayTypeKind:
+ s += fmt.Sprintf("(%v[%v])", ts.typeString(t.ElementType()), t.ArrayLength())
+ case PointerTypeKind:
+ s += fmt.Sprintf("(%v)", ts.typeString(t.ElementType()))
+ case FunctionTypeKind:
+ params := t.ParamTypes()
+ s += "("
+ if len(params) > 0 {
+ s += fmt.Sprintf("%v", ts.typeString(params[0]))
+ for i := 1; i < len(params); i++ {
+ s += fmt.Sprintf(", %v", ts.typeString(params[i]))
+ }
+ }
+ s += fmt.Sprintf("):%v", ts.typeString(t.ReturnType()))
+ case StructTypeKind:
+ if name := t.StructName(); name != "" {
+ ts.s[t] = "%" + name
+ s = fmt.Sprintf("%%%s: %s", name, s)
+ }
+ etypes := t.StructElementTypes()
+ s += "("
+ if n := len(etypes); n > 0 {
+ s += ts.typeString(etypes[0])
+ for i := 1; i < n; i++ {
+ s += fmt.Sprintf(", %v", ts.typeString(etypes[i]))
+ }
+ }
+ s += ")"
+ case IntegerTypeKind:
+ s += fmt.Sprintf("(%d bits)", t.IntTypeWidth())
+ }
+
+ ts.s[t] = s
+ return s
+}
diff --git a/bindings/go/llvm/string_test.go b/bindings/go/llvm/string_test.go
new file mode 100644
index 0000000..3008f3e
--- /dev/null
+++ b/bindings/go/llvm/string_test.go
@@ -0,0 +1,28 @@
+//===- string_test.go - test Stringer implementation for Type -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests the Stringer interface for the Type type.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+import (
+ "testing"
+)
+
+func TestStringRecursiveType(t *testing.T) {
+ ctx := NewContext()
+ defer ctx.Dispose()
+ s := ctx.StructCreateNamed("recursive")
+ s.StructSetBody([]Type{s, s}, false)
+ if str := s.String(); str != "%recursive: StructType(%recursive, %recursive)" {
+ t.Errorf("incorrect string result %q", str)
+ }
+}
diff --git a/bindings/go/llvm/support.go b/bindings/go/llvm/support.go
new file mode 100644
index 0000000..6f20086
--- /dev/null
+++ b/bindings/go/llvm/support.go
@@ -0,0 +1,54 @@
+//===- support.go - Bindings for support ----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the support component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Support.h"
+#include "SupportBindings.h"
+#include <stdlib.h>
+*/
+import "C"
+
+import (
+ "errors"
+ "unsafe"
+)
+
+// Loads a dynamic library such that it may be used as an LLVM plugin.
+// See llvm::sys::DynamicLibrary::LoadLibraryPermanently.
+func LoadLibraryPermanently(lib string) error {
+ var errstr *C.char
+ libstr := C.CString(lib)
+ defer C.free(unsafe.Pointer(libstr))
+ C.LLVMLoadLibraryPermanently2(libstr, &errstr)
+ if errstr != nil {
+ err := errors.New(C.GoString(errstr))
+ C.free(unsafe.Pointer(errstr))
+ return err
+ }
+ return nil
+}
+
+// Parse the given arguments using the LLVM command line parser.
+// See llvm::cl::ParseCommandLineOptions.
+func ParseCommandLineOptions(args []string, overview string) {
+ argstrs := make([]*C.char, len(args))
+ for i, arg := range args {
+ argstrs[i] = C.CString(arg)
+ defer C.free(unsafe.Pointer(argstrs[i]))
+ }
+ overviewstr := C.CString(overview)
+ defer C.free(unsafe.Pointer(overviewstr))
+ C.LLVMParseCommandLineOptions(C.int(len(args)), &argstrs[0], overviewstr)
+}
diff --git a/bindings/go/llvm/target.go b/bindings/go/llvm/target.go
new file mode 100644
index 0000000..bd1d0f3
--- /dev/null
+++ b/bindings/go/llvm/target.go
@@ -0,0 +1,300 @@
+//===- target.go - Bindings for target ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the target component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Target.h"
+#include "llvm-c/TargetMachine.h"
+#include <stdlib.h>
+*/
+import "C"
+import "unsafe"
+import "errors"
+
+type (
+ TargetData struct {
+ C C.LLVMTargetDataRef
+ }
+ Target struct {
+ C C.LLVMTargetRef
+ }
+ TargetMachine struct {
+ C C.LLVMTargetMachineRef
+ }
+ ByteOrdering C.enum_LLVMByteOrdering
+ RelocMode C.LLVMRelocMode
+ CodeGenOptLevel C.LLVMCodeGenOptLevel
+ CodeGenFileType C.LLVMCodeGenFileType
+ CodeModel C.LLVMCodeModel
+)
+
+const (
+ BigEndian ByteOrdering = C.LLVMBigEndian
+ LittleEndian ByteOrdering = C.LLVMLittleEndian
+)
+
+const (
+ RelocDefault RelocMode = C.LLVMRelocDefault
+ RelocStatic RelocMode = C.LLVMRelocStatic
+ RelocPIC RelocMode = C.LLVMRelocPIC
+ RelocDynamicNoPic RelocMode = C.LLVMRelocDynamicNoPic
+)
+
+const (
+ CodeGenLevelNone CodeGenOptLevel = C.LLVMCodeGenLevelNone
+ CodeGenLevelLess CodeGenOptLevel = C.LLVMCodeGenLevelLess
+ CodeGenLevelDefault CodeGenOptLevel = C.LLVMCodeGenLevelDefault
+ CodeGenLevelAggressive CodeGenOptLevel = C.LLVMCodeGenLevelAggressive
+)
+
+const (
+ CodeModelDefault CodeModel = C.LLVMCodeModelDefault
+ CodeModelJITDefault CodeModel = C.LLVMCodeModelJITDefault
+ CodeModelSmall CodeModel = C.LLVMCodeModelSmall
+ CodeModelKernel CodeModel = C.LLVMCodeModelKernel
+ CodeModelMedium CodeModel = C.LLVMCodeModelMedium
+ CodeModelLarge CodeModel = C.LLVMCodeModelLarge
+)
+
+const (
+ AssemblyFile CodeGenFileType = C.LLVMAssemblyFile
+ ObjectFile CodeGenFileType = C.LLVMObjectFile
+)
+
+// InitializeAllTargetInfos - The main program should call this function if it
+// wants access to all available targets that LLVM is configured to support.
+func InitializeAllTargetInfos() { C.LLVMInitializeAllTargetInfos() }
+
+// InitializeAllTargets - The main program should call this function if it wants
+// to link in all available targets that LLVM is configured to support.
+func InitializeAllTargets() { C.LLVMInitializeAllTargets() }
+
+func InitializeAllTargetMCs() { C.LLVMInitializeAllTargetMCs() }
+
+func InitializeAllAsmParsers() { C.LLVMInitializeAllAsmParsers() }
+
+func InitializeAllAsmPrinters() { C.LLVMInitializeAllAsmPrinters() }
+
+var initializeNativeTargetError = errors.New("Failed to initialize native target")
+
+// InitializeNativeTarget - The main program should call this function to
+// initialize the native target corresponding to the host. This is useful
+// for JIT applications to ensure that the target gets linked in correctly.
+func InitializeNativeTarget() error {
+ fail := C.LLVMInitializeNativeTarget()
+ if fail != 0 {
+ return initializeNativeTargetError
+ }
+ return nil
+}
+
+func InitializeNativeAsmPrinter() error {
+ fail := C.LLVMInitializeNativeAsmPrinter()
+ if fail != 0 {
+ return initializeNativeTargetError
+ }
+ return nil
+}
+
+//-------------------------------------------------------------------------
+// llvm.TargetData
+//-------------------------------------------------------------------------
+
+// Creates target data from a target layout string.
+// See the constructor llvm::TargetData::TargetData.
+func NewTargetData(rep string) (td TargetData) {
+ crep := C.CString(rep)
+ defer C.free(unsafe.Pointer(crep))
+ td.C = C.LLVMCreateTargetData(crep)
+ return
+}
+
+// Adds target data information to a pass manager. This does not take ownership
+// of the target data.
+// See the method llvm::PassManagerBase::add.
+func (pm PassManager) Add(td TargetData) {
+ C.LLVMAddTargetData(td.C, pm.C)
+}
+
+// Converts target data to a target layout string. The string must be disposed
+// with LLVMDisposeMessage.
+// See the constructor llvm::TargetData::TargetData.
+func (td TargetData) String() (s string) {
+ cmsg := C.LLVMCopyStringRepOfTargetData(td.C)
+ s = C.GoString(cmsg)
+ C.LLVMDisposeMessage(cmsg)
+ return
+}
+
+// Returns the byte order of a target, either BigEndian or LittleEndian.
+// See the method llvm::TargetData::isLittleEndian.
+func (td TargetData) ByteOrder() ByteOrdering { return ByteOrdering(C.LLVMByteOrder(td.C)) }
+
+// Returns the pointer size in bytes for a target.
+// See the method llvm::TargetData::getPointerSize.
+func (td TargetData) PointerSize() int { return int(C.LLVMPointerSize(td.C)) }
+
+// Returns the integer type that is the same size as a pointer on a target.
+// See the method llvm::TargetData::getIntPtrType.
+func (td TargetData) IntPtrType() (t Type) { t.C = C.LLVMIntPtrType(td.C); return }
+
+// Computes the size of a type in bytes for a target.
+// See the method llvm::TargetData::getTypeSizeInBits.
+func (td TargetData) TypeSizeInBits(t Type) uint64 {
+ return uint64(C.LLVMSizeOfTypeInBits(td.C, t.C))
+}
+
+// Computes the storage size of a type in bytes for a target.
+// See the method llvm::TargetData::getTypeStoreSize.
+func (td TargetData) TypeStoreSize(t Type) uint64 {
+ return uint64(C.LLVMStoreSizeOfType(td.C, t.C))
+}
+
+// Computes the ABI size of a type in bytes for a target.
+// See the method llvm::TargetData::getTypeAllocSize.
+func (td TargetData) TypeAllocSize(t Type) uint64 {
+ return uint64(C.LLVMABISizeOfType(td.C, t.C))
+}
+
+// Computes the ABI alignment of a type in bytes for a target.
+// See the method llvm::TargetData::getABITypeAlignment.
+func (td TargetData) ABITypeAlignment(t Type) int {
+ return int(C.LLVMABIAlignmentOfType(td.C, t.C))
+}
+
+// Computes the call frame alignment of a type in bytes for a target.
+// See the method llvm::TargetData::getCallFrameTypeAlignment.
+func (td TargetData) CallFrameTypeAlignment(t Type) int {
+ return int(C.LLVMCallFrameAlignmentOfType(td.C, t.C))
+}
+
+// Computes the preferred alignment of a type in bytes for a target.
+// See the method llvm::TargetData::getPrefTypeAlignment.
+func (td TargetData) PrefTypeAlignment(t Type) int {
+ return int(C.LLVMPreferredAlignmentOfType(td.C, t.C))
+}
+
+// Computes the preferred alignment of a global variable in bytes for a target.
+// See the method llvm::TargetData::getPreferredAlignment.
+func (td TargetData) PreferredAlignment(g Value) int {
+ return int(C.LLVMPreferredAlignmentOfGlobal(td.C, g.C))
+}
+
+// Computes the structure element that contains the byte offset for a target.
+// See the method llvm::StructLayout::getElementContainingOffset.
+func (td TargetData) ElementContainingOffset(t Type, offset uint64) int {
+ return int(C.LLVMElementAtOffset(td.C, t.C, C.ulonglong(offset)))
+}
+
+// Computes the byte offset of the indexed struct element for a target.
+// See the method llvm::StructLayout::getElementOffset.
+func (td TargetData) ElementOffset(t Type, element int) uint64 {
+ return uint64(C.LLVMOffsetOfElement(td.C, t.C, C.unsigned(element)))
+}
+
+// Deallocates a TargetData.
+// See the destructor llvm::TargetData::~TargetData.
+func (td TargetData) Dispose() { C.LLVMDisposeTargetData(td.C) }
+
+//-------------------------------------------------------------------------
+// llvm.Target
+//-------------------------------------------------------------------------
+
+func FirstTarget() Target {
+ return Target{C.LLVMGetFirstTarget()}
+}
+
+func (t Target) NextTarget() Target {
+ return Target{C.LLVMGetNextTarget(t.C)}
+}
+
+func GetTargetFromTriple(triple string) (t Target, err error) {
+ var errstr *C.char
+ ctriple := C.CString(triple)
+ defer C.free(unsafe.Pointer(ctriple))
+ fail := C.LLVMGetTargetFromTriple(ctriple, &t.C, &errstr)
+ if fail != 0 {
+ err = errors.New(C.GoString(errstr))
+ C.free(unsafe.Pointer(errstr))
+ }
+ return
+}
+
+func (t Target) Name() string {
+ return C.GoString(C.LLVMGetTargetName(t.C))
+}
+
+func (t Target) Description() string {
+ return C.GoString(C.LLVMGetTargetDescription(t.C))
+}
+
+//-------------------------------------------------------------------------
+// llvm.TargetMachine
+//-------------------------------------------------------------------------
+
+// CreateTargetMachine creates a new TargetMachine.
+func (t Target) CreateTargetMachine(Triple string, CPU string, Features string,
+ Level CodeGenOptLevel, Reloc RelocMode,
+ CodeModel CodeModel) (tm TargetMachine) {
+ cTriple := C.CString(Triple)
+ defer C.free(unsafe.Pointer(cTriple))
+ cCPU := C.CString(CPU)
+ defer C.free(unsafe.Pointer(cCPU))
+ cFeatures := C.CString(Features)
+ defer C.free(unsafe.Pointer(cFeatures))
+ tm.C = C.LLVMCreateTargetMachine(t.C, cTriple, cCPU, cFeatures,
+ C.LLVMCodeGenOptLevel(Level),
+ C.LLVMRelocMode(Reloc),
+ C.LLVMCodeModel(CodeModel))
+ return
+}
+
+// Triple returns the triple describing the machine (arch-vendor-os).
+func (tm TargetMachine) Triple() string {
+ cstr := C.LLVMGetTargetMachineTriple(tm.C)
+ return C.GoString(cstr)
+}
+
+// TargetData returns the TargetData for the machine.
+func (tm TargetMachine) TargetData() TargetData {
+ return TargetData{C.LLVMGetTargetMachineData(tm.C)}
+}
+
+func (tm TargetMachine) EmitToMemoryBuffer(m Module, ft CodeGenFileType) (MemoryBuffer, error) {
+ var errstr *C.char
+ var mb MemoryBuffer
+ fail := C.LLVMTargetMachineEmitToMemoryBuffer(tm.C, m.C, C.LLVMCodeGenFileType(ft), &errstr, &mb.C)
+ if fail != 0 {
+ err := errors.New(C.GoString(errstr))
+ C.free(unsafe.Pointer(errstr))
+ return MemoryBuffer{}, err
+ }
+ return mb, nil
+}
+
+func (tm TargetMachine) AddAnalysisPasses(pm PassManager) {
+ C.LLVMAddAnalysisPasses(tm.C, pm.C)
+}
+
+// Dispose releases resources related to the TargetMachine.
+func (tm TargetMachine) Dispose() {
+ C.LLVMDisposeTargetMachine(tm.C)
+}
+
+func DefaultTargetTriple() (triple string) {
+ cTriple := C.LLVMGetDefaultTargetTriple()
+ defer C.free(unsafe.Pointer(cTriple))
+ triple = C.GoString(cTriple)
+ return
+}
diff --git a/bindings/go/llvm/transforms_instrumentation.go b/bindings/go/llvm/transforms_instrumentation.go
new file mode 100644
index 0000000..9b191b2
--- /dev/null
+++ b/bindings/go/llvm/transforms_instrumentation.go
@@ -0,0 +1,43 @@
+//===- transforms_instrumentation.go - Bindings for instrumentation -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the instrumentation component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "InstrumentationBindings.h"
+#include <stdlib.h>
+*/
+import "C"
+import "unsafe"
+
+func (pm PassManager) AddAddressSanitizerFunctionPass() {
+ C.LLVMAddAddressSanitizerFunctionPass(pm.C)
+}
+
+func (pm PassManager) AddAddressSanitizerModulePass() {
+ C.LLVMAddAddressSanitizerModulePass(pm.C)
+}
+
+func (pm PassManager) AddThreadSanitizerPass() {
+ C.LLVMAddThreadSanitizerPass(pm.C)
+}
+
+func (pm PassManager) AddMemorySanitizerPass() {
+ C.LLVMAddMemorySanitizerPass(pm.C)
+}
+
+func (pm PassManager) AddDataFlowSanitizerPass(abilist string) {
+ cabilist := C.CString(abilist)
+ defer C.free(unsafe.Pointer(cabilist))
+ C.LLVMAddDataFlowSanitizerPass(pm.C, cabilist)
+}
diff --git a/bindings/go/llvm/transforms_ipo.go b/bindings/go/llvm/transforms_ipo.go
new file mode 100644
index 0000000..12d972b
--- /dev/null
+++ b/bindings/go/llvm/transforms_ipo.go
@@ -0,0 +1,42 @@
+//===- transforms_ipo.go - Bindings for ipo -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the ipo component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Transforms/IPO.h"
+*/
+import "C"
+
+// helpers
+func boolToUnsigned(b bool) C.unsigned {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+func (pm PassManager) AddArgumentPromotionPass() { C.LLVMAddArgumentPromotionPass(pm.C) }
+func (pm PassManager) AddConstantMergePass() { C.LLVMAddConstantMergePass(pm.C) }
+func (pm PassManager) AddDeadArgEliminationPass() { C.LLVMAddDeadArgEliminationPass(pm.C) }
+func (pm PassManager) AddFunctionAttrsPass() { C.LLVMAddFunctionAttrsPass(pm.C) }
+func (pm PassManager) AddFunctionInliningPass() { C.LLVMAddFunctionInliningPass(pm.C) }
+func (pm PassManager) AddGlobalDCEPass() { C.LLVMAddGlobalDCEPass(pm.C) }
+func (pm PassManager) AddGlobalOptimizerPass() { C.LLVMAddGlobalOptimizerPass(pm.C) }
+func (pm PassManager) AddIPConstantPropagationPass() { C.LLVMAddIPConstantPropagationPass(pm.C) }
+func (pm PassManager) AddPruneEHPass() { C.LLVMAddPruneEHPass(pm.C) }
+func (pm PassManager) AddIPSCCPPass() { C.LLVMAddIPSCCPPass(pm.C) }
+func (pm PassManager) AddInternalizePass(allButMain bool) {
+ C.LLVMAddInternalizePass(pm.C, boolToUnsigned(allButMain))
+}
+func (pm PassManager) AddStripDeadPrototypesPass() { C.LLVMAddStripDeadPrototypesPass(pm.C) }
diff --git a/bindings/go/llvm/transforms_pmbuilder.go b/bindings/go/llvm/transforms_pmbuilder.go
new file mode 100644
index 0000000..3d79d6e
--- /dev/null
+++ b/bindings/go/llvm/transforms_pmbuilder.go
@@ -0,0 +1,48 @@
+//===- transforms_pmbuilder.go - Bindings for PassManagerBuilder ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the PassManagerBuilder class.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Transforms/PassManagerBuilder.h"
+*/
+import "C"
+
+type PassManagerBuilder struct {
+ C C.LLVMPassManagerBuilderRef
+}
+
+func NewPassManagerBuilder() (pmb PassManagerBuilder) {
+ pmb.C = C.LLVMPassManagerBuilderCreate()
+ return
+}
+
+func (pmb PassManagerBuilder) SetOptLevel(level int) {
+ C.LLVMPassManagerBuilderSetOptLevel(pmb.C, C.uint(level))
+}
+
+func (pmb PassManagerBuilder) SetSizeLevel(level int) {
+ C.LLVMPassManagerBuilderSetSizeLevel(pmb.C, C.uint(level))
+}
+
+func (pmb PassManagerBuilder) Populate(pm PassManager) {
+ C.LLVMPassManagerBuilderPopulateModulePassManager(pmb.C, pm.C)
+}
+
+func (pmb PassManagerBuilder) PopulateFunc(pm PassManager) {
+ C.LLVMPassManagerBuilderPopulateFunctionPassManager(pmb.C, pm.C)
+}
+
+func (pmb PassManagerBuilder) Dispose() {
+ C.LLVMPassManagerBuilderDispose(pmb.C)
+}
diff --git a/bindings/go/llvm/transforms_scalar.go b/bindings/go/llvm/transforms_scalar.go
new file mode 100644
index 0000000..6492a85
--- /dev/null
+++ b/bindings/go/llvm/transforms_scalar.go
@@ -0,0 +1,45 @@
+//===- transforms_scalar.go - Bindings for scalaropts ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the scalaropts component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Transforms/Scalar.h"
+*/
+import "C"
+
+func (pm PassManager) AddAggressiveDCEPass() { C.LLVMAddAggressiveDCEPass(pm.C) }
+func (pm PassManager) AddCFGSimplificationPass() { C.LLVMAddCFGSimplificationPass(pm.C) }
+func (pm PassManager) AddDeadStoreEliminationPass() { C.LLVMAddDeadStoreEliminationPass(pm.C) }
+func (pm PassManager) AddGVNPass() { C.LLVMAddGVNPass(pm.C) }
+func (pm PassManager) AddIndVarSimplifyPass() { C.LLVMAddIndVarSimplifyPass(pm.C) }
+func (pm PassManager) AddInstructionCombiningPass() { C.LLVMAddInstructionCombiningPass(pm.C) }
+func (pm PassManager) AddJumpThreadingPass() { C.LLVMAddJumpThreadingPass(pm.C) }
+func (pm PassManager) AddLICMPass() { C.LLVMAddLICMPass(pm.C) }
+func (pm PassManager) AddLoopDeletionPass() { C.LLVMAddLoopDeletionPass(pm.C) }
+func (pm PassManager) AddLoopRotatePass() { C.LLVMAddLoopRotatePass(pm.C) }
+func (pm PassManager) AddLoopUnrollPass() { C.LLVMAddLoopUnrollPass(pm.C) }
+func (pm PassManager) AddLoopUnswitchPass() { C.LLVMAddLoopUnswitchPass(pm.C) }
+func (pm PassManager) AddMemCpyOptPass() { C.LLVMAddMemCpyOptPass(pm.C) }
+func (pm PassManager) AddPromoteMemoryToRegisterPass() { C.LLVMAddPromoteMemoryToRegisterPass(pm.C) }
+func (pm PassManager) AddReassociatePass() { C.LLVMAddReassociatePass(pm.C) }
+func (pm PassManager) AddSCCPPass() { C.LLVMAddSCCPPass(pm.C) }
+func (pm PassManager) AddScalarReplAggregatesPass() { C.LLVMAddScalarReplAggregatesPass(pm.C) }
+func (pm PassManager) AddScalarReplAggregatesPassWithThreshold(threshold int) {
+ C.LLVMAddScalarReplAggregatesPassWithThreshold(pm.C, C.int(threshold))
+}
+func (pm PassManager) AddSimplifyLibCallsPass() { C.LLVMAddSimplifyLibCallsPass(pm.C) }
+func (pm PassManager) AddTailCallEliminationPass() { C.LLVMAddTailCallEliminationPass(pm.C) }
+func (pm PassManager) AddConstantPropagationPass() { C.LLVMAddConstantPropagationPass(pm.C) }
+func (pm PassManager) AddDemoteMemoryToRegisterPass() { C.LLVMAddDemoteMemoryToRegisterPass(pm.C) }
+func (pm PassManager) AddVerifierPass() { C.LLVMAddVerifierPass(pm.C) }
diff --git a/bindings/go/llvm/version.go b/bindings/go/llvm/version.go
new file mode 100644
index 0000000..d0623be
--- /dev/null
+++ b/bindings/go/llvm/version.go
@@ -0,0 +1,21 @@
+//===- version.go - LLVM version info -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines LLVM version information.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm/Config/llvm-config.h"
+*/
+import "C"
+
+const Version = C.LLVM_VERSION_STRING
diff --git a/bindings/ocaml/Makefile b/bindings/ocaml/Makefile
index b0e1f09..2005367 100644
--- a/bindings/ocaml/Makefile
+++ b/bindings/ocaml/Makefile
@@ -1,10 +1,10 @@
##===- bindings/ocaml/Makefile -----------------------------*- Makefile -*-===##
-#
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
-#
+#
##===----------------------------------------------------------------------===##
LEVEL := ../..
diff --git a/bindings/ocaml/Makefile.ocaml b/bindings/ocaml/Makefile.ocaml
index 1b964ee..5e00cf5 100644
--- a/bindings/ocaml/Makefile.ocaml
+++ b/bindings/ocaml/Makefile.ocaml
@@ -1,27 +1,30 @@
##===- bindings/ocaml/Makefile.ocaml -----------------------*- Makefile -*-===##
-#
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
-#
+#
##===----------------------------------------------------------------------===##
-#
+#
# An OCaml library is a unique project type in the context of LLVM, so rules are
# here rather than in Makefile.rules.
-#
+#
# Reference materials on installing OCaml libraries:
-#
+#
# https://fedoraproject.org/wiki/Packaging/OCaml
# http://pkg-ocaml-maint.alioth.debian.org/ocaml_packaging_policy.txt
-#
+#
##===----------------------------------------------------------------------===##
include $(LEVEL)/Makefile.config
+# We have our own rules for building static libraries.
+NO_BUILD_ARCHIVE = 1
+
# CFLAGS needs to be set before Makefile.rules is included.
-CXX.Flags += -I"$(shell $(OCAMLC) -where)"
-C.Flags += -I"$(shell $(OCAMLC) -where)"
+CXX.Flags += -I"$(shell $(OCAMLFIND) c -where)"
+C.Flags += -I"$(shell $(OCAMLFIND) c -where)"
ifeq ($(ENABLE_SHARED),1)
LINK_COMPONENTS := all
@@ -50,64 +53,55 @@ endif
# from toplevels.
ifneq ($(ObjectsO),)
ifeq ($(ENABLE_SHARED),1)
-OCAMLSTUBS := 1
+OCAMLSTUBS := 1
+OCAMLSTUBFLAGS := $(patsubst %,-cclib %, $(LLVMLibsOptions) -l$(LIBRARYNAME))
+endif
+endif
+
+# Avoid the need for LD_LIBRARY_PATH
+ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
+ifneq ($(HOST_OS),Darwin)
+OCAMLRPATH := $(RPATH) -Wl,'$$ORIGIN/../../lib'
endif
endif
# Tools
-OCAMLCFLAGS += -I $(ObjDir) -I $(OcamlDir)
+OCAMLCFLAGS += -I $(OcamlDir) $(addprefix -package ,$(FindlibPackages))
+
ifndef IS_CLEANING_TARGET
ifneq ($(ObjectsO),)
OCAMLAFLAGS += $(patsubst %,-cclib %, \
$(filter-out -L$(LibDir),-l$(LIBRARYNAME) \
$(shell $(LLVM_CONFIG) --ldflags)) \
- $(UsedLibs))
+ $(UsedLibs) $(ExtraLibs))
else
OCAMLAFLAGS += $(patsubst %,-cclib %, \
$(filter-out -L$(LibDir),$(shell $(LLVM_CONFIG) --ldflags)) \
- $(UsedLibs))
+ $(UsedLibs) $(ExtraLibs))
endif
endif
-
-# -g was introduced in 3.10.0.
-#ifneq ($(ENABLE_OPTIMIZED),1)
-# OCAMLDEBUGFLAG := -g
-#endif
-
-Compile.CMI := $(strip $(OCAMLC) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
-Compile.CMO := $(strip $(OCAMLC) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
-Compile.CMX := $(strip $(OCAMLOPT) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
-ifdef OCAMLSTUBS
-# Avoid the need for LD_LIBRARY_PATH
-ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
-ifneq ($(HOST_OS),Darwin)
-OCAMLRPATH := $(RPATH) -Wl,'$(SharedLibDir)'
-endif
-endif
+ifneq ($(DEBUG_SYMBOLS),1)
+ OCAMLDEBUGFLAG := -g
endif
-ifdef OCAMLSTUBS
-Archive.CMA := $(strip $(OCAMLC) -a -dllib -l$(LIBRARYNAME) $(OCAMLDEBUGFLAG) \
- -o)
-else
-Archive.CMA := $(strip $(OCAMLC) -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
- -o)
-endif
+Compile.CMI := $(strip $(OCAMLFIND) c -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
+Compile.CMO := $(strip $(OCAMLFIND) c -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
+Compile.CMX := $(strip $(OCAMLFIND) opt -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
ifdef OCAMLSTUBS
-Archive.CMXA := $(strip $(OCAMLOPT) -a $(patsubst %,-cclib %, \
- $(LLVMLibsOptions) -l$(LIBRARYNAME) \
- -L$(SharedLibDir) $(OCAMLRPATH)) \
- $(OCAMLDEBUGFLAG) -o)
+# -dllib is engaged with ocamlc builds, $(OCAMLSTUBFLAGS) in ocamlc -custom builds.
+Archive.CMA := $(strip $(OCAMLFIND) c -a -dllib -l$(LIBRARYNAME) $(OCAMLSTUBFLAGS) \
+ $(OCAMLDEBUGFLAG) -o)
else
-Archive.CMXA := $(strip $(OCAMLOPT) -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) -o)
+Archive.CMA := $(strip $(OCAMLFIND) c -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
+ -o)
endif
-ifdef OCAMLOPT
-Archive.EXE := $(strip $(OCAMLOPT) -cc $(CXX) $(OCAMLCFLAGS) $(UsedOcamlLibs:%=%.cmxa) $(OCAMLDEBUGFLAG) -o)
+ifdef OCAMLSTUBS
+Archive.CMXA := $(strip $(OCAMLFIND) opt -a $(OCAMLSTUBFLAGS) $(OCAMLDEBUGFLAG) -o)
else
-Archive.EXE := $(strip $(OCAMLC) -cc $(CXX) $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG:%=%.cma) -o)
+Archive.CMXA := $(strip $(OCAMLFIND) opt -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) -o)
endif
# Source files
@@ -191,7 +185,7 @@ $(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
ifdef LIBRARYNAME
$(ObjDir)/$(LIBRARYNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
$(OcamlDir)/.dir $(ObjDir)/.dir
- $(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
+ $(Verb) $(OCAMLFIND) dep $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
-include $(ObjDir)/$(LIBRARYNAME).ocamldep
endif
@@ -199,7 +193,7 @@ endif
ifdef TOOLNAME
$(ObjDir)/$(TOOLNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
$(OcamlDir)/.dir $(ObjDir)/.dir
- $(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
+ $(Verb) $(OCAMLFIND) dep $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
-include $(ObjDir)/$(TOOLNAME).ocamldep
endif
@@ -225,7 +219,7 @@ install-a:: $(LibraryA)
$(Echo) "Installing $(BuildMode) $(DestA)"
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) $(INSTALL) $(LibraryA) $(DestA)
- $(Verb)
+ $(Verb)
uninstall-a::
$(Echo) "Uninstalling $(DestA)"
@@ -368,8 +362,8 @@ endif
##===- Build optimized ocaml archive (.ml's -> .cmx's -> .cmxa, .a) -------===##
# The ocamlopt compiler is supported on a set of targets disjoint from LLVM's.
-# If unavailable, 'configure' will not define OCAMLOPT in Makefile.config.
-ifdef OCAMLOPT
+# If unavailable, 'configure' will set HAVE_OCAMLOPT to 0 in Makefile.config.
+ifeq ($(HAVE_OCAMLOPT),1)
$(OcamlDir)/%.cmx: $(ObjDir)/%.cmx
$(Verb) $(CP) -f $< $@
@@ -419,31 +413,11 @@ uninstall-cmxa::
endif
endif
-##===- Build executables --------------------------------------------------===##
-
-ifdef TOOLNAME
-all-local:: $(OutputEXE)
-clean-local:: clean-exe
-
-$(OutputEXE): $(ToolEXE) $(OcamlDir)/.dir
- $(Verb) $(CP) -f $< $@
-
-ifndef OCAMLOPT
-$(ToolEXE): $(ObjectsCMO) $(OcamlDir)/.dir
- $(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
- $(Verb) $(Archive.EXE) $@ $(ObjectsCMO)
-else
-$(ToolEXE): $(ObjectsCMX) $(OcamlDir)/.dir
- $(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
- $(Verb) $(Archive.EXE) $@ $(ObjectsCMX)
-endif
-endif
-
##===- Generate documentation ---------------------------------------------===##
$(ObjDir)/$(LIBRARYNAME).odoc: $(ObjectsCMI)
$(Echo) "Documenting $(notdir $@)"
- $(Verb) $(OCAMLDOC) -I $(ObjDir) -I $(OcamlDir) -dump $@ $(OcamlHeaders)
+ $(Verb) $(OCAMLFIND) doc -I $(ObjDir) -I $(OcamlDir) -dump $@ $(OcamlHeaders)
ocamldoc: $(ObjDir)/$(LIBRARYNAME).odoc
@@ -454,15 +428,17 @@ printcamlvars::
$(Echo) "LLVM_CONFIG : " '$(LLVM_CONFIG)'
$(Echo) "OCAMLCFLAGS : " '$(OCAMLCFLAGS)'
$(Echo) "OCAMLAFLAGS : " '$(OCAMLAFLAGS)'
- $(Echo) "OCAMLC : " '$(OCAMLC)'
- $(Echo) "OCAMLOPT : " '$(OCAMLOPT)'
- $(Echo) "OCAMLDEP : " '$(OCAMLDEP)'
+ $(Echo) "OCAMLRPATH : " '$(OCAMLRPATH)'
+ $(Echo) "OCAMLSTUBS : " '$(OCAMLSTUBS)'
+ $(Echo) "OCAMLSTUBFLAGS : " '$(OCAMLSTUBFLAGS)'
+ $(Echo) "OCAMLFIND : " '$(OCAMLFIND)'
$(Echo) "Compile.CMI : " '$(Compile.CMI)'
$(Echo) "Compile.CMO : " '$(Compile.CMO)'
$(Echo) "Archive.CMA : " '$(Archive.CMA)'
$(Echo) "Compile.CMX : " '$(Compile.CMX)'
$(Echo) "Archive.CMXA : " '$(Archive.CMXA)'
$(Echo) "CAML_LIBDIR : " '$(CAML_LIBDIR)'
+ $(Echo) "LibraryA : " '$(LibraryA)'
$(Echo) "LibraryCMA : " '$(LibraryCMA)'
$(Echo) "LibraryCMXA : " '$(LibraryCMXA)'
$(Echo) "SharedLib : " '$(SharedLib)'
@@ -482,6 +458,7 @@ printcamlvars::
$(Echo) "DestSharedLib: " '$(DestSharedLib)'
$(Echo) "UsedLibs : " '$(UsedLibs)'
$(Echo) "UsedLibNames : " '$(UsedLibNames)'
+ $(Echo) "ExtraLibs : " '$(ExtraLibs)'
.PHONY: printcamlvars build-cmis \
clean-a clean-cmis clean-cma clean-cmxa \
diff --git a/bindings/ocaml/all_backends/Makefile b/bindings/ocaml/all_backends/Makefile
index a5ff290..f7c8cdb 100644
--- a/bindings/ocaml/all_backends/Makefile
+++ b/bindings/ocaml/all_backends/Makefile
@@ -1,4 +1,4 @@
-##===- bindings/ocaml/all_backends/Makefile ----------------------*- Makefile -*-===##
+##===- bindings/ocaml/all_backends/Makefile ----------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -7,7 +7,7 @@
#
##===----------------------------------------------------------------------===##
#
-# This is the makefile for the Objective Caml Llvm_backends interface.
+# This is the makefile for the Objective Caml Llvm_all_backends interface.
#
##===----------------------------------------------------------------------===##
diff --git a/bindings/ocaml/analysis/Makefile b/bindings/ocaml/analysis/Makefile
index cbfcb24..daff061 100644
--- a/bindings/ocaml/analysis/Makefile
+++ b/bindings/ocaml/analysis/Makefile
@@ -1,14 +1,14 @@
##===- bindings/ocaml/analysis/Makefile --------------------*- Makefile -*-===##
-#
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
-#
+#
##===----------------------------------------------------------------------===##
-#
+#
# This is the makefile for the Objective Caml Llvm_analysis interface.
-#
+#
##===----------------------------------------------------------------------===##
LEVEL := ../../..
diff --git a/bindings/ocaml/analysis/analysis_ocaml.c b/bindings/ocaml/analysis/analysis_ocaml.c
index 91be2d3..44e3197 100644
--- a/bindings/ocaml/analysis/analysis_ocaml.c
+++ b/bindings/ocaml/analysis/analysis_ocaml.c
@@ -20,15 +20,14 @@
#include "caml/mlvalues.h"
#include "caml/memory.h"
-
/* Llvm.llmodule -> string option */
CAMLprim value llvm_verify_module(LLVMModuleRef M) {
CAMLparam0();
CAMLlocal2(String, Option);
-
+
char *Message;
int Result = LLVMVerifyModule(M, LLVMReturnStatusAction, &Message);
-
+
if (0 == Result) {
Option = Val_int(0);
} else {
@@ -36,9 +35,9 @@ CAMLprim value llvm_verify_module(LLVMModuleRef M) {
String = copy_string(Message);
Store_field(Option, 0, String);
}
-
+
LLVMDisposeMessage(Message);
-
+
CAMLreturn(Option);
}
diff --git a/bindings/ocaml/analysis/llvm_analysis.ml b/bindings/ocaml/analysis/llvm_analysis.ml
index 21088ab..8c11a63 100644
--- a/bindings/ocaml/analysis/llvm_analysis.ml
+++ b/bindings/ocaml/analysis/llvm_analysis.ml
@@ -1,4 +1,4 @@
-(*===-- llvm_analysis.ml - LLVM OCaml Interface -----------------*- C++ -*-===*
+(*===-- llvm_analysis.ml - LLVM OCaml Interface ---------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
diff --git a/bindings/ocaml/analysis/llvm_analysis.mli b/bindings/ocaml/analysis/llvm_analysis.mli
index 1a0af02..03197cd 100644
--- a/bindings/ocaml/analysis/llvm_analysis.mli
+++ b/bindings/ocaml/analysis/llvm_analysis.mli
@@ -1,4 +1,4 @@
-(*===-- llvm_analysis.mli - LLVM OCaml Interface ----------------*- C++ -*-===*
+(*===-- llvm_analysis.mli - LLVM OCaml Interface --------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
diff --git a/bindings/ocaml/backends/META.llvm_backend.in b/bindings/ocaml/backends/META.llvm_backend.in
index 0d4a6d6..6c1e8c4 100644
--- a/bindings/ocaml/backends/META.llvm_backend.in
+++ b/bindings/ocaml/backends/META.llvm_backend.in
@@ -5,4 +5,3 @@ requires = "llvm"
archive(byte) = "llvm_@TARGET@.cma"
archive(native) = "llvm_@TARGET@.cmxa"
directory = "."
-linkopts = "-ccopt -lstdc++" \ No newline at end of file
diff --git a/bindings/ocaml/backends/backend_ocaml.c b/bindings/ocaml/backends/backend_ocaml.c
index 2d4ba85..3e1a438 100644
--- a/bindings/ocaml/backends/backend_ocaml.c
+++ b/bindings/ocaml/backends/backend_ocaml.c
@@ -19,10 +19,11 @@
#include "caml/alloc.h"
#include "caml/memory.h"
-// TODO: Figure out how to call these only for targets which support them.
-// LLVMInitialize ## target ## AsmPrinter();
-// LLVMInitialize ## target ## AsmParser();
-// LLVMInitialize ## target ## Disassembler();
+/* TODO: Figure out how to call these only for targets which support them.
+ * LLVMInitialize ## target ## AsmPrinter();
+ * LLVMInitialize ## target ## AsmParser();
+ * LLVMInitialize ## target ## Disassembler();
+ */
#define INITIALIZER1(target) \
CAMLprim value llvm_initialize_ ## target(value Unit) { \
diff --git a/bindings/ocaml/bitreader/Makefile b/bindings/ocaml/bitreader/Makefile
index a1c7de8..dad4e1d 100644
--- a/bindings/ocaml/bitreader/Makefile
+++ b/bindings/ocaml/bitreader/Makefile
@@ -1,14 +1,14 @@
##===- bindings/ocaml/bitreader/Makefile -------------------*- Makefile -*-===##
-#
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
-#
+#
##===----------------------------------------------------------------------===##
-#
+#
# This is the makefile for the Objective Caml Llvm_bitreader interface.
-#
+#
##===----------------------------------------------------------------------===##
LEVEL := ../../..
diff --git a/bindings/ocaml/bitreader/bitreader_ocaml.c b/bindings/ocaml/bitreader/bitreader_ocaml.c
index 0264e73..15ebd5f 100644
--- a/bindings/ocaml/bitreader/bitreader_ocaml.c
+++ b/bindings/ocaml/bitreader/bitreader_ocaml.c
@@ -16,58 +16,28 @@
#include "caml/alloc.h"
#include "caml/fail.h"
#include "caml/memory.h"
+#include "caml/callback.h"
-
-/* Can't use the recommended caml_named_value mechanism for backwards
- compatibility reasons. This is largely equivalent. */
-static value llvm_bitreader_error_exn;
-
-CAMLprim value llvm_register_bitreader_exns(value Error) {
- llvm_bitreader_error_exn = Field(Error, 0);
- register_global_root(&llvm_bitreader_error_exn);
- return Val_unit;
-}
-
-static void llvm_raise(value Prototype, char *Message) {
- CAMLparam1(Prototype);
- CAMLlocal1(CamlMessage);
-
- CamlMessage = copy_string(Message);
- LLVMDisposeMessage(Message);
-
- raise_with_arg(Prototype, CamlMessage);
- abort(); /* NOTREACHED */
-#ifdef CAMLnoreturn
- CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
-#endif
-}
-
-
-/*===-- Modules -----------------------------------------------------------===*/
+void llvm_raise(value Prototype, char *Message);
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
-CAMLprim value llvm_get_module(LLVMContextRef C, LLVMMemoryBufferRef MemBuf) {
- CAMLparam0();
- CAMLlocal2(Variant, MessageVal);
- char *Message;
-
+CAMLprim LLVMModuleRef llvm_get_module(LLVMContextRef C, LLVMMemoryBufferRef MemBuf) {
LLVMModuleRef M;
+ char *Message;
+
if (LLVMGetBitcodeModuleInContext(C, MemBuf, &M, &Message))
- llvm_raise(llvm_bitreader_error_exn, Message);
-
- CAMLreturn((value) M);
+ llvm_raise(*caml_named_value("Llvm_bitreader.Error"), Message);
+
+ return M;
}
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
-CAMLprim value llvm_parse_bitcode(LLVMContextRef C,
- LLVMMemoryBufferRef MemBuf) {
- CAMLparam0();
- CAMLlocal2(Variant, MessageVal);
+CAMLprim LLVMModuleRef llvm_parse_bitcode(LLVMContextRef C, LLVMMemoryBufferRef MemBuf) {
LLVMModuleRef M;
char *Message;
-
+
if (LLVMParseBitcodeInContext(C, MemBuf, &M, &Message))
- llvm_raise(llvm_bitreader_error_exn, Message);
-
- CAMLreturn((value) M);
+ llvm_raise(*caml_named_value("Llvm_bitreader.Error"), Message);
+
+ return M;
}
diff --git a/bindings/ocaml/bitreader/llvm_bitreader.ml b/bindings/ocaml/bitreader/llvm_bitreader.ml
index 865208c..b26efdd 100644
--- a/bindings/ocaml/bitreader/llvm_bitreader.ml
+++ b/bindings/ocaml/bitreader/llvm_bitreader.ml
@@ -1,4 +1,4 @@
-(*===-- llvm_bitreader.ml - LLVM OCaml Interface ----------------*- C++ -*-===*
+(*===-- llvm_bitreader.ml - LLVM OCaml Interface --------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
@@ -7,14 +7,13 @@
*
*===----------------------------------------------------------------------===*)
-
exception Error of string
-external register_exns : exn -> unit = "llvm_register_bitreader_exns"
-let _ = register_exns (Error "")
-
-external get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
- = "llvm_get_module"
+let () = Callback.register_exception "Llvm_bitreader.Error" (Error "")
-external parse_bitcode : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
- = "llvm_parse_bitcode"
+external get_module
+ : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
+ = "llvm_get_module"
+external parse_bitcode
+ : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
+ = "llvm_parse_bitcode"
diff --git a/bindings/ocaml/bitreader/llvm_bitreader.mli b/bindings/ocaml/bitreader/llvm_bitreader.mli
index ff377b9..4351343 100644
--- a/bindings/ocaml/bitreader/llvm_bitreader.mli
+++ b/bindings/ocaml/bitreader/llvm_bitreader.mli
@@ -1,4 +1,4 @@
-(*===-- llvm_bitreader.mli - LLVM OCaml Interface ---------------*- C++ -*-===*
+(*===-- llvm_bitreader.mli - LLVM OCaml Interface -------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
@@ -20,7 +20,6 @@ exception Error of string
encountered. See the function [llvm::getBitcodeModule]. *)
val get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
-
(** [parse_bitcode context mb] parses the bitcode for a new module [m] from the
memory buffer [mb] in the context [context]. Returns [m] if successful, or
raises [Error msg] otherwise, where [msg] is a description of the error
diff --git a/bindings/ocaml/bitwriter/Makefile b/bindings/ocaml/bitwriter/Makefile
index cec0a59..9f0b2c8 100644
--- a/bindings/ocaml/bitwriter/Makefile
+++ b/bindings/ocaml/bitwriter/Makefile
@@ -1,14 +1,14 @@
##===- bindings/ocaml/bitwriter/Makefile -------------------*- Makefile -*-===##
-#
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
-#
+#
##===----------------------------------------------------------------------===##
-#
+#
# This is the makefile for the Objective Caml Llvm_bitwriter interface.
-#
+#
##===----------------------------------------------------------------------===##
LEVEL := ../../..
diff --git a/bindings/ocaml/bitwriter/bitwriter_ocaml.c b/bindings/ocaml/bitwriter/bitwriter_ocaml.c
index a47f700..04fd619 100644
--- a/bindings/ocaml/bitwriter/bitwriter_ocaml.c
+++ b/bindings/ocaml/bitwriter/bitwriter_ocaml.c
@@ -21,25 +21,28 @@
#include "caml/mlvalues.h"
#include "caml/memory.h"
-/*===-- Modules -----------------------------------------------------------===*/
-
/* Llvm.llmodule -> string -> bool */
-CAMLprim value llvm_write_bitcode_file(value M, value Path) {
- int res = LLVMWriteBitcodeToFile((LLVMModuleRef) M, String_val(Path));
- return Val_bool(res == 0);
+CAMLprim value llvm_write_bitcode_file(LLVMModuleRef M, value Path) {
+ int Result = LLVMWriteBitcodeToFile(M, String_val(Path));
+ return Val_bool(Result == 0);
}
/* ?unbuffered:bool -> Llvm.llmodule -> Unix.file_descr -> bool */
-CAMLprim value llvm_write_bitcode_to_fd(value U, value M, value FD) {
+CAMLprim value llvm_write_bitcode_to_fd(value U, LLVMModuleRef M, value FD) {
int Unbuffered;
- int res;
+ int Result;
if (U == Val_int(0)) {
Unbuffered = 0;
} else {
- Unbuffered = Bool_val(Field(U,0));
+ Unbuffered = Bool_val(Field(U, 0));
}
- res = LLVMWriteBitcodeToFD((LLVMModuleRef) M, Int_val(FD), 0, Unbuffered);
- return Val_bool(res == 0);
+ Result = LLVMWriteBitcodeToFD(M, Int_val(FD), 0, Unbuffered);
+ return Val_bool(Result == 0);
+}
+
+/* Llvm.llmodule -> Llvm.llmemorybuffer */
+CAMLprim LLVMMemoryBufferRef llvm_write_bitcode_to_memory_buffer(LLVMModuleRef M) {
+ return LLVMWriteBitcodeToMemoryBuffer(M);
}
diff --git a/bindings/ocaml/bitwriter/llvm_bitwriter.ml b/bindings/ocaml/bitwriter/llvm_bitwriter.ml
index fac8553..fca6efa 100644
--- a/bindings/ocaml/bitwriter/llvm_bitwriter.ml
+++ b/bindings/ocaml/bitwriter/llvm_bitwriter.ml
@@ -1,4 +1,4 @@
-(*===-- llvm_bitwriter.ml - LLVM OCaml Interface ----------------*- C++ -*-===*
+(*===-- llvm_bitwriter.ml - LLVM OCaml Interface --------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
@@ -12,14 +12,17 @@
*
*===----------------------------------------------------------------------===*)
+external write_bitcode_file
+ : Llvm.llmodule -> string -> bool
+ = "llvm_write_bitcode_file"
-(* Writes the bitcode for module the given path. Returns true if successful. *)
-external write_bitcode_file : Llvm.llmodule -> string -> bool
- = "llvm_write_bitcode_file"
+external write_bitcode_to_fd
+ : ?unbuffered:bool -> Llvm.llmodule -> Unix.file_descr -> bool
+ = "llvm_write_bitcode_to_fd"
-external write_bitcode_to_fd : ?unbuffered:bool -> Llvm.llmodule
- -> Unix.file_descr -> bool
- = "llvm_write_bitcode_to_fd"
+external write_bitcode_to_memory_buffer
+ : Llvm.llmodule -> Llvm.llmemorybuffer
+ = "llvm_write_bitcode_to_memory_buffer"
let output_bitcode ?unbuffered channel m =
write_bitcode_to_fd ?unbuffered m (Unix.descr_of_out_channel channel)
diff --git a/bindings/ocaml/bitwriter/llvm_bitwriter.mli b/bindings/ocaml/bitwriter/llvm_bitwriter.mli
index bb3e3b8..3d0f780 100644
--- a/bindings/ocaml/bitwriter/llvm_bitwriter.mli
+++ b/bindings/ocaml/bitwriter/llvm_bitwriter.mli
@@ -1,4 +1,4 @@
-(*===-- llvm_bitwriter.mli - LLVM OCaml Interface ---------------*- C++ -*-===*
+(*===-- llvm_bitwriter.mli - LLVM OCaml Interface -------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
@@ -14,15 +14,22 @@
(** [write_bitcode_file m path] writes the bitcode for module [m] to the file at
[path]. Returns [true] if successful, [false] otherwise. *)
-external write_bitcode_file : Llvm.llmodule -> string -> bool
- = "llvm_write_bitcode_file"
+external write_bitcode_file
+ : Llvm.llmodule -> string -> bool
+ = "llvm_write_bitcode_file"
(** [write_bitcode_to_fd ~unbuffered fd m] writes the bitcode for module
[m] to the channel [c]. If [unbuffered] is [true], after every write the fd
will be flushed. Returns [true] if successful, [false] otherwise. *)
-external write_bitcode_to_fd : ?unbuffered:bool -> Llvm.llmodule
- -> Unix.file_descr -> bool
- = "llvm_write_bitcode_to_fd"
+external write_bitcode_to_fd
+ : ?unbuffered:bool -> Llvm.llmodule -> Unix.file_descr -> bool
+ = "llvm_write_bitcode_to_fd"
+
+(** [write_bitcode_to_memory_buffer m] returns a memory buffer containing
+ the bitcode for module [m]. *)
+external write_bitcode_to_memory_buffer
+ : Llvm.llmodule -> Llvm.llmemorybuffer
+ = "llvm_write_bitcode_to_memory_buffer"
(** [output_bitcode ~unbuffered c m] writes the bitcode for module [m]
to the channel [c]. If [unbuffered] is [true], after every write the fd
diff --git a/bindings/ocaml/executionengine/Makefile b/bindings/ocaml/executionengine/Makefile
index 5fa3f22..8b5d28f 100644
--- a/bindings/ocaml/executionengine/Makefile
+++ b/bindings/ocaml/executionengine/Makefile
@@ -1,19 +1,20 @@
-##===- bindings/ocaml/executionengine/Makefile --------------*- Makefile -*-===##
-#
+##===- bindings/ocaml/executionengine/Makefile -------------*- Makefile -*-===##
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
-#
+#
##===----------------------------------------------------------------------===##
-#
+#
# This is the makefile for the Objective Caml Llvm_executionengine interface.
-#
+#
##===----------------------------------------------------------------------===##
LEVEL := ../../..
LIBRARYNAME := llvm_executionengine
-UsedComponents := executionengine jit interpreter native
+UsedComponents := executionengine mcjit native
UsedOcamlInterfaces := llvm llvm_target
+FindlibPackages := ctypes
include ../Makefile.ocaml
diff --git a/bindings/ocaml/executionengine/executionengine_ocaml.c b/bindings/ocaml/executionengine/executionengine_ocaml.c
index 4b44a91..0557efc 100644
--- a/bindings/ocaml/executionengine/executionengine_ocaml.c
+++ b/bindings/ocaml/executionengine/executionengine_ocaml.c
@@ -15,189 +15,48 @@
|* *|
\*===----------------------------------------------------------------------===*/
+#include <string.h>
+#include <assert.h>
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Target.h"
#include "caml/alloc.h"
#include "caml/custom.h"
#include "caml/fail.h"
#include "caml/memory.h"
-#include <string.h>
-#include <assert.h>
+#include "caml/callback.h"
-/* Force the LLVM interpreter and JIT to be linked in. */
-void llvm_initialize(void) {
- LLVMLinkInInterpreter();
- LLVMLinkInJIT();
-}
+void llvm_raise(value Prototype, char *Message);
/* unit -> bool */
-CAMLprim value llvm_initialize_native_target(value Unit) {
- return Val_bool(LLVMInitializeNativeTarget());
-}
-
-/* Can't use the recommended caml_named_value mechanism for backwards
- compatibility reasons. This is largely equivalent. */
-static value llvm_ee_error_exn;
-
-CAMLprim value llvm_register_ee_exns(value Error) {
- llvm_ee_error_exn = Field(Error, 0);
- register_global_root(&llvm_ee_error_exn);
- return Val_unit;
-}
+CAMLprim value llvm_ee_initialize(value Unit) {
+ LLVMLinkInMCJIT();
-static void llvm_raise(value Prototype, char *Message) {
- CAMLparam1(Prototype);
- CAMLlocal1(CamlMessage);
-
- CamlMessage = copy_string(Message);
- LLVMDisposeMessage(Message);
-
- raise_with_arg(Prototype, CamlMessage);
- abort(); /* NOTREACHED */
-#ifdef CAMLnoreturn
- CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
-#endif
+ return Val_bool(!LLVMInitializeNativeTarget() &&
+ !LLVMInitializeNativeAsmParser() &&
+ !LLVMInitializeNativeAsmPrinter());
}
-
-/*--... Operations on generic values .......................................--*/
-
-#define Genericvalue_val(v) (*(LLVMGenericValueRef *)(Data_custom_val(v)))
-
-static void llvm_finalize_generic_value(value GenVal) {
- LLVMDisposeGenericValue(Genericvalue_val(GenVal));
-}
-
-static struct custom_operations generic_value_ops = {
- (char *) "LLVMGenericValue",
- llvm_finalize_generic_value,
- custom_compare_default,
- custom_hash_default,
- custom_serialize_default,
- custom_deserialize_default
-#ifdef custom_compare_ext_default
- , custom_compare_ext_default
-#endif
-};
-
-static value alloc_generic_value(LLVMGenericValueRef Ref) {
- value Val = alloc_custom(&generic_value_ops, sizeof(LLVMGenericValueRef), 0, 1);
- Genericvalue_val(Val) = Ref;
- return Val;
-}
-
-/* Llvm.lltype -> float -> t */
-CAMLprim value llvm_genericvalue_of_float(LLVMTypeRef Ty, value N) {
- CAMLparam1(N);
- CAMLreturn(alloc_generic_value(
- LLVMCreateGenericValueOfFloat(Ty, Double_val(N))));
-}
-
-/* 'a -> t */
-CAMLprim value llvm_genericvalue_of_pointer(value V) {
- CAMLparam1(V);
- CAMLreturn(alloc_generic_value(LLVMCreateGenericValueOfPointer(Op_val(V))));
-}
-
-/* Llvm.lltype -> int -> t */
-CAMLprim value llvm_genericvalue_of_int(LLVMTypeRef Ty, value Int) {
- return alloc_generic_value(LLVMCreateGenericValueOfInt(Ty, Int_val(Int), 1));
-}
-
-/* Llvm.lltype -> int32 -> t */
-CAMLprim value llvm_genericvalue_of_int32(LLVMTypeRef Ty, value Int32) {
- CAMLparam1(Int32);
- CAMLreturn(alloc_generic_value(
- LLVMCreateGenericValueOfInt(Ty, Int32_val(Int32), 1)));
-}
-
-/* Llvm.lltype -> nativeint -> t */
-CAMLprim value llvm_genericvalue_of_nativeint(LLVMTypeRef Ty, value NatInt) {
- CAMLparam1(NatInt);
- CAMLreturn(alloc_generic_value(
- LLVMCreateGenericValueOfInt(Ty, Nativeint_val(NatInt), 1)));
-}
-
-/* Llvm.lltype -> int64 -> t */
-CAMLprim value llvm_genericvalue_of_int64(LLVMTypeRef Ty, value Int64) {
- CAMLparam1(Int64);
- CAMLreturn(alloc_generic_value(
- LLVMCreateGenericValueOfInt(Ty, Int64_val(Int64), 1)));
-}
-
-/* Llvm.lltype -> t -> float */
-CAMLprim value llvm_genericvalue_as_float(LLVMTypeRef Ty, value GenVal) {
- CAMLparam1(GenVal);
- CAMLreturn(copy_double(
- LLVMGenericValueToFloat(Ty, Genericvalue_val(GenVal))));
-}
-
-/* t -> 'a */
-CAMLprim value llvm_genericvalue_as_pointer(value GenVal) {
- return Val_op(LLVMGenericValueToPointer(Genericvalue_val(GenVal)));
-}
-
-/* t -> int */
-CAMLprim value llvm_genericvalue_as_int(value GenVal) {
- assert(LLVMGenericValueIntWidth(Genericvalue_val(GenVal)) <= 8 * sizeof(value)
- && "Generic value too wide to treat as an int!");
- return Val_int(LLVMGenericValueToInt(Genericvalue_val(GenVal), 1));
-}
-
-/* t -> int32 */
-CAMLprim value llvm_genericvalue_as_int32(value GenVal) {
- CAMLparam1(GenVal);
- assert(LLVMGenericValueIntWidth(Genericvalue_val(GenVal)) <= 32
- && "Generic value too wide to treat as an int32!");
- CAMLreturn(copy_int32(LLVMGenericValueToInt(Genericvalue_val(GenVal), 1)));
-}
-
-/* t -> int64 */
-CAMLprim value llvm_genericvalue_as_int64(value GenVal) {
- CAMLparam1(GenVal);
- assert(LLVMGenericValueIntWidth(Genericvalue_val(GenVal)) <= 64
- && "Generic value too wide to treat as an int64!");
- CAMLreturn(copy_int64(LLVMGenericValueToInt(Genericvalue_val(GenVal), 1)));
-}
-
-/* t -> nativeint */
-CAMLprim value llvm_genericvalue_as_nativeint(value GenVal) {
- CAMLparam1(GenVal);
- assert(LLVMGenericValueIntWidth(Genericvalue_val(GenVal)) <= 8 * sizeof(value)
- && "Generic value too wide to treat as a nativeint!");
- CAMLreturn(copy_nativeint(LLVMGenericValueToInt(Genericvalue_val(GenVal),1)));
-}
-
-
-/*--... Operations on execution engines ....................................--*/
-
-/* llmodule -> ExecutionEngine.t */
-CAMLprim LLVMExecutionEngineRef llvm_ee_create(LLVMModuleRef M) {
- LLVMExecutionEngineRef Interp;
- char *Error;
- if (LLVMCreateExecutionEngineForModule(&Interp, M, &Error))
- llvm_raise(llvm_ee_error_exn, Error);
- return Interp;
-}
-
-/* llmodule -> ExecutionEngine.t */
-CAMLprim LLVMExecutionEngineRef
-llvm_ee_create_interpreter(LLVMModuleRef M) {
- LLVMExecutionEngineRef Interp;
+/* llmodule -> llcompileroption -> ExecutionEngine.t */
+CAMLprim LLVMExecutionEngineRef llvm_ee_create(value OptRecordOpt, LLVMModuleRef M) {
+ value OptRecord;
+ LLVMExecutionEngineRef MCJIT;
char *Error;
- if (LLVMCreateInterpreterForModule(&Interp, M, &Error))
- llvm_raise(llvm_ee_error_exn, Error);
- return Interp;
-}
+ struct LLVMMCJITCompilerOptions Options;
+
+ LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
+ if (OptRecordOpt != Val_int(0)) {
+ OptRecord = Field(OptRecordOpt, 0);
+ Options.OptLevel = Int_val(Field(OptRecord, 0));
+ Options.CodeModel = Int_val(Field(OptRecord, 1));
+ Options.NoFramePointerElim = Int_val(Field(OptRecord, 2));
+ Options.EnableFastISel = Int_val(Field(OptRecord, 3));
+ Options.MCJMM = NULL;
+ }
-/* llmodule -> int -> ExecutionEngine.t */
-CAMLprim LLVMExecutionEngineRef
-llvm_ee_create_jit(LLVMModuleRef M, value OptLevel) {
- LLVMExecutionEngineRef JIT;
- char *Error;
- if (LLVMCreateJITCompilerForModule(&JIT, M, Int_val(OptLevel), &Error))
- llvm_raise(llvm_ee_error_exn, Error);
- return JIT;
+ if (LLVMCreateMCJITCompilerForModule(&MCJIT, M, &Options,
+ sizeof(Options), &Error))
+ llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
+ return MCJIT;
}
/* ExecutionEngine.t -> unit */
@@ -213,43 +72,12 @@ CAMLprim value llvm_ee_add_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
}
/* llmodule -> ExecutionEngine.t -> llmodule */
-CAMLprim LLVMModuleRef llvm_ee_remove_module(LLVMModuleRef M,
- LLVMExecutionEngineRef EE) {
+CAMLprim value llvm_ee_remove_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
LLVMModuleRef RemovedModule;
char *Error;
if (LLVMRemoveModule(EE, M, &RemovedModule, &Error))
- llvm_raise(llvm_ee_error_exn, Error);
- return RemovedModule;
-}
-
-/* string -> ExecutionEngine.t -> llvalue option */
-CAMLprim value llvm_ee_find_function(value Name, LLVMExecutionEngineRef EE) {
- CAMLparam1(Name);
- CAMLlocal1(Option);
- LLVMValueRef Found;
- if (LLVMFindFunction(EE, String_val(Name), &Found))
- CAMLreturn(Val_unit);
- Option = alloc(1, 0);
- Field(Option, 0) = Val_op(Found);
- CAMLreturn(Option);
-}
-
-/* llvalue -> GenericValue.t array -> ExecutionEngine.t -> GenericValue.t */
-CAMLprim value llvm_ee_run_function(LLVMValueRef F, value Args,
- LLVMExecutionEngineRef EE) {
- unsigned NumArgs;
- LLVMGenericValueRef Result, *GVArgs;
- unsigned I;
-
- NumArgs = Wosize_val(Args);
- GVArgs = (LLVMGenericValueRef*) malloc(NumArgs * sizeof(LLVMGenericValueRef));
- for (I = 0; I != NumArgs; ++I)
- GVArgs[I] = Genericvalue_val(Field(Args, I));
-
- Result = LLVMRunFunction(EE, F, NumArgs, GVArgs);
-
- free(GVArgs);
- return alloc_generic_value(Result);
+ llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
+ return Val_unit;
}
/* ExecutionEngine.t -> unit */
@@ -264,78 +92,31 @@ CAMLprim value llvm_ee_run_static_dtors(LLVMExecutionEngineRef EE) {
return Val_unit;
}
-/* llvalue -> string array -> (string * string) array -> ExecutionEngine.t ->
- int */
-CAMLprim value llvm_ee_run_function_as_main(LLVMValueRef F,
- value Args, value Env,
- LLVMExecutionEngineRef EE) {
- CAMLparam2(Args, Env);
- int I, NumArgs, NumEnv, EnvSize, Result;
- const char **CArgs, **CEnv;
- char *CEnvBuf, *Pos;
-
- NumArgs = Wosize_val(Args);
- NumEnv = Wosize_val(Env);
-
- /* Build the environment. */
- CArgs = (const char **) malloc(NumArgs * sizeof(char*));
- for (I = 0; I != NumArgs; ++I)
- CArgs[I] = String_val(Field(Args, I));
-
- /* Compute the size of the environment string buffer. */
- for (I = 0, EnvSize = 0; I != NumEnv; ++I) {
- EnvSize += strlen(String_val(Field(Field(Env, I), 0))) + 1;
- EnvSize += strlen(String_val(Field(Field(Env, I), 1))) + 1;
- }
-
- /* Build the environment. */
- CEnv = (const char **) malloc((NumEnv + 1) * sizeof(char*));
- CEnvBuf = (char*) malloc(EnvSize);
- Pos = CEnvBuf;
- for (I = 0; I != NumEnv; ++I) {
- char *Name = String_val(Field(Field(Env, I), 0)),
- *Value = String_val(Field(Field(Env, I), 1));
- int NameLen = strlen(Name),
- ValueLen = strlen(Value);
-
- CEnv[I] = Pos;
- memcpy(Pos, Name, NameLen);
- Pos += NameLen;
- *Pos++ = '=';
- memcpy(Pos, Value, ValueLen);
- Pos += ValueLen;
- *Pos++ = '\0';
- }
- CEnv[NumEnv] = NULL;
-
- Result = LLVMRunFunctionAsMain(EE, F, NumArgs, CArgs, CEnv);
-
- free(CArgs);
- free(CEnv);
- free(CEnvBuf);
-
- CAMLreturn(Val_int(Result));
-}
-
-/* llvalue -> ExecutionEngine.t -> unit */
-CAMLprim value llvm_ee_free_machine_code(LLVMValueRef F,
- LLVMExecutionEngineRef EE) {
- LLVMFreeMachineCodeForFunction(EE, F);
- return Val_unit;
-}
-
extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData);
/* ExecutionEngine.t -> Llvm_target.DataLayout.t */
CAMLprim value llvm_ee_get_data_layout(LLVMExecutionEngineRef EE) {
value DataLayout;
LLVMTargetDataRef OrigDataLayout;
- OrigDataLayout = LLVMGetExecutionEngineTargetData(EE);
-
char* TargetDataCStr;
+
+ OrigDataLayout = LLVMGetExecutionEngineTargetData(EE);
TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
LLVMDisposeMessage(TargetDataCStr);
return DataLayout;
}
+
+/* Llvm.llvalue -> int64 -> llexecutionengine -> unit */
+CAMLprim value llvm_ee_add_global_mapping(LLVMValueRef Global, value Ptr,
+ LLVMExecutionEngineRef EE) {
+ LLVMAddGlobalMapping(EE, Global, (void*) (Int64_val(Ptr)));
+ return Val_unit;
+}
+
+/* Llvm.llvalue -> llexecutionengine -> int64 */
+CAMLprim value llvm_ee_get_pointer_to_global(LLVMValueRef Global,
+ LLVMExecutionEngineRef EE) {
+ return caml_copy_int64((int64_t) LLVMGetPointerToGlobal(EE, Global));
+}
diff --git a/bindings/ocaml/executionengine/llvm_executionengine.ml b/bindings/ocaml/executionengine/llvm_executionengine.ml
index a738df7..c0ff330 100644
--- a/bindings/ocaml/executionengine/llvm_executionengine.ml
+++ b/bindings/ocaml/executionengine/llvm_executionengine.ml
@@ -1,4 +1,4 @@
-(*===-- llvm_executionengine.ml - LLVM OCaml Interface ----------*- C++ -*-===*
+(*===-- llvm_executionengine.ml - LLVM OCaml Interface --------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
@@ -7,105 +7,54 @@
*
*===----------------------------------------------------------------------===*)
-
exception Error of string
-external register_exns: exn -> unit
- = "llvm_register_ee_exns"
-
-
-module GenericValue = struct
- type t
-
- external of_float: Llvm.lltype -> float -> t
- = "llvm_genericvalue_of_float"
- external of_pointer: 'a -> t
- = "llvm_genericvalue_of_pointer"
- external of_int32: Llvm.lltype -> int32 -> t
- = "llvm_genericvalue_of_int32"
- external of_int: Llvm.lltype -> int -> t
- = "llvm_genericvalue_of_int"
- external of_nativeint: Llvm.lltype -> nativeint -> t
- = "llvm_genericvalue_of_nativeint"
- external of_int64: Llvm.lltype -> int64 -> t
- = "llvm_genericvalue_of_int64"
-
- external as_float: Llvm.lltype -> t -> float
- = "llvm_genericvalue_as_float"
- external as_pointer: t -> 'a
- = "llvm_genericvalue_as_pointer"
- external as_int32: t -> int32
- = "llvm_genericvalue_as_int32"
- external as_int: t -> int
- = "llvm_genericvalue_as_int"
- external as_nativeint: t -> nativeint
- = "llvm_genericvalue_as_nativeint"
- external as_int64: t -> int64
- = "llvm_genericvalue_as_int64"
-end
-
-
-module ExecutionEngine = struct
- type t
-
- (* FIXME: Ocaml is not running this setup code unless we use 'val' in the
- interface, which causes the emission of a stub for each function;
- using 'external' in the module allows direct calls into
- ocaml_executionengine.c. This is hardly fatal, but it is unnecessary
- overhead on top of the two stubs that are already invoked for each
- call into LLVM. *)
- let _ = register_exns (Error "")
-
- external create: Llvm.llmodule -> t
- = "llvm_ee_create"
- external create_interpreter: Llvm.llmodule -> t
- = "llvm_ee_create_interpreter"
- external create_jit: Llvm.llmodule -> int -> t
- = "llvm_ee_create_jit"
- external dispose: t -> unit
- = "llvm_ee_dispose"
- external add_module: Llvm.llmodule -> t -> unit
- = "llvm_ee_add_module"
- external remove_module: Llvm.llmodule -> t -> Llvm.llmodule
- = "llvm_ee_remove_module"
- external find_function: string -> t -> Llvm.llvalue option
- = "llvm_ee_find_function"
- external run_function: Llvm.llvalue -> GenericValue.t array -> t ->
- GenericValue.t
- = "llvm_ee_run_function"
- external run_static_ctors: t -> unit
- = "llvm_ee_run_static_ctors"
- external run_static_dtors: t -> unit
- = "llvm_ee_run_static_dtors"
- external run_function_as_main: Llvm.llvalue -> string array ->
- (string * string) array -> t -> int
- = "llvm_ee_run_function_as_main"
- external free_machine_code: Llvm.llvalue -> t -> unit
- = "llvm_ee_free_machine_code"
-
- external data_layout : t -> Llvm_target.DataLayout.t
- = "llvm_ee_get_data_layout"
-
- (* The following are not bound. Patches are welcome.
-
- add_global_mapping: llvalue -> llgenericvalue -> t -> unit
- clear_all_global_mappings: t -> unit
- update_global_mapping: llvalue -> llgenericvalue -> t -> unit
- get_pointer_to_global_if_available: llvalue -> t -> llgenericvalue
- get_pointer_to_global: llvalue -> t -> llgenericvalue
- get_pointer_to_function: llvalue -> t -> llgenericvalue
- get_pointer_to_function_or_stub: llvalue -> t -> llgenericvalue
- get_global_value_at_address: llgenericvalue -> t -> llvalue option
- store_value_to_memory: llgenericvalue -> llgenericvalue -> lltype -> unit
- initialize_memory: llvalue -> llgenericvalue -> t -> unit
- recompile_and_relink_function: llvalue -> t -> llgenericvalue
- get_or_emit_global_variable: llvalue -> t -> llgenericvalue
- disable_lazy_compilation: t -> unit
- lazy_compilation_enabled: t -> bool
- install_lazy_function_creator: (string -> llgenericvalue) -> t -> unit
-
- *)
-end
-
-external initialize_native_target : unit -> bool
- = "llvm_initialize_native_target"
+let () = Callback.register_exception "Llvm_executionengine.Error" (Error "")
+
+external initialize : unit -> bool
+ = "llvm_ee_initialize"
+
+type llexecutionengine
+
+type llcompileroptions = {
+ opt_level: int;
+ code_model: Llvm_target.CodeModel.t;
+ no_framepointer_elim: bool;
+ enable_fast_isel: bool;
+}
+
+let default_compiler_options = {
+ opt_level = 0;
+ code_model = Llvm_target.CodeModel.JITDefault;
+ no_framepointer_elim = false;
+ enable_fast_isel = false }
+
+external create : ?options:llcompileroptions -> Llvm.llmodule -> llexecutionengine
+ = "llvm_ee_create"
+external dispose : llexecutionengine -> unit
+ = "llvm_ee_dispose"
+external add_module : Llvm.llmodule -> llexecutionengine -> unit
+ = "llvm_ee_add_module"
+external remove_module : Llvm.llmodule -> llexecutionengine -> unit
+ = "llvm_ee_remove_module"
+external run_static_ctors : llexecutionengine -> unit
+ = "llvm_ee_run_static_ctors"
+external run_static_dtors : llexecutionengine -> unit
+ = "llvm_ee_run_static_dtors"
+external data_layout : llexecutionengine -> Llvm_target.DataLayout.t
+ = "llvm_ee_get_data_layout"
+external add_global_mapping_ : Llvm.llvalue -> int64 -> llexecutionengine -> unit
+ = "llvm_ee_add_global_mapping"
+external get_pointer_to_global_ : Llvm.llvalue -> llexecutionengine -> int64
+ = "llvm_ee_get_pointer_to_global"
+
+let add_global_mapping llval ptr ee =
+ add_global_mapping_ llval (Ctypes.raw_address_of_ptr (Ctypes.to_voidp ptr)) ee
+
+let get_pointer_to_global llval typ ee =
+ Ctypes.coerce (let open Ctypes in ptr void) typ
+ (Ctypes.ptr_of_raw_address (get_pointer_to_global_ llval ee))
+
+(* The following are not bound. Patches are welcome.
+target_machine : llexecutionengine -> Llvm_target.TargetMachine.t
+ *)
diff --git a/bindings/ocaml/executionengine/llvm_executionengine.mli b/bindings/ocaml/executionengine/llvm_executionengine.mli
index 74a6062..b07151d 100644
--- a/bindings/ocaml/executionengine/llvm_executionengine.mli
+++ b/bindings/ocaml/executionengine/llvm_executionengine.mli
@@ -1,4 +1,4 @@
-(*===-- llvm_executionengine.mli - LLVM OCaml Interface ---------*- C++ -*-===*
+(*===-- llvm_executionengine.mli - LLVM OCaml Interface -------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
@@ -10,147 +10,75 @@
(** JIT Interpreter.
This interface provides an OCaml API for LLVM execution engine (JIT/
- interpreter), the classes in the ExecutionEngine library. *)
+ interpreter), the classes in the [ExecutionEngine] library. *)
exception Error of string
-module GenericValue: sig
- (** [GenericValue.t] is a boxed union type used to portably pass arguments to
- and receive values from the execution engine. It supports only a limited
- selection of types; for more complex argument types, it is necessary to
- generate a stub function by hand or to pass parameters by reference.
- See the struct [llvm::GenericValue]. *)
- type t
-
- (** [of_float fpty n] boxes the float [n] in a float-valued generic value
- according to the floating point type [fpty]. See the fields
- [llvm::GenericValue::DoubleVal] and [llvm::GenericValue::FloatVal]. *)
- val of_float : Llvm.lltype -> float -> t
-
- (** [of_pointer v] boxes the pointer value [v] in a generic value. See the
- field [llvm::GenericValue::PointerVal]. *)
- val of_pointer : 'a -> t
-
- (** [of_int32 n w] boxes the int32 [i] in a generic value with the bitwidth
- [w]. See the field [llvm::GenericValue::IntVal]. *)
- val of_int32 : Llvm.lltype -> int32 -> t
-
- (** [of_int n w] boxes the int [i] in a generic value with the bitwidth
- [w]. See the field [llvm::GenericValue::IntVal]. *)
- val of_int : Llvm.lltype -> int -> t
-
- (** [of_natint n w] boxes the native int [i] in a generic value with the
- bitwidth [w]. See the field [llvm::GenericValue::IntVal]. *)
- val of_nativeint : Llvm.lltype -> nativeint -> t
-
- (** [of_int64 n w] boxes the int64 [i] in a generic value with the bitwidth
- [w]. See the field [llvm::GenericValue::IntVal]. *)
- val of_int64 : Llvm.lltype -> int64 -> t
-
- (** [as_float fpty gv] unboxes the floating point-valued generic value [gv] of
- floating point type [fpty]. See the fields [llvm::GenericValue::DoubleVal]
- and [llvm::GenericValue::FloatVal]. *)
- val as_float : Llvm.lltype -> t -> float
-
- (** [as_pointer gv] unboxes the pointer-valued generic value [gv]. See the
- field [llvm::GenericValue::PointerVal]. *)
- val as_pointer : t -> 'a
-
- (** [as_int32 gv] unboxes the integer-valued generic value [gv] as an [int32].
- Is invalid if [gv] has a bitwidth greater than 32 bits. See the field
- [llvm::GenericValue::IntVal]. *)
- val as_int32 : t -> int32
-
- (** [as_int gv] unboxes the integer-valued generic value [gv] as an [int].
- Is invalid if [gv] has a bitwidth greater than the host bit width (but the
- most significant bit may be lost). See the field
- [llvm::GenericValue::IntVal]. *)
- val as_int : t -> int
-
- (** [as_natint gv] unboxes the integer-valued generic value [gv] as a
- [nativeint]. Is invalid if [gv] has a bitwidth greater than
- [nativeint]. See the field [llvm::GenericValue::IntVal]. *)
- val as_nativeint : t -> nativeint
-
- (** [as_int64 gv] returns the integer-valued generic value [gv] as an [int64].
- Is invalid if [gv] has a bitwidth greater than [int64]. See the field
- [llvm::GenericValue::IntVal]. *)
- val as_int64 : t -> int64
-end
-
-
-module ExecutionEngine: sig
- (** An execution engine is either a JIT compiler or an interpreter, capable of
- directly loading an LLVM module and executing its functions without first
- invoking a static compiler and generating a native executable. *)
- type t
-
- (** [create m] creates a new execution engine, taking ownership of the
- module [m] if successful. Creates a JIT if possible, else falls back to an
- interpreter. Raises [Error msg] if an error occurrs. The execution engine
- is not garbage collected and must be destroyed with [dispose ee].
- See the function [llvm::EngineBuilder::create]. *)
- val create : Llvm.llmodule -> t
-
- (** [create_interpreter m] creates a new interpreter, taking ownership of the
- module [m] if successful. Raises [Error msg] if an error occurrs. The
- execution engine is not garbage collected and must be destroyed with
- [dispose ee].
- See the function [llvm::EngineBuilder::create]. *)
- val create_interpreter : Llvm.llmodule -> t
-
- (** [create_jit m optlevel] creates a new JIT (just-in-time compiler), taking
- ownership of the module [m] if successful with the desired optimization
- level [optlevel]. Raises [Error msg] if an error occurrs. The execution
- engine is not garbage collected and must be destroyed with [dispose ee].
- See the function [llvm::EngineBuilder::create]. *)
- val create_jit : Llvm.llmodule -> int -> t
-
- (** [dispose ee] releases the memory used by the execution engine and must be
- invoked to avoid memory leaks. *)
- val dispose : t -> unit
-
- (** [add_module m ee] adds the module [m] to the execution engine [ee]. *)
- val add_module : Llvm.llmodule -> t -> unit
-
- (** [remove_module m ee] removes the module [m] from the execution engine
- [ee], disposing of [m] and the module referenced by [mp]. Raises
- [Error msg] if an error occurs. *)
- val remove_module : Llvm.llmodule -> t -> Llvm.llmodule
-
- (** [find_function n ee] finds the function named [n] defined in any of the
- modules owned by the execution engine [ee]. Returns [None] if the function
- is not found and [Some f] otherwise. *)
- val find_function : string -> t -> Llvm.llvalue option
-
- (** [run_function f args ee] synchronously executes the function [f] with the
- arguments [args], which must be compatible with the parameter types. *)
- val run_function : Llvm.llvalue -> GenericValue.t array -> t ->
- GenericValue.t
-
- (** [run_static_ctors ee] executes the static constructors of each module in
- the execution engine [ee]. *)
- val run_static_ctors : t -> unit
-
- (** [run_static_dtors ee] executes the static destructors of each module in
- the execution engine [ee]. *)
- val run_static_dtors : t -> unit
-
- (** [run_function_as_main f args env ee] executes the function [f] as a main
- function, passing it [argv] and [argc] according to the string array
- [args], and [envp] as specified by the array [env]. Returns the integer
- return value of the function. *)
- val run_function_as_main : Llvm.llvalue -> string array ->
- (string * string) array -> t -> int
-
- (** [free_machine_code f ee] releases the memory in the execution engine [ee]
- used to store the machine code for the function [f]. *)
- val free_machine_code : Llvm.llvalue -> t -> unit
-
- (** [data_layout ee] is the data layout of the execution engine [ee]. *)
- val data_layout : t -> Llvm_target.DataLayout.t
-end
-
-(** [initialize_native_target ()] initializes the native target corresponding
- to the host. Returns [true] if initialization is {b not} done. *)
-val initialize_native_target : unit -> bool
+(** [initialize ()] initializes the backend corresponding to the host.
+ Returns [true] if initialization is successful; [false] indicates
+ that there is no such backend or it is unable to emit object code
+ via MCJIT. *)
+val initialize : unit -> bool
+
+(** An execution engine is either a JIT compiler or an interpreter, capable of
+ directly loading an LLVM module and executing its functions without first
+ invoking a static compiler and generating a native executable. *)
+type llexecutionengine
+
+(** MCJIT compiler options. See [llvm::TargetOptions]. *)
+type llcompileroptions = {
+ opt_level: int;
+ code_model: Llvm_target.CodeModel.t;
+ no_framepointer_elim: bool;
+ enable_fast_isel: bool;
+}
+
+(** Default MCJIT compiler options:
+ [{ opt_level = 0; code_model = CodeModel.JIT_default;
+ no_framepointer_elim = false; enable_fast_isel = false }] *)
+val default_compiler_options : llcompileroptions
+
+(** [create m optlevel] creates a new MCJIT just-in-time compiler, taking
+ ownership of the module [m] if successful with the desired optimization
+ level [optlevel]. Raises [Error msg] if an error occurrs. The execution
+ engine is not garbage collected and must be destroyed with [dispose ee].
+
+ Run {!initialize} before using this function.
+
+ See the function [llvm::EngineBuilder::create]. *)
+val create : ?options:llcompileroptions -> Llvm.llmodule -> llexecutionengine
+
+(** [dispose ee] releases the memory used by the execution engine and must be
+ invoked to avoid memory leaks. *)
+val dispose : llexecutionengine -> unit
+
+(** [add_module m ee] adds the module [m] to the execution engine [ee]. *)
+val add_module : Llvm.llmodule -> llexecutionengine -> unit
+
+(** [remove_module m ee] removes the module [m] from the execution engine
+ [ee]. Raises [Error msg] if an error occurs. *)
+val remove_module : Llvm.llmodule -> llexecutionengine -> unit
+
+(** [run_static_ctors ee] executes the static constructors of each module in
+ the execution engine [ee]. *)
+val run_static_ctors : llexecutionengine -> unit
+
+(** [run_static_dtors ee] executes the static destructors of each module in
+ the execution engine [ee]. *)
+val run_static_dtors : llexecutionengine -> unit
+
+(** [data_layout ee] is the data layout of the execution engine [ee]. *)
+val data_layout : llexecutionengine -> Llvm_target.DataLayout.t
+
+(** [add_global_mapping gv ptr ee] tells the execution engine [ee] that
+ the global [gv] is at the specified location [ptr], which must outlive
+ [gv] and [ee].
+ All uses of [gv] in the compiled code will refer to [ptr]. *)
+val add_global_mapping : Llvm.llvalue -> 'a Ctypes.ptr -> llexecutionengine -> unit
+
+(** [get_pointer_to_global gv typ ee] returns the value of the global
+ variable [gv] in the execution engine [ee] as type [typ], which may
+ be a pointer type (e.g. [int ptr typ]) for global variables or
+ a function (e.g. [(int -> int) typ]) type for functions, and which
+ will be live as long as [gv] and [ee] are. *)
+val get_pointer_to_global : Llvm.llvalue -> 'a Ctypes.typ -> llexecutionengine -> 'a
diff --git a/bindings/ocaml/irreader/irreader_ocaml.c b/bindings/ocaml/irreader/irreader_ocaml.c
index 30c10c7..ce593db 100644
--- a/bindings/ocaml/irreader/irreader_ocaml.c
+++ b/bindings/ocaml/irreader/irreader_ocaml.c
@@ -16,33 +16,9 @@
#include "caml/alloc.h"
#include "caml/fail.h"
#include "caml/memory.h"
+#include "caml/callback.h"
-/* Can't use the recommended caml_named_value mechanism for backwards
- compatibility reasons. This is largely equivalent. */
-static value llvm_irreader_error_exn;
-
-CAMLprim value llvm_register_irreader_exns(value Error) {
- llvm_irreader_error_exn = Field(Error, 0);
- register_global_root(&llvm_irreader_error_exn);
- return Val_unit;
-}
-
-static void llvm_raise(value Prototype, char *Message) {
- CAMLparam1(Prototype);
- CAMLlocal1(CamlMessage);
-
- CamlMessage = copy_string(Message);
- LLVMDisposeMessage(Message);
-
- raise_with_arg(Prototype, CamlMessage);
- abort(); /* NOTREACHED */
-#ifdef CAMLnoreturn
- CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
-#endif
-}
-
-
-/*===-- Modules -----------------------------------------------------------===*/
+void llvm_raise(value Prototype, char *Message);
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
CAMLprim value llvm_parse_ir(LLVMContextRef C,
@@ -53,7 +29,7 @@ CAMLprim value llvm_parse_ir(LLVMContextRef C,
char *Message;
if (LLVMParseIRInContext(C, MemBuf, &M, &Message))
- llvm_raise(llvm_irreader_error_exn, Message);
+ llvm_raise(*caml_named_value("Llvm_irreader.Error"), Message);
CAMLreturn((value) M);
}
diff --git a/bindings/ocaml/irreader/llvm_irreader.ml b/bindings/ocaml/irreader/llvm_irreader.ml
index 455b1fa..f757d62 100644
--- a/bindings/ocaml/irreader/llvm_irreader.ml
+++ b/bindings/ocaml/irreader/llvm_irreader.ml
@@ -10,8 +10,7 @@
exception Error of string
-external register_exns : exn -> unit = "llvm_register_irreader_exns"
-let _ = register_exns (Error "")
+let _ = Callback.register_exception "Llvm_irreader.Error" (Error "")
external parse_ir : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
= "llvm_parse_ir"
diff --git a/bindings/ocaml/linker/linker_ocaml.c b/bindings/ocaml/linker/linker_ocaml.c
index 2491e3b..ed37777 100644
--- a/bindings/ocaml/linker/linker_ocaml.c
+++ b/bindings/ocaml/linker/linker_ocaml.c
@@ -1,4 +1,4 @@
-/*===-- linker_ocaml.c - LLVM Ocaml Glue ------------------------*- C++ -*-===*\
+/*===-- linker_ocaml.c - LLVM OCaml Glue ------------------------*- C++ -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
@@ -19,36 +19,16 @@
#include "caml/alloc.h"
#include "caml/memory.h"
#include "caml/fail.h"
+#include "caml/callback.h"
-static value llvm_linker_error_exn;
+void llvm_raise(value Prototype, char *Message);
-CAMLprim value llvm_register_linker_exns(value Error) {
- llvm_linker_error_exn = Field(Error, 0);
- register_global_root(&llvm_linker_error_exn);
- return Val_unit;
-}
-
-static void llvm_raise(value Prototype, char *Message) {
- CAMLparam1(Prototype);
- CAMLlocal1(CamlMessage);
-
- CamlMessage = copy_string(Message);
- LLVMDisposeMessage(Message);
-
- raise_with_arg(Prototype, CamlMessage);
- abort(); /* NOTREACHED */
-#ifdef CAMLnoreturn
- CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
-#endif
-}
-
-/* llmodule -> llmodule -> Mode.t -> unit
- raises Error msg on error */
+/* llmodule -> llmodule -> Mode.t -> unit */
CAMLprim value llvm_link_modules(LLVMModuleRef Dst, LLVMModuleRef Src, value Mode) {
char* Message;
if (LLVMLinkModules(Dst, Src, Int_val(Mode), &Message))
- llvm_raise(llvm_linker_error_exn, Message);
+ llvm_raise(*caml_named_value("Llvm_linker.Error"), Message);
return Val_unit;
}
diff --git a/bindings/ocaml/linker/llvm_linker.ml b/bindings/ocaml/linker/llvm_linker.ml
index 2b73e2e..5854d70 100644
--- a/bindings/ocaml/linker/llvm_linker.ml
+++ b/bindings/ocaml/linker/llvm_linker.ml
@@ -9,8 +9,7 @@
exception Error of string
-external register_exns : exn -> unit = "llvm_register_linker_exns"
-let _ = register_exns (Error "")
+let () = Callback.register_exception "Llvm_linker.Error" (Error "")
module Mode = struct
type t =
@@ -19,4 +18,4 @@ module Mode = struct
end
external link_modules : Llvm.llmodule -> Llvm.llmodule -> Mode.t -> unit
- = "llvm_link_modules" \ No newline at end of file
+ = "llvm_link_modules"
diff --git a/bindings/ocaml/llvm/META.llvm.in b/bindings/ocaml/llvm/META.llvm.in
index edb84e0..f9808c7 100644
--- a/bindings/ocaml/llvm/META.llvm.in
+++ b/bindings/ocaml/llvm/META.llvm.in
@@ -4,7 +4,6 @@ description = "LLVM OCaml bindings"
archive(byte) = "llvm.cma"
archive(native) = "llvm.cmxa"
directory = "."
-linkopts = "-ccopt -lstdc++"
package "analysis" (
requires = "llvm"
@@ -31,7 +30,7 @@ package "bitwriter" (
)
package "executionengine" (
- requires = "llvm,llvm.target"
+ requires = "llvm,llvm.target,ctypes.foreign"
version = "@PACKAGE_VERSION@"
description = "JIT and Interpreter for LLVM"
archive(byte) = "llvm_executionengine.cma"
diff --git a/bindings/ocaml/llvm/Makefile b/bindings/ocaml/llvm/Makefile
index 850f564..fb682c7 100644
--- a/bindings/ocaml/llvm/Makefile
+++ b/bindings/ocaml/llvm/Makefile
@@ -1,20 +1,21 @@
##===- bindings/ocaml/llvm/Makefile ------------------------*- Makefile -*-===##
-#
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
-#
+#
##===----------------------------------------------------------------------===##
-#
+#
# This is the makefile for the Objective Caml Llvm interface.
-#
+#
##===----------------------------------------------------------------------===##
LEVEL := ../../..
LIBRARYNAME := llvm
-UsedComponents := core
+UsedComponents := core transformutils
UsedOcamlLibs := llvm
+ExtraLibs := -lstdc++
include ../Makefile.ocaml
diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml
index 39875a5..0df4d40 100644
--- a/bindings/ocaml/llvm/llvm.ml
+++ b/bindings/ocaml/llvm/llvm.ml
@@ -1,4 +1,4 @@
-(*===-- llvm/llvm.ml - LLVM Ocaml Interface --------------------------------===*
+(*===-- llvm/llvm.ml - LLVM OCaml Interface -------------------------------===*
*
* The LLVM Compiler Infrastructure
*
@@ -66,6 +66,13 @@ module Visibility = struct
| Protected
end
+module DLLStorageClass = struct
+ type t =
+ | Default
+ | DLLImport
+ | DLLExport
+end
+
module CallConv = struct
let c = 0
let fast = 8
@@ -278,8 +285,7 @@ end
exception IoError of string
-external register_exns : exn -> unit = "llvm_register_core_exns"
-let _ = register_exns (IoError "")
+let () = Callback.register_exception "Llvm.IoError" (IoError "")
external install_fatal_error_handler : (string -> unit) -> unit
= "llvm_install_fatal_error_handler"
@@ -287,6 +293,8 @@ external reset_fatal_error_handler : unit -> unit
= "llvm_reset_fatal_error_handler"
external enable_pretty_stacktrace : unit -> unit
= "llvm_enable_pretty_stacktrace"
+external parse_command_line_options : ?overview:string -> string array -> unit
+ = "llvm_parse_command_line_options"
type ('a, 'b) llpos =
| At_end of 'a
@@ -305,6 +313,7 @@ external mdkind_id : llcontext -> string -> llmdkind = "llvm_mdkind_id"
(*===-- Modules -----------------------------------------------------------===*)
external create_module : llcontext -> string -> llmodule = "llvm_create_module"
external dispose_module : llmodule -> unit = "llvm_dispose_module"
+external clone_module : llmodule -> llmodule = "LLVMCloneModule"
external target_triple: llmodule -> string
= "llvm_target_triple"
external set_target_triple: string -> llmodule -> unit
@@ -428,6 +437,7 @@ let fold_right_uses f v init =
(*--... Operations on users ................................................--*)
external operand : llvalue -> int -> llvalue = "llvm_operand"
+external operand_use : llvalue -> int -> lluse = "llvm_operand_use"
external set_operand : llvalue -> int -> llvalue -> unit = "llvm_set_operand"
external num_operands : llvalue -> int = "llvm_num_operands"
@@ -465,6 +475,8 @@ external int64_of_const : llvalue -> Int64.t option
external const_int_of_string : lltype -> string -> int -> llvalue
= "llvm_const_int_of_string"
external const_float : lltype -> float -> llvalue = "llvm_const_float"
+external float_of_const : llvalue -> float option
+ = "llvm_float_of_const"
external const_float_of_string : lltype -> string -> llvalue
= "llvm_const_float_of_string"
@@ -479,6 +491,8 @@ external const_named_struct : lltype -> llvalue array -> llvalue
external const_packed_struct : llcontext -> llvalue array -> llvalue
= "llvm_const_packed_struct"
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
+external string_of_const : llvalue -> string option = "llvm_string_of_const"
+external const_element : llvalue -> int -> llvalue = "llvm_const_element"
(*--... Constant expressions ...............................................--*)
external align_of : lltype -> llvalue = "LLVMAlignOf"
@@ -569,6 +583,8 @@ external section : llvalue -> string = "llvm_section"
external set_section : string -> llvalue -> unit = "llvm_set_section"
external visibility : llvalue -> Visibility.t = "llvm_visibility"
external set_visibility : Visibility.t -> llvalue -> unit = "llvm_set_visibility"
+external dll_storage_class : llvalue -> DLLStorageClass.t = "llvm_dll_storage_class"
+external set_dll_storage_class : DLLStorageClass.t -> llvalue -> unit = "llvm_set_dll_storage_class"
external alignment : llvalue -> int = "llvm_alignment"
external set_alignment : int -> llvalue -> unit = "llvm_set_alignment"
external is_global_constant : llvalue -> bool = "llvm_is_global_constant"
@@ -952,6 +968,8 @@ external instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos
external instr_opcode : llvalue -> Opcode.t = "llvm_instr_get_opcode"
external icmp_predicate : llvalue -> Icmp.t option = "llvm_instr_icmp_predicate"
+external fcmp_predicate : llvalue -> Fcmp.t option = "llvm_instr_fcmp_predicate"
+external instr_clone : llvalue -> llvalue = "llvm_instr_clone"
let rec iter_instrs_range f i e =
if i = e then () else
@@ -1019,6 +1037,63 @@ external set_tail_call : bool -> llvalue -> unit = "llvm_set_tail_call"
external is_volatile : llvalue -> bool = "llvm_is_volatile"
external set_volatile : bool -> llvalue -> unit = "llvm_set_volatile"
+(*--... Operations on terminators ..........................................--*)
+
+let is_terminator llv =
+ let open ValueKind in
+ let open Opcode in
+ match classify_value llv with
+ | Instruction (Br | IndirectBr | Invoke | Resume | Ret | Switch | Unreachable)
+ -> true
+ | _ -> false
+
+external successor : llvalue -> int -> llbasicblock = "llvm_successor"
+external set_successor : llvalue -> int -> llbasicblock -> unit
+ = "llvm_set_successor"
+external num_successors : llvalue -> int = "llvm_num_successors"
+
+let successors llv =
+ if not (is_terminator llv) then
+ raise (Invalid_argument "Llvm.successors can only be used on terminators")
+ else
+ Array.init (num_successors llv) (successor llv)
+
+let iter_successors f llv =
+ if not (is_terminator llv) then
+ raise (Invalid_argument "Llvm.iter_successors can only be used on terminators")
+ else
+ for i = 0 to num_successors llv - 1 do
+ f (successor llv i)
+ done
+
+let fold_successors f llv z =
+ if not (is_terminator llv) then
+ raise (Invalid_argument "Llvm.fold_successors can only be used on terminators")
+ else
+ let n = num_successors llv in
+ let rec aux i acc =
+ if i >= n then acc
+ else begin
+ let llb = successor llv i in
+ aux (i+1) (f llb acc)
+ end
+ in aux 0 z
+
+
+(*--... Operations on branches .............................................--*)
+external condition : llvalue -> llvalue = "llvm_condition"
+external set_condition : llvalue -> llvalue -> unit
+ = "llvm_set_condition"
+external is_conditional : llvalue -> bool = "llvm_is_conditional"
+
+let get_branch llv =
+ if classify_value llv <> ValueKind.Instruction Opcode.Br then
+ None
+ else if is_conditional llv then
+ Some (`Conditional (condition llv, successor llv 0, successor llv 1))
+ else
+ Some (`Unconditional (successor llv 0))
+
(*--... Operations on phi nodes ............................................--*)
external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit
= "llvm_add_incoming"
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index f5f5b53..e5e90c3 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -105,6 +105,15 @@ module Visibility : sig
| Protected
end
+(** The DLL storage class of a global value, accessed with {!dll_storage_class} and
+ {!set_dll_storage_class}. See [llvm::GlobalValue::DLLStorageClassTypes]. *)
+module DLLStorageClass : sig
+ type t =
+ | Default
+ | DLLImport
+ | DLLExport
+end
+
(** The following calling convention values may be accessed with
{!function_call_conv} and {!set_function_call_conv}. Calling
conventions are open-ended. *)
@@ -157,16 +166,16 @@ end
See the [llvm::ICmpInst::Predicate] enumeration. *)
module Icmp : sig
type t =
- | Eq (* Equal *)
- | Ne (* Not equal *)
- | Ugt (* Unsigned greater than *)
- | Uge (* Unsigned greater or equal *)
- | Ult (* Unsigned less than *)
- | Ule (* Unsigned less or equal *)
- | Sgt (* Signed greater than *)
- | Sge (* Signed greater or equal *)
- | Slt (* Signed less than *)
- | Sle (* Signed less or equal *)
+ | Eq (** Equal *)
+ | Ne (** Not equal *)
+ | Ugt (** Unsigned greater than *)
+ | Uge (** Unsigned greater or equal *)
+ | Ult (** Unsigned less than *)
+ | Ule (** Unsigned less or equal *)
+ | Sgt (** Signed greater than *)
+ | Sge (** Signed greater or equal *)
+ | Slt (** Signed less than *)
+ | Sle (** Signed less or equal *)
end
(** The predicate for a floating-point comparison ([fcmp]) instruction.
@@ -175,38 +184,38 @@ end
See the [llvm::FCmpInst::Predicate] enumeration. *)
module Fcmp : sig
type t =
- | False (* Always false *)
- | Oeq (* Ordered and equal *)
- | Ogt (* Ordered and greater than *)
- | Oge (* Ordered and greater or equal *)
- | Olt (* Ordered and less than *)
- | Ole (* Ordered and less or equal *)
- | One (* Ordered and not equal *)
- | Ord (* Ordered (no operand is NaN) *)
- | Uno (* Unordered (one operand at least is NaN) *)
- | Ueq (* Unordered and equal *)
- | Ugt (* Unordered and greater than *)
- | Uge (* Unordered and greater or equal *)
- | Ult (* Unordered and less than *)
- | Ule (* Unordered and less or equal *)
- | Une (* Unordered and not equal *)
- | True (* Always true *)
+ | False (** Always false *)
+ | Oeq (** Ordered and equal *)
+ | Ogt (** Ordered and greater than *)
+ | Oge (** Ordered and greater or equal *)
+ | Olt (** Ordered and less than *)
+ | Ole (** Ordered and less or equal *)
+ | One (** Ordered and not equal *)
+ | Ord (** Ordered (no operand is NaN) *)
+ | Uno (** Unordered (one operand at least is NaN) *)
+ | Ueq (** Unordered and equal *)
+ | Ugt (** Unordered and greater than *)
+ | Uge (** Unordered and greater or equal *)
+ | Ult (** Unordered and less than *)
+ | Ule (** Unordered and less or equal *)
+ | Une (** Unordered and not equal *)
+ | True (** Always true *)
end
(** The opcodes for LLVM instructions and constant expressions. *)
module Opcode : sig
type t =
- | Invalid (* not an instruction *)
- (* Terminator Instructions *)
- | Ret
+ | Invalid (** Not an instruction *)
+
+ | Ret (** Terminator Instructions *)
| Br
| Switch
| IndirectBr
| Invoke
| Invalid2
| Unreachable
- (* Standard Binary Operators *)
- | Add
+
+ | Add (** Standard Binary Operators *)
| FAdd
| Sub
| FSub
@@ -218,20 +227,20 @@ module Opcode : sig
| URem
| SRem
| FRem
- (* Logical Operators *)
- | Shl
+
+ | Shl (** Logical Operators *)
| LShr
| AShr
| And
| Or
| Xor
- (* Memory Operators *)
- | Alloca
+
+ | Alloca (** Memory Operators *)
| Load
| Store
| GetElementPtr
- (* Cast Operators *)
- | Trunc
+
+ | Trunc (** Cast Operators *)
| ZExt
| SExt
| FPToUI
@@ -243,8 +252,8 @@ module Opcode : sig
| PtrToInt
| IntToPtr
| BitCast
- (* Other Operators *)
- | ICmp
+
+ | ICmp (** Other Operators *)
| FCmp
| PHI
| Call
@@ -291,7 +300,7 @@ module AtomicOrdering : sig
| NotAtomic
| Unordered
| Monotonic
- | Invalid (* removed due to API changes *)
+ | Invalid (** removed due to API changes *)
| Acquire
| Release
| AcqiureRelease
@@ -381,6 +390,14 @@ val install_fatal_error_handler : (string -> unit) -> unit
(** [reset_fatal_error_handler ()] resets LLVM's fatal error handler. *)
val reset_fatal_error_handler : unit -> unit
+(** [parse_command_line_options ?overview args] parses [args] using
+ the LLVM command line parser. Note that the only stable thing about this
+ function is its signature; you cannot rely on any particular set of command
+ line arguments being interpreted the same way across LLVM versions.
+
+ See the function [llvm::cl::ParseCommandLineOptions()]. *)
+val parse_command_line_options : ?overview:string -> string array -> unit
+
(** {6 Contexts} *)
(** [create_context ()] creates a context for storing the "global" state in
@@ -414,6 +431,9 @@ val create_module : llcontext -> string -> llmodule
[llvm::Module::~Module]. *)
val dispose_module : llmodule -> unit
+(** [clone_module m] returns an exact copy of module [m]. *)
+val clone_module : llmodule -> llmodule
+
(** [target_triple m] is the target specifier for the module [m], something like
[i686-apple-darwin8]. See the method [llvm::Module::getTargetTriple]. *)
val target_triple: llmodule -> string
@@ -651,7 +671,7 @@ val x86_mmx_type : llcontext -> lltype
val type_by_name : llmodule -> string -> lltype option
-(* {6 Values} *)
+(** {6 Values} *)
(** [type_of v] returns the type of the value [v].
See the method [llvm::Value::getType]. *)
@@ -682,7 +702,7 @@ val string_of_llvalue : llvalue -> string
val replace_all_uses_with : llvalue -> llvalue -> unit
-(* {6 Uses} *)
+(** {6 Uses} *)
(** [use_begin v] returns the first position in the use list for the value [v].
[use_begin] and [use_succ] can e used to iterate over the use list in order.
@@ -714,12 +734,17 @@ val fold_left_uses : ('a -> lluse -> 'a) -> 'a -> llvalue -> 'a
val fold_right_uses : (lluse -> 'a -> 'a) -> llvalue -> 'a -> 'a
-(* {6 Users} *)
+(** {6 Users} *)
(** [operand v i] returns the operand at index [i] for the value [v]. See the
method [llvm::User::getOperand]. *)
val operand : llvalue -> int -> llvalue
+(** [operand_use v i] returns the use of the operand at index [i] for the value [v]. See the
+ method [llvm::User::getOperandUse]. *)
+val operand_use : llvalue -> int -> lluse
+
+
(** [set_operand v i o] sets the operand of the value [v] at the index [i] to
the value [o].
See the method [llvm::User::setOperand]. *)
@@ -837,15 +862,19 @@ val const_int_of_string : lltype -> string -> int -> llvalue
value [n]. See the method [llvm::ConstantFP::get]. *)
val const_float : lltype -> float -> llvalue
+(** [float_of_const c] returns the float value of the [c] constant float.
+ None is returned if this is not an float constant.
+ See the method [llvm::ConstantFP::getDoubleValue].*)
+val float_of_const : llvalue -> float option
+
(** [const_float_of_string ty s] returns the floating point constant of type
[ty] and value [n]. See the method [llvm::ConstantFP::get]. *)
val const_float_of_string : lltype -> string -> llvalue
-
(** {7 Operations on composite constants} *)
(** [const_string c s] returns the constant [i8] array with the values of the
- characters in the string [s] in the context [c]. The array is not
+ characters in the string [s] in the context [c]. The array is not
null-terminated (but see {!const_stringz}). This value can in turn be used
as the initializer for a global variable. See the method
[llvm::ConstantArray::get]. *)
@@ -887,6 +916,14 @@ val const_packed_struct : llcontext -> llvalue array -> llvalue
values [elts]. See the method [llvm::ConstantVector::get]. *)
val const_vector : llvalue array -> llvalue
+(** [string_of_const c] returns [Some str] if [c] is a string constant,
+ or [None] if this is not a string constant. *)
+val string_of_const : llvalue -> string option
+
+(** [const_element c] returns a constant for a specified index's element.
+ See the method ConstantDataSequential::getElementAsConstant. *)
+val const_element : llvalue -> int -> llvalue
+
(** {7 Constant expressions} *)
@@ -1234,6 +1271,14 @@ val visibility : llvalue -> Visibility.t
[v]. See the method [llvm::GlobalValue::setVisibility]. *)
val set_visibility : Visibility.t -> llvalue -> unit
+(** [dll_storage_class g] returns the DLL storage class of the global value [g].
+ See the method [llvm::GlobalValue::getDLLStorageClass]. *)
+val dll_storage_class : llvalue -> DLLStorageClass.t
+
+(** [set_dll_storage_class v g] sets the DLL storage class of the global value [g] to
+ [v]. See the method [llvm::GlobalValue::setDLLStorageClass]. *)
+val set_dll_storage_class : DLLStorageClass.t -> llvalue -> unit
+
(** [alignment g] returns the required alignment of the global value [g].
See the method [llvm::GlobalValue::getAlignment]. *)
val alignment : llvalue -> int
@@ -1687,6 +1732,15 @@ val instr_opcode : llvalue -> Opcode.t
instruction [i]. *)
val icmp_predicate : llvalue -> Icmp.t option
+(** [fcmp_predicate i] returns the [fcmp.t] corresponding to an [fcmp]
+ instruction [i]. *)
+val fcmp_predicate : llvalue -> Fcmp.t option
+
+(** [inst_clone i] returns a copy of instruction [i],
+ The instruction has no parent, and no name.
+ See the method [llvm::Instruction::clone]. *)
+val instr_clone : llvalue -> llvalue
+
(** {7 Operations on call sites} *)
@@ -1741,6 +1795,52 @@ val is_volatile : llvalue -> bool
[llvm::StoreInst::setVolatile]. *)
val set_volatile : bool -> llvalue -> unit
+(** {7 Operations on terminators} *)
+
+(** [is_terminator v] returns true if the instruction [v] is a terminator. *)
+val is_terminator : llvalue -> bool
+
+(** [successor v i] returns the successor at index [i] for the value [v].
+ See the method [llvm::TerminatorInst::getSuccessor]. *)
+val successor : llvalue -> int -> llbasicblock
+
+(** [set_successor v i o] sets the successor of the value [v] at the index [i] to
+ the value [o].
+ See the method [llvm::TerminatorInst::setSuccessor]. *)
+val set_successor : llvalue -> int -> llbasicblock -> unit
+
+(** [num_successors v] returns the number of successors for the value [v].
+ See the method [llvm::TerminatorInst::getNumSuccessors]. *)
+val num_successors : llvalue -> int
+
+(** [successors v] returns the successors of [v]. *)
+val successors : llvalue -> llbasicblock array
+
+(** [iter_successors f v] applies function f to each successor [v] in order. Tail recursive. *)
+val iter_successors : (llbasicblock -> unit) -> llvalue -> unit
+
+(** [fold_successors f v init] is [f (... (f init vN) ...) v1] where [v1,...,vN] are the successors of [v]. Tail recursive. *)
+val fold_successors : (llbasicblock -> 'a -> 'a) -> llvalue -> 'a -> 'a
+
+(** {7 Operations on branches} *)
+
+(** [is_conditional v] returns true if the branch instruction [v] is conditional.
+ See the method [llvm::BranchInst::isConditional]. *)
+val is_conditional : llvalue -> bool
+
+(** [condition v] return the condition of the branch instruction [v].
+ See the method [llvm::BranchInst::getCondition]. *)
+val condition : llvalue -> llvalue
+
+(** [set_condition v c] sets the condition of the branch instruction [v] to the value [c].
+ See the method [llvm::BranchInst::setCondition]. *)
+val set_condition : llvalue -> llvalue -> unit
+
+(** [get_branch c] returns a description of the branch instruction [c]. *)
+val get_branch : llvalue ->
+ [ `Conditional of llvalue * llbasicblock * llbasicblock
+ | `Unconditional of llbasicblock ]
+ option
(** {7 Operations on phi nodes} *)
@@ -2402,7 +2502,7 @@ module MemoryBuffer : sig
path [p]. If the file could not be read, then [IoError msg] is
raised. *)
val of_file : string -> llmemorybuffer
-
+
(** [of_stdin ()] is the memory buffer containing the contents of standard input.
If standard input is empty, then [IoError msg] is raised. *)
val of_stdin : unit -> llmemorybuffer
@@ -2413,7 +2513,7 @@ module MemoryBuffer : sig
(** [as_string mb] is the string containing the contents of memory buffer [mb]. *)
val as_string : llmemorybuffer -> string
-
+
(** Disposes of a memory buffer. *)
val dispose : llmemorybuffer -> unit
end
@@ -2425,13 +2525,13 @@ module PassManager : sig
(** *)
type 'a t
type any = [ `Module | `Function ]
-
+
(** [PassManager.create ()] constructs a new whole-module pass pipeline. This
type of pipeline is suitable for link-time optimization and whole-module
transformations.
See the constructor of [llvm::PassManager]. *)
val create : unit -> [ `Module ] t
-
+
(** [PassManager.create_function m] constructs a new function-by-function
pass pipeline over the module [m]. It does not take ownership of [m].
This type of pipeline is suitable for code generation and JIT compilation
@@ -2450,19 +2550,19 @@ module PassManager : sig
the module, [false] otherwise.
See the [llvm::FunctionPassManager::doInitialization] method. *)
val initialize : [ `Function ] t -> bool
-
+
(** [run_function f fpm] executes all of the function passes scheduled in the
function pass manager [fpm] over the function [f]. Returns [true] if any
of the passes modified [f], [false] otherwise.
See the [llvm::FunctionPassManager::run] method. *)
val run_function : llvalue -> [ `Function ] t -> bool
-
+
(** [finalize fpm] finalizes all of the function passes scheduled in in the
function pass manager [fpm]. Returns [true] if any of the passes
modified the module, [false] otherwise.
See the [llvm::FunctionPassManager::doFinalization] method. *)
val finalize : [ `Function ] t -> bool
-
+
(** Frees the memory of a pass pipeline. For function pipelines, does not free
the module.
See the destructor of [llvm::BasePassManager]. *)
diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c
index d5ebdcd..63c235d 100644
--- a/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/bindings/ocaml/llvm/llvm_ocaml.c
@@ -15,46 +15,33 @@
|* *|
\*===----------------------------------------------------------------------===*/
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
#include "llvm-c/Core.h"
#include "caml/alloc.h"
#include "caml/custom.h"
#include "caml/memory.h"
#include "caml/fail.h"
#include "caml/callback.h"
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/* Can't use the recommended caml_named_value mechanism for backwards
- compatibility reasons. This is largely equivalent. */
-static value llvm_ioerror_exn;
-CAMLprim value llvm_register_core_exns(value IoError) {
- llvm_ioerror_exn = Field(IoError, 0);
- register_global_root(&llvm_ioerror_exn);
+value llvm_string_of_message(char* Message) {
+ value String = caml_copy_string(Message);
+ LLVMDisposeMessage(Message);
- return Val_unit;
+ return String;
}
-static void llvm_raise(value Prototype, char *Message) {
+void llvm_raise(value Prototype, char *Message) {
CAMLparam1(Prototype);
- CAMLlocal1(CamlMessage);
-
- CamlMessage = copy_string(Message);
- LLVMDisposeMessage(Message);
-
- raise_with_arg(Prototype, CamlMessage);
- abort(); /* NOTREACHED */
-#ifdef CAMLnoreturn
- CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
-#endif
+ caml_raise_with_arg(Prototype, llvm_string_of_message(Message));
+ CAMLnoreturn;
}
static value llvm_fatal_error_handler;
static void llvm_fatal_error_trampoline(const char *Reason) {
- callback(llvm_fatal_error_handler, copy_string(Reason));
+ callback(llvm_fatal_error_handler, caml_copy_string(Reason));
}
CAMLprim value llvm_install_fatal_error_handler(value Handler) {
@@ -75,6 +62,17 @@ CAMLprim value llvm_enable_pretty_stacktrace(value Unit) {
return Val_unit;
}
+CAMLprim value llvm_parse_command_line_options(value Overview, value Args) {
+ char *COverview;
+ if (Overview == Val_int(0)) {
+ COverview = NULL;
+ } else {
+ COverview = String_val(Field(Overview, 0));
+ }
+ LLVMParseCommandLineOptions(Wosize_val(Args), (const char* const*) Op_val(Args), COverview);
+ return Val_unit;
+}
+
static value alloc_variant(int tag, void *Value) {
value Iter = alloc_small(1, tag);
Field(Iter, 0) = Val_op(Value);
@@ -157,7 +155,7 @@ CAMLprim value llvm_dispose_module(LLVMModuleRef M) {
/* llmodule -> string */
CAMLprim value llvm_target_triple(LLVMModuleRef M) {
- return copy_string(LLVMGetTarget(M));
+ return caml_copy_string(LLVMGetTarget(M));
}
/* string -> llmodule -> unit */
@@ -168,7 +166,7 @@ CAMLprim value llvm_set_target_triple(value Trip, LLVMModuleRef M) {
/* llmodule -> string */
CAMLprim value llvm_data_layout(LLVMModuleRef M) {
- return copy_string(LLVMGetDataLayout(M));
+ return caml_copy_string(LLVMGetDataLayout(M));
}
/* string -> llmodule -> unit */
@@ -186,22 +184,24 @@ CAMLprim value llvm_dump_module(LLVMModuleRef M) {
/* string -> llmodule -> unit */
CAMLprim value llvm_print_module(value Filename, LLVMModuleRef M) {
char* Message;
- if(LLVMPrintModuleToFile(M, String_val(Filename), &Message)) {
- llvm_raise(llvm_ioerror_exn, Message);
- }
+
+ if(LLVMPrintModuleToFile(M, String_val(Filename), &Message))
+ llvm_raise(*caml_named_value("Llvm.IoError"), Message);
return Val_unit;
}
/* llmodule -> string */
CAMLprim value llvm_string_of_llmodule(LLVMModuleRef M) {
+ CAMLparam0();
+ CAMLlocal1(ModuleStr);
char* ModuleCStr;
- ModuleCStr = LLVMPrintModuleToString(M);
- value ModuleStr = caml_copy_string(ModuleCStr);
+ ModuleCStr = LLVMPrintModuleToString(M);
+ ModuleStr = caml_copy_string(ModuleCStr);
LLVMDisposeMessage(ModuleCStr);
- return ModuleStr;
+ CAMLreturn(ModuleStr);
}
/* llmodule -> string -> unit */
@@ -234,13 +234,15 @@ CAMLprim value llvm_dump_type(LLVMTypeRef Val) {
/* lltype -> string */
CAMLprim value llvm_string_of_lltype(LLVMTypeRef M) {
+ CAMLparam0();
+ CAMLlocal1(TypeStr);
char* TypeCStr;
- TypeCStr = LLVMPrintTypeToString(M);
- value TypeStr = caml_copy_string(TypeCStr);
+ TypeCStr = LLVMPrintTypeToString(M);
+ TypeStr = caml_copy_string(TypeCStr);
LLVMDisposeMessage(TypeCStr);
- return TypeStr;
+ CAMLreturn(TypeStr);
}
/*--... Operations on integer types ........................................--*/
@@ -537,7 +539,7 @@ CAMLprim value llvm_classify_value(LLVMValueRef Val) {
/* llvalue -> string */
CAMLprim value llvm_value_name(LLVMValueRef Val) {
- return copy_string(LLVMGetValueName(Val));
+ return caml_copy_string(LLVMGetValueName(Val));
}
/* string -> llvalue -> unit */
@@ -554,13 +556,15 @@ CAMLprim value llvm_dump_value(LLVMValueRef Val) {
/* llvalue -> string */
CAMLprim value llvm_string_of_llvalue(LLVMValueRef M) {
+ CAMLparam0();
+ CAMLlocal1(ValueStr);
char* ValueCStr;
- ValueCStr = LLVMPrintValueToString(M);
- value ValueStr = caml_copy_string(ValueCStr);
+ ValueCStr = LLVMPrintValueToString(M);
+ ValueStr = caml_copy_string(ValueCStr);
LLVMDisposeMessage(ValueCStr);
- return ValueStr;
+ CAMLreturn(ValueStr);
}
/* llvalue -> llvalue -> unit */
@@ -577,6 +581,11 @@ CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value I) {
return LLVMGetOperand(V, Int_val(I));
}
+/* llvalue -> int -> lluse */
+CAMLprim LLVMUseRef llvm_operand_use(LLVMValueRef V, value I) {
+ return LLVMGetOperandUse(V, Int_val(I));
+}
+
/* llvalue -> int -> llvalue -> unit */
CAMLprim value llvm_set_operand(LLVMValueRef U, value I, LLVMValueRef V) {
LLVMSetOperand(U, Int_val(I), V);
@@ -695,7 +704,7 @@ CAMLprim value llvm_append_namedmd(LLVMModuleRef M, value Name, LLVMValueRef Val
/* lltype -> int -> llvalue */
CAMLprim LLVMValueRef llvm_const_int(LLVMTypeRef IntTy, value N) {
- return LLVMConstInt(IntTy, (long long) Int_val(N), 1);
+ return LLVMConstInt(IntTy, (long long) Long_val(N), 1);
}
/* lltype -> Int64.t -> bool -> llvalue */
@@ -729,6 +738,28 @@ CAMLprim LLVMValueRef llvm_const_float(LLVMTypeRef RealTy, value N) {
return LLVMConstReal(RealTy, Double_val(N));
}
+
+/* llvalue -> float */
+CAMLprim value llvm_float_of_const(LLVMValueRef Const)
+{
+ CAMLparam0();
+ CAMLlocal1(Option);
+ LLVMBool LosesInfo;
+ double Result;
+
+ if (LLVMIsAConstantFP(Const)) {
+ Result = LLVMConstRealGetDouble(Const, &LosesInfo);
+ if (LosesInfo)
+ CAMLreturn(Val_int(0));
+
+ Option = alloc(1, 0);
+ Field(Option, 0) = caml_copy_double(Result);
+ CAMLreturn(Option);
+ }
+
+ CAMLreturn(Val_int(0));
+}
+
/* lltype -> string -> llvalue */
CAMLprim LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value S) {
return LLVMConstRealOfStringAndSize(RealTy, String_val(S),
@@ -782,6 +813,31 @@ CAMLprim LLVMValueRef llvm_const_vector(value ElementVals) {
Wosize_val(ElementVals));
}
+/* llvalue -> string option */
+CAMLprim value llvm_string_of_const(LLVMValueRef Const) {
+ const char *S;
+ size_t Len;
+ CAMLparam0();
+ CAMLlocal2(Option, Str);
+
+ if(LLVMIsAConstantDataSequential(Const) && LLVMIsConstantString(Const)) {
+ S = LLVMGetAsString(Const, &Len);
+ Str = caml_alloc_string(Len);
+ memcpy(String_val(Str), S, Len);
+
+ Option = alloc(1, 0);
+ Field(Option, 0) = Str;
+ CAMLreturn(Option);
+ } else {
+ CAMLreturn(Val_int(0));
+ }
+}
+
+/* llvalue -> int -> llvalue */
+CAMLprim LLVMValueRef llvm_const_element(LLVMValueRef Const, value N) {
+ return LLVMGetElementAsConstant(Const, Int_val(N));
+}
+
/*--... Constant expressions ...............................................--*/
/* Icmp.t -> llvalue -> llvalue -> llvalue */
@@ -881,7 +937,7 @@ CAMLprim value llvm_set_linkage(value Linkage, LLVMValueRef Global) {
/* llvalue -> string */
CAMLprim value llvm_section(LLVMValueRef Global) {
- return copy_string(LLVMGetSection(Global));
+ return caml_copy_string(LLVMGetSection(Global));
}
/* string -> llvalue -> unit */
@@ -901,6 +957,17 @@ CAMLprim value llvm_set_visibility(value Viz, LLVMValueRef Global) {
return Val_unit;
}
+/* llvalue -> DLLStorageClass.t */
+CAMLprim value llvm_dll_storage_class(LLVMValueRef Global) {
+ return Val_int(LLVMGetDLLStorageClass(Global));
+}
+
+/* DLLStorageClass.t -> llvalue -> unit */
+CAMLprim value llvm_set_dll_storage_class(value Viz, LLVMValueRef Global) {
+ LLVMSetDLLStorageClass(Global, Int_val(Viz));
+ return Val_unit;
+}
+
/* llvalue -> int */
CAMLprim value llvm_alignment(LLVMValueRef Global) {
return Val_int(LLVMGetAlignment(Global));
@@ -1151,10 +1218,10 @@ CAMLprim value llvm_gc(LLVMValueRef Fn) {
const char *GC;
CAMLparam0();
CAMLlocal2(Name, Option);
-
+
if ((GC = LLVMGetGC(Fn))) {
- Name = copy_string(GC);
-
+ Name = caml_copy_string(GC);
+
Option = alloc(1, 0);
Field(Option, 0) = Name;
CAMLreturn(Option);
@@ -1328,6 +1395,25 @@ CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) {
CAMLreturn(Val_int(0));
}
+/* llvalue -> FCmp.t option */
+CAMLprim value llvm_instr_fcmp_predicate(LLVMValueRef Val) {
+ CAMLparam0();
+ int x = LLVMGetFCmpPredicate(Val);
+ if (x) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = Val_int(x - LLVMRealPredicateFalse);
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* llvalue -> llvalue */
+CAMLprim LLVMValueRef llvm_instr_clone(LLVMValueRef Inst) {
+ if (!LLVMIsAInstruction(Inst))
+ failwith("Not an instruction");
+ return LLVMInstructionClone(Inst);
+}
+
/*--... Operations on call sites ...........................................--*/
@@ -1386,6 +1472,43 @@ CAMLprim value llvm_set_volatile(value IsVolatile,
return Val_unit;
}
+
+/*--.. Operations on terminators ...........................................--*/
+
+/* llvalue -> int -> llbasicblock */
+CAMLprim LLVMBasicBlockRef llvm_successor(LLVMValueRef V, value I) {
+ return LLVMGetSuccessor(V, Int_val(I));
+}
+
+/* llvalue -> int -> llvalue -> unit */
+CAMLprim value llvm_set_successor(LLVMValueRef U, value I, LLVMBasicBlockRef B) {
+ LLVMSetSuccessor(U, Int_val(I), B);
+ return Val_unit;
+}
+
+/* llvalue -> int */
+CAMLprim value llvm_num_successors(LLVMValueRef V) {
+ return Val_int(LLVMGetNumSuccessors(V));
+}
+
+/*--.. Operations on branch ................................................--*/
+
+/* llvalue -> llvalue */
+CAMLprim LLVMValueRef llvm_condition(LLVMValueRef V) {
+ return LLVMGetCondition(V);
+}
+
+/* llvalue -> llvalue -> unit */
+CAMLprim value llvm_set_condition(LLVMValueRef B, LLVMValueRef C) {
+ LLVMSetCondition(B, C);
+ return Val_unit;
+}
+
+/* llvalue -> bool */
+CAMLprim value llvm_is_conditional(LLVMValueRef V) {
+ return Val_bool(LLVMIsConditional(V));
+}
+
/*--... Operations on phi nodes ............................................--*/
/* (llvalue * llbasicblock) -> llvalue -> unit */
@@ -1402,20 +1525,20 @@ CAMLprim value llvm_incoming(LLVMValueRef PhiNode) {
unsigned I;
CAMLparam0();
CAMLlocal3(Hd, Tl, Tmp);
-
+
/* Build a tuple list of them. */
Tl = Val_int(0);
for (I = LLVMCountIncoming(PhiNode); I != 0; ) {
Hd = alloc(2, 0);
Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I));
Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I));
-
+
Tmp = alloc(2, 0);
Store_field(Tmp, 0, Hd);
Store_field(Tmp, 1, Tl);
Tl = Tmp;
}
-
+
CAMLreturn(Tl);
}
@@ -1434,15 +1557,13 @@ static void llvm_finalize_builder(value B) {
}
static struct custom_operations builder_ops = {
- (char *) "LLVMIRBuilder",
+ (char *) "Llvm.llbuilder",
llvm_finalize_builder,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
- custom_deserialize_default
-#ifdef custom_compare_ext_default
- , custom_compare_ext_default
-#endif
+ custom_deserialize_default,
+ custom_compare_ext_default
};
static value alloc_builder(LLVMBuilderRef B) {
@@ -1472,7 +1593,7 @@ CAMLprim value llvm_position_builder(value Pos, value B) {
CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) {
LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
if (!InsertBlock)
- raise_not_found();
+ caml_raise_not_found();
return InsertBlock;
}
@@ -2048,9 +2169,9 @@ CAMLprim LLVMValueRef llvm_build_fcmp(value Pred,
CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
value Hd, Tl;
LLVMValueRef FirstValue, PhiNode;
-
+
assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!");
-
+
Hd = Field(Incoming, 0);
FirstValue = (LLVMValueRef) Field(Hd, 0);
PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue),
@@ -2061,7 +2182,7 @@ CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0),
(LLVMBasicBlockRef*) &Field(Hd, 1), 1);
}
-
+
return PhiNode;
}
@@ -2097,7 +2218,7 @@ CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec,
LLVMValueRef Element,
LLVMValueRef Idx,
value Name, value B) {
- return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
+ return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
String_val(Name));
}
@@ -2149,11 +2270,11 @@ CAMLprim value llvm_memorybuffer_of_file(value Path) {
CAMLparam1(Path);
char *Message;
LLVMMemoryBufferRef MemBuf;
-
+
if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path),
&MemBuf, &Message))
- llvm_raise(llvm_ioerror_exn, Message);
-
+ llvm_raise(*caml_named_value("Llvm.IoError"), Message);
+
CAMLreturn((value) MemBuf);
}
@@ -2162,22 +2283,23 @@ CAMLprim value llvm_memorybuffer_of_file(value Path) {
CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
char *Message;
LLVMMemoryBufferRef MemBuf;
-
+
if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
- llvm_raise(llvm_ioerror_exn, Message);
-
+ llvm_raise(*caml_named_value("Llvm.IoError"), Message);
+
return MemBuf;
}
/* ?name:string -> string -> llmemorybuffer */
CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_string(value Name, value String) {
+ LLVMMemoryBufferRef MemBuf;
const char *NameCStr;
+
if(Name == Val_int(0))
NameCStr = "";
else
NameCStr = String_val(Field(Name, 0));
- LLVMMemoryBufferRef MemBuf;
MemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(
String_val(String), caml_string_length(String), NameCStr);
diff --git a/bindings/ocaml/target/llvm_target.ml b/bindings/ocaml/target/llvm_target.ml
index 974bd49..bd7388e 100644
--- a/bindings/ocaml/target/llvm_target.ml
+++ b/bindings/ocaml/target/llvm_target.ml
@@ -47,8 +47,7 @@ end
exception Error of string
-external register_exns : exn -> unit = "llvm_register_target_exns"
-let _ = register_exns (Error "")
+let () = Callback.register_exception "Llvm_target.Error" (Error "")
module DataLayout = struct
type t
@@ -127,6 +126,8 @@ module TargetMachine = struct
= "llvm_targetmachine_features"
external data_layout : t -> DataLayout.t
= "llvm_targetmachine_data_layout"
+ external add_analysis_passes : [< Llvm.PassManager.any ] Llvm.PassManager.t -> t -> unit
+ = "llvm_targetmachine_add_analysis_passes"
external set_verbose_asm : bool -> t -> unit
= "llvm_targetmachine_set_verbose_asm"
external emit_to_file : Llvm.llmodule -> CodeGenFileType.t -> string ->
diff --git a/bindings/ocaml/target/llvm_target.mli b/bindings/ocaml/target/llvm_target.mli
index 4f5e717..676bc61 100644
--- a/bindings/ocaml/target/llvm_target.mli
+++ b/bindings/ocaml/target/llvm_target.mli
@@ -67,7 +67,7 @@ module DataLayout : sig
See the method [llvm::DataLayout::getStringRepresentation]. *)
val as_string : t -> string
- (** [add_to_pass_manager dl pm] adds the target data [dl] to
+ (** [add_to_pass_manager pm dl] adds the data layout [dl] to
the pass manager [pm].
See the method [llvm::PassManagerBase::add]. *)
val add_to_pass_manager : [<Llvm.PassManager.any] Llvm.PassManager.t ->
@@ -207,6 +207,10 @@ module TargetMachine : sig
(** Returns the data layout of this target machine. *)
val data_layout : t -> DataLayout.t
+ (** Adds the target-specific analysis passes to the pass manager.
+ See [llvm::TargetMachine::addAnalysisPasses]. *)
+ val add_analysis_passes : [< Llvm.PassManager.any ] Llvm.PassManager.t -> t -> unit
+
(** Sets the assembly verbosity of this target machine.
See [llvm::TargetMachine::setAsmVerbosity]. *)
val set_verbose_asm : bool -> t -> unit
diff --git a/bindings/ocaml/target/target_ocaml.c b/bindings/ocaml/target/target_ocaml.c
index 74e8185..8f77cb4 100644
--- a/bindings/ocaml/target/target_ocaml.c
+++ b/bindings/ocaml/target/target_ocaml.c
@@ -21,37 +21,10 @@
#include "caml/fail.h"
#include "caml/memory.h"
#include "caml/custom.h"
+#include "caml/callback.h"
-/*===---- Exceptions ------------------------------------------------------===*/
-
-static value llvm_target_error_exn;
-
-CAMLprim value llvm_register_target_exns(value Error) {
- llvm_target_error_exn = Field(Error, 0);
- register_global_root(&llvm_target_error_exn);
- return Val_unit;
-}
-
-static void llvm_raise(value Prototype, char *Message) {
- CAMLparam1(Prototype);
- CAMLlocal1(CamlMessage);
-
- CamlMessage = copy_string(Message);
- LLVMDisposeMessage(Message);
-
- raise_with_arg(Prototype, CamlMessage);
- abort(); /* NOTREACHED */
-#ifdef CAMLnoreturn
- CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
-#endif
-}
-
-static value llvm_string_of_message(char* Message) {
- value String = caml_copy_string(Message);
- LLVMDisposeMessage(Message);
-
- return String;
-}
+void llvm_raise(value Prototype, char *Message);
+value llvm_string_of_message(char* Message);
/*===---- Data Layout -----------------------------------------------------===*/
@@ -62,15 +35,13 @@ static void llvm_finalize_data_layout(value DataLayout) {
}
static struct custom_operations llvm_data_layout_ops = {
- (char *) "LLVMDataLayout",
+ (char *) "Llvm_target.DataLayout.t",
llvm_finalize_data_layout,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
- custom_deserialize_default
-#ifdef custom_compare_ext_default
- , custom_compare_ext_default
-#endif
+ custom_deserialize_default,
+ custom_compare_ext_default
};
value llvm_alloc_data_layout(LLVMTargetDataRef DataLayout) {
@@ -219,7 +190,7 @@ CAMLprim LLVMTargetRef llvm_target_by_triple(value Triple) {
char *Error;
if(LLVMGetTargetFromTriple(String_val(Triple), &T, &Error))
- llvm_raise(llvm_target_error_exn, Error);
+ llvm_raise(*caml_named_value("Llvm_target.Error"), Error);
return T;
}
@@ -258,15 +229,13 @@ static void llvm_finalize_target_machine(value Machine) {
}
static struct custom_operations llvm_target_machine_ops = {
- (char *) "LLVMTargetMachine",
+ (char *) "Llvm_target.TargetMachine.t",
llvm_finalize_target_machine,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
- custom_deserialize_default
-#ifdef custom_compare_ext_default
- , custom_compare_ext_default
-#endif
+ custom_deserialize_default,
+ custom_compare_ext_default
};
static value llvm_alloc_targetmachine(LLVMTargetMachineRef Machine) {
@@ -337,6 +306,7 @@ CAMLprim value llvm_targetmachine_features(value Machine) {
CAMLprim value llvm_targetmachine_data_layout(value Machine) {
CAMLparam1(Machine);
CAMLlocal1(DataLayout);
+ char *TargetDataCStr;
/* LLVMGetTargetMachineData returns a pointer owned by the TargetMachine,
so it is impossible to wrap it with llvm_alloc_target_data, which assumes
@@ -344,7 +314,6 @@ CAMLprim value llvm_targetmachine_data_layout(value Machine) {
LLVMTargetDataRef OrigDataLayout;
OrigDataLayout = LLVMGetTargetMachineData(TargetMachine_val(Machine));
- char* TargetDataCStr;
TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
LLVMDisposeMessage(TargetDataCStr);
@@ -361,12 +330,12 @@ CAMLprim value llvm_targetmachine_set_verbose_asm(value Verb, value Machine) {
/* Llvm.llmodule -> CodeGenFileType.t -> string -> TargetMachine.t -> unit */
CAMLprim value llvm_targetmachine_emit_to_file(LLVMModuleRef Module,
value FileType, value FileName, value Machine) {
- char* ErrorMessage;
+ char *ErrorMessage;
if(LLVMTargetMachineEmitToFile(TargetMachine_val(Machine), Module,
String_val(FileName), Int_val(FileType),
&ErrorMessage)) {
- llvm_raise(llvm_target_error_exn, ErrorMessage);
+ llvm_raise(*caml_named_value("Llvm_target.Error"), ErrorMessage);
}
return Val_unit;
@@ -377,14 +346,21 @@ CAMLprim value llvm_targetmachine_emit_to_file(LLVMModuleRef Module,
CAMLprim LLVMMemoryBufferRef llvm_targetmachine_emit_to_memory_buffer(
LLVMModuleRef Module, value FileType,
value Machine) {
- char* ErrorMessage;
+ char *ErrorMessage;
LLVMMemoryBufferRef Buffer;
if(LLVMTargetMachineEmitToMemoryBuffer(TargetMachine_val(Machine), Module,
Int_val(FileType), &ErrorMessage,
&Buffer)) {
- llvm_raise(llvm_target_error_exn, ErrorMessage);
+ llvm_raise(*caml_named_value("Llvm_target.Error"), ErrorMessage);
}
return Buffer;
}
+
+/* TargetMachine.t -> Llvm.PassManager.t -> unit */
+CAMLprim value llvm_targetmachine_add_analysis_passes(LLVMPassManagerRef PM,
+ value Machine) {
+ LLVMAddAnalysisPasses(TargetMachine_val(Machine), PM);
+ return Val_unit;
+}
diff --git a/bindings/ocaml/transforms/Makefile b/bindings/ocaml/transforms/Makefile
index 92c8396..f3637a6 100644
--- a/bindings/ocaml/transforms/Makefile
+++ b/bindings/ocaml/transforms/Makefile
@@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL := ../../..
-DIRS = scalar ipo vectorize passmgr_builder
+DIRS = scalar_opts ipo vectorize passmgr_builder
ocamldoc:
$(Verb) for i in $(DIRS) ; do \
diff --git a/bindings/ocaml/transforms/ipo/Makefile b/bindings/ocaml/transforms/ipo/Makefile
index ed67a7c..f54bc4e 100644
--- a/bindings/ocaml/transforms/ipo/Makefile
+++ b/bindings/ocaml/transforms/ipo/Makefile
@@ -1,4 +1,4 @@
-##===- bindings/ocaml/transforms/scalar/Makefile -----------*- Makefile -*-===##
+##===- bindings/ocaml/transforms/ipo/Makefile --------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -7,7 +7,7 @@
#
##===----------------------------------------------------------------------===##
#
-# This is the makefile for the Objective Caml Llvm_scalar_opts interface.
+# This is the makefile for the Objective Caml Llvm_ipo interface.
#
##===----------------------------------------------------------------------===##
diff --git a/bindings/ocaml/transforms/ipo/ipo_ocaml.c b/bindings/ocaml/transforms/ipo/ipo_ocaml.c
index 4ad8afb..9d8fb1e 100644
--- a/bindings/ocaml/transforms/ipo/ipo_ocaml.c
+++ b/bindings/ocaml/transforms/ipo/ipo_ocaml.c
@@ -56,12 +56,6 @@ CAMLprim value llvm_add_always_inliner(LLVMPassManagerRef PM) {
}
/* [`Module] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_always_inliner_pass(LLVMPassManagerRef PM) {
- LLVMAddAlwaysInlinerPass(PM);
- return Val_unit;
-}
-
-/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_global_dce(LLVMPassManagerRef PM) {
LLVMAddGlobalDCEPass(PM);
return Val_unit;
@@ -74,7 +68,7 @@ CAMLprim value llvm_add_global_optimizer(LLVMPassManagerRef PM) {
}
/* [`Module] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_ipc_propagation(LLVMPassManagerRef PM) {
+CAMLprim value llvm_add_ip_constant_propagation(LLVMPassManagerRef PM) {
LLVMAddIPConstantPropagationPass(PM);
return Val_unit;
}
@@ -91,7 +85,7 @@ CAMLprim value llvm_add_ipsccp(LLVMPassManagerRef PM) {
return Val_unit;
}
-/* [`Module] Llvm.PassManager.t -> bool -> unit */
+/* [`Module] Llvm.PassManager.t -> all_but_main:bool -> unit */
CAMLprim value llvm_add_internalize(LLVMPassManagerRef PM, value AllButMain) {
LLVMAddInternalizePass(PM, Bool_val(AllButMain));
return Val_unit;
diff --git a/bindings/ocaml/transforms/ipo/llvm_ipo.ml b/bindings/ocaml/transforms/ipo/llvm_ipo.ml
index 93f564a..1af7d67 100644
--- a/bindings/ocaml/transforms/ipo/llvm_ipo.ml
+++ b/bindings/ocaml/transforms/ipo/llvm_ipo.ml
@@ -7,31 +7,45 @@
*
*===----------------------------------------------------------------------===*)
-external add_argument_promotion : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_argument_promotion"
-external add_constant_merge : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_constant_merge"
-external add_dead_arg_elimination :
- [ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_dead_arg_elimination"
-external add_function_attrs : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_function_attrs"
-external add_function_inlining : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_function_inlining"
-external add_always_inliner : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_always_inliner"
-external add_global_dce : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_global_dce"
-external add_global_optimizer : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_global_optimizer"
-external add_ipc_propagation : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_ipc_propagation"
-external add_prune_eh : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_prune_eh"
-external add_ipsccp : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_ipsccp"
-external add_internalize : [ | `Module ] Llvm.PassManager.t -> bool -> unit =
- "llvm_add_internalize"
-external add_strip_dead_prototypes :
- [ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_strip_dead_prototypes"
-external add_strip_symbols : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_strip_symbols"
+external add_argument_promotion
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_argument_promotion"
+external add_constant_merge
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_constant_merge"
+external add_dead_arg_elimination
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_dead_arg_elimination"
+external add_function_attrs
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_function_attrs"
+external add_function_inlining
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_function_inlining"
+external add_always_inliner
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_always_inliner"
+external add_global_dce
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_global_dce"
+external add_global_optimizer
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_global_optimizer"
+external add_ipc_propagation
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_ip_constant_propagation"
+external add_prune_eh
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_prune_eh"
+external add_ipsccp
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_ipsccp"
+external add_internalize
+ : [ `Module ] Llvm.PassManager.t -> all_but_main:bool -> unit
+ = "llvm_add_internalize"
+external add_strip_dead_prototypes
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_strip_dead_prototypes"
+external add_strip_symbols
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_strip_symbols"
diff --git a/bindings/ocaml/transforms/ipo/llvm_ipo.mli b/bindings/ocaml/transforms/ipo/llvm_ipo.mli
index 1944c30..09a4860 100644
--- a/bindings/ocaml/transforms/ipo/llvm_ipo.mli
+++ b/bindings/ocaml/transforms/ipo/llvm_ipo.mli
@@ -12,58 +12,72 @@
This interface provides an OCaml API for LLVM interprocedural optimizations, the
classes in the [LLVMIPO] library. *)
-(** See llvm::createAddArgumentPromotionPass *)
-external add_argument_promotion : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_argument_promotion"
-
-(** See llvm::createConstantMergePass function. *)
-external add_constant_merge : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_constant_merge"
-
-(** See llvm::createDeadArgEliminationPass function. *)
-external add_dead_arg_elimination :
- [ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_dead_arg_elimination"
-
-(** See llvm::createFunctionAttrsPass function. *)
-external add_function_attrs : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_function_attrs"
-
-(** See llvm::createFunctionInliningPass function. *)
-external add_function_inlining : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_function_inlining"
-
-(** See llvm::createAlwaysInlinerPass function. *)
-external add_always_inliner : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_always_inliner"
-
-(** See llvm::createGlobalDCEPass function. *)
-external add_global_dce : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_global_dce"
-
-(** See llvm::createGlobalOptimizerPass function. *)
-external add_global_optimizer : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_global_optimizer"
-
-(** See llvm::createIPConstantPropagationPass function. *)
-external add_ipc_propagation : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_ipc_propagation"
-
-(** See llvm::createPruneEHPass function. *)
-external add_prune_eh : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_prune_eh"
-
-(** See llvm::createIPSCCPPass function. *)
-external add_ipsccp : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_ipsccp"
-
-(** See llvm::createInternalizePass function. *)
-external add_internalize : [ | `Module ] Llvm.PassManager.t -> bool -> unit =
- "llvm_add_internalize"
-
-(** See llvm::createStripDeadPrototypesPass function. *)
-external add_strip_dead_prototypes :
- [ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_strip_dead_prototypes"
-
-(** See llvm::createStripSymbolsPass function. *)
-external add_strip_symbols : [ | `Module ] Llvm.PassManager.t -> unit =
- "llvm_add_strip_symbols"
+(** See the [llvm::createAddArgumentPromotionPass] function. *)
+external add_argument_promotion
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_argument_promotion"
+
+(** See the [llvm::createConstantMergePass] function. *)
+external add_constant_merge
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_constant_merge"
+
+(** See the [llvm::createDeadArgEliminationPass] function. *)
+external add_dead_arg_elimination
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_dead_arg_elimination"
+
+(** See the [llvm::createFunctionAttrsPass] function. *)
+external add_function_attrs
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_function_attrs"
+
+(** See the [llvm::createFunctionInliningPass] function. *)
+external add_function_inlining
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_function_inlining"
+
+(** See the [llvm::createAlwaysInlinerPass] function. *)
+external add_always_inliner
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_always_inliner"
+
+(** See the [llvm::createGlobalDCEPass] function. *)
+external add_global_dce
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_global_dce"
+
+(** See the [llvm::createGlobalOptimizerPass] function. *)
+external add_global_optimizer
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_global_optimizer"
+
+(** See the [llvm::createIPConstantPropagationPass] function. *)
+external add_ipc_propagation
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_ip_constant_propagation"
+
+(** See the [llvm::createPruneEHPass] function. *)
+external add_prune_eh
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_prune_eh"
+
+(** See the [llvm::createIPSCCPPass] function. *)
+external add_ipsccp
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_ipsccp"
+
+(** See the [llvm::createInternalizePass] function. *)
+external add_internalize
+ : [ `Module ] Llvm.PassManager.t -> all_but_main:bool -> unit
+ = "llvm_add_internalize"
+
+(** See the [llvm::createStripDeadPrototypesPass] function. *)
+external add_strip_dead_prototypes
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_strip_dead_prototypes"
+
+(** See the [llvm::createStripSymbolsPass] function. *)
+external add_strip_symbols
+ : [ `Module ] Llvm.PassManager.t -> unit
+ = "llvm_add_strip_symbols"
diff --git a/bindings/ocaml/transforms/passmgr_builder/llvm_passmgr_builder.mli b/bindings/ocaml/transforms/passmgr_builder/llvm_passmgr_builder.mli
index 66b0981..ce162b1 100644
--- a/bindings/ocaml/transforms/passmgr_builder/llvm_passmgr_builder.mli
+++ b/bindings/ocaml/transforms/passmgr_builder/llvm_passmgr_builder.mli
@@ -14,41 +14,41 @@
type t
-(** See [llvm::PassManagerBuilder]. *)
+(** See the [llvm::PassManagerBuilder] function. *)
external create : unit -> t
= "llvm_pmbuilder_create"
-(** See [llvm::PassManagerBuilder::OptLevel]. *)
+(** See the [llvm::PassManagerBuilder::OptLevel] function. *)
external set_opt_level : int -> t -> unit
= "llvm_pmbuilder_set_opt_level"
-(** See [llvm::PassManagerBuilder::SizeLevel]. *)
+(** See the [llvm::PassManagerBuilder::SizeLevel] function. *)
external set_size_level : int -> t -> unit
= "llvm_pmbuilder_set_size_level"
-(** See [llvm::PassManagerBuilder::DisableUnitAtATime]. *)
+(** See the [llvm::PassManagerBuilder::DisableUnitAtATime] function. *)
external set_disable_unit_at_a_time : bool -> t -> unit
= "llvm_pmbuilder_set_disable_unit_at_a_time"
-(** See [llvm::PassManagerBuilder::DisableUnrollLoops]. *)
+(** See the [llvm::PassManagerBuilder::DisableUnrollLoops] function. *)
external set_disable_unroll_loops : bool -> t -> unit
= "llvm_pmbuilder_set_disable_unroll_loops"
-(** See [llvm::PassManagerBuilder::Inliner]. *)
+(** See the [llvm::PassManagerBuilder::Inliner] function. *)
external use_inliner_with_threshold : int -> t -> unit
= "llvm_pmbuilder_use_inliner_with_threshold"
-(** See [llvm::PassManagerBuilder::populateFunctionPassManager]. *)
+(** See the [llvm::PassManagerBuilder::populateFunctionPassManager] function. *)
external populate_function_pass_manager
: [ `Function ] Llvm.PassManager.t -> t -> unit
= "llvm_pmbuilder_populate_function_pass_manager"
-(** See [llvm::PassManagerBuilder::populateModulePassManager]. *)
+(** See the [llvm::PassManagerBuilder::populateModulePassManager] function. *)
external populate_module_pass_manager
: [ `Module ] Llvm.PassManager.t -> t -> unit
= "llvm_pmbuilder_populate_module_pass_manager"
-(** See [llvm::PassManagerBuilder::populateLTOPassManager]. *)
+(** See the [llvm::PassManagerBuilder::populateLTOPassManager] function. *)
external populate_lto_pass_manager
: [ `Module ] Llvm.PassManager.t -> internalize:bool -> run_inliner:bool -> t -> unit
- = "llvm_pmbuilder_populate_lto_pass_manager" \ No newline at end of file
+ = "llvm_pmbuilder_populate_lto_pass_manager"
diff --git a/bindings/ocaml/transforms/passmgr_builder/passmgr_builder_ocaml.c b/bindings/ocaml/transforms/passmgr_builder/passmgr_builder_ocaml.c
index a707856..a43863c 100644
--- a/bindings/ocaml/transforms/passmgr_builder/passmgr_builder_ocaml.c
+++ b/bindings/ocaml/transforms/passmgr_builder/passmgr_builder_ocaml.c
@@ -27,15 +27,13 @@ static void llvm_finalize_pmbuilder(value PMB) {
}
static struct custom_operations pmbuilder_ops = {
- (char *) "LLVMPassManagerBuilder",
+ (char *) "Llvm_passmgr_builder.t",
llvm_finalize_pmbuilder,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
- custom_deserialize_default
-#ifdef custom_compare_ext_default
- , custom_compare_ext_default
-#endif
+ custom_deserialize_default,
+ custom_compare_ext_default
};
static value alloc_pmbuilder(LLVMPassManagerBuilderRef Ref) {
diff --git a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml
deleted file mode 100644
index 958939d..0000000
--- a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml
+++ /dev/null
@@ -1,114 +0,0 @@
-(*===-- llvm_scalar_opts.ml - LLVM OCaml Interface -------------*- OCaml -*-===*
- *
- * The LLVM Compiler Infrastructure
- *
- * This file is distributed under the University of Illinois Open Source
- * License. See LICENSE.TXT for details.
- *
- *===----------------------------------------------------------------------===*)
-
-external add_constant_propagation : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_constant_propagation"
-external add_sccp : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_sccp"
-external add_dead_store_elimination : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_dead_store_elimination"
-external add_aggressive_dce : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_aggressive_dce"
-external
-add_scalar_repl_aggregation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_scalar_repl_aggregation"
-
-external
-add_scalar_repl_aggregation_ssa : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_scalar_repl_aggregation_ssa"
-
-external
-add_scalar_repl_aggregation_with_threshold : int -> [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_scalar_repl_aggregation_with_threshold"
-external add_ind_var_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_ind_var_simplification"
-external
-add_instruction_combination : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_instruction_combination"
-external add_licm : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_licm"
-external add_loop_unswitch : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_unswitch"
-external add_loop_unroll : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_unroll"
-external add_loop_rotation : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_rotation"
-external
-add_memory_to_register_promotion : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_memory_to_register_promotion"
-external
-add_memory_to_register_demotion : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_memory_to_register_demotion"
-external add_reassociation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_reassociation"
-external add_jump_threading : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_jump_threading"
-external add_cfg_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_cfg_simplification"
-external
-add_tail_call_elimination : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_tail_call_elimination"
-external add_gvn : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_gvn"
-external add_memcpy_opt : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_memcpy_opt"
-external add_loop_deletion : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_deletion"
-
-external add_loop_idiom : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_idiom"
-
-external
-add_lib_call_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_lib_call_simplification"
-
-external
-add_verifier : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_verifier"
-
-external
-add_correlated_value_propagation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_correlated_value_propagation"
-
-external
-add_early_cse : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_early_cse"
-
-external
-add_lower_expect_intrinsic : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_lower_expect_intrinsic"
-
-external
-add_type_based_alias_analysis : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_type_based_alias_analysis"
-
-external
-add_basic_alias_analysis : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_basic_alias_analysis"
-
-external
-add_partially_inline_lib_calls : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_partially_inline_lib_calls"
diff --git a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli
deleted file mode 100644
index ab6fa4a..0000000
--- a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli
+++ /dev/null
@@ -1,168 +0,0 @@
-(*===-- llvm_scalar_opts.mli - LLVM OCaml Interface ------------*- OCaml -*-===*
- *
- * The LLVM Compiler Infrastructure
- *
- * This file is distributed under the University of Illinois Open Source
- * License. See LICENSE.TXT for details.
- *
- *===----------------------------------------------------------------------===*)
-
-(** Scalar Transforms.
-
- This interface provides an OCaml API for LLVM scalar transforms, the
- classes in the [LLVMScalarOpts] library. *)
-
-(** See the [llvm::createConstantPropagationPass] function. *)
-external add_constant_propagation : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_constant_propagation"
-
-(** See the [llvm::createSCCPPass] function. *)
-external add_sccp : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_sccp"
-
-(** See [llvm::createDeadStoreEliminationPass] function. *)
-external add_dead_store_elimination : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_dead_store_elimination"
-
-(** See The [llvm::createAggressiveDCEPass] function. *)
-external add_aggressive_dce : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_aggressive_dce"
-
-(** See the [llvm::createScalarReplAggregatesPass] function. *)
-external
-add_scalar_repl_aggregation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_scalar_repl_aggregation"
-
-(** See the [llvm::createScalarReplAggregatesPassSSA] function. *)
-external
-add_scalar_repl_aggregation_ssa : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_scalar_repl_aggregation_ssa"
-
-(** See the [llvm::createScalarReplAggregatesWithThreshold] function. *)
-external
-add_scalar_repl_aggregation_with_threshold : int -> [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_scalar_repl_aggregation_with_threshold"
-
-(** See the [llvm::createIndVarSimplifyPass] function. *)
-external add_ind_var_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_ind_var_simplification"
-
-(** See the [llvm::createInstructionCombiningPass] function. *)
-external
-add_instruction_combination : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_instruction_combination"
-
-(** See the [llvm::createLICMPass] function. *)
-external add_licm : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_licm"
-
-(** See the [llvm::createLoopUnswitchPass] function. *)
-external add_loop_unswitch : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_unswitch"
-
-(** See the [llvm::createLoopUnrollPass] function. *)
-external add_loop_unroll : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_unroll"
-
-(** See the [llvm::createLoopRotatePass] function. *)
-external add_loop_rotation : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_rotation"
-
-(** See the [llvm::createPromoteMemoryToRegisterPass] function. *)
-external
-add_memory_to_register_promotion : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_memory_to_register_promotion"
-
-(** See the [llvm::createDemoteMemoryToRegisterPass] function. *)
-external
-add_memory_to_register_demotion : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_memory_to_register_demotion"
-
-(** See the [llvm::createReassociatePass] function. *)
-external add_reassociation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_reassociation"
-
-(** See the [llvm::createJumpThreadingPass] function. *)
-external add_jump_threading : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_jump_threading"
-
-(** See the [llvm::createCFGSimplificationPass] function. *)
-external add_cfg_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_cfg_simplification"
-
-(** See the [llvm::createTailCallEliminationPass] function. *)
-external
-add_tail_call_elimination : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_tail_call_elimination"
-
-(** See the [llvm::createGVNPass] function. *)
-external add_gvn : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_gvn"
-
-(** See the [llvm::createMemCpyOptPass] function. *)
-external add_memcpy_opt : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_memcpy_opt"
-
-(** See the [llvm::createLoopDeletionPass] function. *)
-external add_loop_deletion : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_deletion"
-
-external add_loop_idiom : [<Llvm.PassManager.any] Llvm.PassManager.t
- -> unit
- = "llvm_add_loop_idiom"
-
-(** See the [llvm::createSimplifyLibCallsPass] function. *)
-external
-add_lib_call_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_lib_call_simplification"
-
-(** See the [llvm::createVerifierPass] function. *)
-external
-add_verifier : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_verifier"
-
-(** See the [llvm::createCorrelatedValuePropagationPass] function. *)
-external
-add_correlated_value_propagation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_correlated_value_propagation"
-
-(** See the [llvm::createEarlyCSE] function. *)
-external
-add_early_cse : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_early_cse"
-
-(** See the [llvm::createLowerExpectIntrinsicPass] function. *)
-external
-add_lower_expect_intrinsic : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_lower_expect_intrinsic"
-
-(** See the [llvm::createTypeBasedAliasAnalysisPass] function. *)
-external
-add_type_based_alias_analysis : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_type_based_alias_analysis"
-
-(** See the [llvm::createBasicAliasAnalysisPass] function. *)
-external
-add_basic_alias_analysis : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_basic_alias_analysis"
-
-(** See the [llvm::createPartiallyInlineLibCallsPass] function. *)
-external
-add_partially_inline_lib_calls : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_partially_inline_lib_calls"
diff --git a/bindings/ocaml/transforms/scalar/Makefile b/bindings/ocaml/transforms/scalar_opts/Makefile
index 6e250f6..63d86a6 100644
--- a/bindings/ocaml/transforms/scalar/Makefile
+++ b/bindings/ocaml/transforms/scalar_opts/Makefile
@@ -1,4 +1,4 @@
-##===- bindings/ocaml/transforms/scalar/Makefile -----------*- Makefile -*-===##
+##===- bindings/ocaml/transforms/scalar_opts/Makefile ------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
diff --git a/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.ml b/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.ml
new file mode 100644
index 0000000..b90d0ae
--- /dev/null
+++ b/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.ml
@@ -0,0 +1,120 @@
+(*===-- llvm_scalar_opts.ml - LLVM OCaml Interface ------------*- OCaml -*-===*
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===----------------------------------------------------------------------===*)
+
+external add_aggressive_dce
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_aggressive_dce"
+external add_alignment_from_assumptions
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_alignment_from_assumptions"
+external add_cfg_simplification
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_cfg_simplification"
+external add_dead_store_elimination
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_dead_store_elimination"
+external add_scalarizer
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scalarizer"
+external add_merged_load_store_motion
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_merged_load_store_motion"
+external add_gvn
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_gvn"
+external add_ind_var_simplification
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_ind_var_simplify"
+external add_instruction_combination
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_instruction_combining"
+external add_jump_threading
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_jump_threading"
+external add_licm
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_licm"
+external add_loop_deletion
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_deletion"
+external add_loop_idiom
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_idiom"
+external add_loop_rotation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_rotate"
+external add_loop_reroll
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_reroll"
+external add_loop_unroll
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_unroll"
+external add_loop_unswitch
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_unswitch"
+external add_memcpy_opt
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_memcpy_opt"
+external add_partially_inline_lib_calls
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_partially_inline_lib_calls"
+external add_lower_switch
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_lower_switch"
+external add_memory_to_register_promotion
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_promote_memory_to_register"
+external add_reassociation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_reassociation"
+external add_sccp
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_sccp"
+external add_scalar_repl_aggregation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scalar_repl_aggregates"
+external add_scalar_repl_aggregation_ssa
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scalar_repl_aggregates_ssa"
+external add_scalar_repl_aggregation_with_threshold
+ : int -> [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scalar_repl_aggregates_with_threshold"
+external add_lib_call_simplification
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_simplify_lib_calls"
+external add_tail_call_elimination
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_tail_call_elimination"
+external add_constant_propagation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_constant_propagation"
+external add_memory_to_register_demotion
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_demote_memory_to_register"
+external add_verifier
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_verifier"
+external add_correlated_value_propagation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_correlated_value_propagation"
+external add_early_cse
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_early_cse"
+external add_lower_expect_intrinsic
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_lower_expect_intrinsic"
+external add_type_based_alias_analysis
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_type_based_alias_analysis"
+external add_scoped_no_alias_alias_analysis
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scoped_no_alias_aa"
+external add_basic_alias_analysis
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_basic_alias_analysis"
diff --git a/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli b/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli
new file mode 100644
index 0000000..b4cefed
--- /dev/null
+++ b/bindings/ocaml/transforms/scalar_opts/llvm_scalar_opts.mli
@@ -0,0 +1,198 @@
+(*===-- llvm_scalar_opts.mli - LLVM OCaml Interface -----------*- OCaml -*-===*
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===----------------------------------------------------------------------===*)
+
+(** Scalar Transforms.
+
+ This interface provides an OCaml API for LLVM scalar transforms, the
+ classes in the [LLVMScalarOpts] library. *)
+
+(** See the [llvm::createAggressiveDCEPass] function. *)
+external add_aggressive_dce
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_aggressive_dce"
+
+(** See the [llvm::createAlignmentFromAssumptionsPass] function. *)
+external add_alignment_from_assumptions
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_alignment_from_assumptions"
+
+(** See the [llvm::createCFGSimplificationPass] function. *)
+external add_cfg_simplification
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_cfg_simplification"
+
+(** See [llvm::createDeadStoreEliminationPass] function. *)
+external add_dead_store_elimination
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_dead_store_elimination"
+
+(** See [llvm::createScalarizerPass] function. *)
+external add_scalarizer
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scalarizer"
+
+(** See [llvm::createMergedLoadStoreMotionPass] function. *)
+external add_merged_load_store_motion
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_merged_load_store_motion"
+
+(** See the [llvm::createGVNPass] function. *)
+external add_gvn
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_gvn"
+
+(** See the [llvm::createIndVarSimplifyPass] function. *)
+external add_ind_var_simplification
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_ind_var_simplify"
+
+(** See the [llvm::createInstructionCombiningPass] function. *)
+external add_instruction_combination
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_instruction_combining"
+
+(** See the [llvm::createJumpThreadingPass] function. *)
+external add_jump_threading
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_jump_threading"
+
+(** See the [llvm::createLICMPass] function. *)
+external add_licm
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_licm"
+
+(** See the [llvm::createLoopDeletionPass] function. *)
+external add_loop_deletion
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_deletion"
+
+(** See the [llvm::createLoopIdiomPass] function. *)
+external add_loop_idiom
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_idiom"
+
+(** See the [llvm::createLoopRotatePass] function. *)
+external add_loop_rotation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_rotate"
+
+(** See the [llvm::createLoopRerollPass] function. *)
+external add_loop_reroll
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_reroll"
+
+(** See the [llvm::createLoopUnrollPass] function. *)
+external add_loop_unroll
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_unroll"
+
+(** See the [llvm::createLoopUnswitchPass] function. *)
+external add_loop_unswitch
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_unswitch"
+
+(** See the [llvm::createMemCpyOptPass] function. *)
+external add_memcpy_opt
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_memcpy_opt"
+
+(** See the [llvm::createPartiallyInlineLibCallsPass] function. *)
+external add_partially_inline_lib_calls
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_partially_inline_lib_calls"
+
+(** See the [llvm::createLowerSwitchPass] function. *)
+external add_lower_switch
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_lower_switch"
+
+(** See the [llvm::createPromoteMemoryToRegisterPass] function. *)
+external add_memory_to_register_promotion
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_promote_memory_to_register"
+
+(** See the [llvm::createReassociatePass] function. *)
+external add_reassociation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_reassociation"
+
+(** See the [llvm::createSCCPPass] function. *)
+external add_sccp
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_sccp"
+
+(** See the [llvm::createScalarReplAggregatesPass] function. *)
+external add_scalar_repl_aggregation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scalar_repl_aggregates"
+
+(** See the [llvm::createScalarReplAggregatesPassSSA] function. *)
+external add_scalar_repl_aggregation_ssa
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scalar_repl_aggregates_ssa"
+
+(** See the [llvm::createScalarReplAggregatesWithThreshold] function. *)
+external add_scalar_repl_aggregation_with_threshold
+ : int -> [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scalar_repl_aggregates_with_threshold"
+
+(** See the [llvm::createSimplifyLibCallsPass] function. *)
+external add_lib_call_simplification
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_simplify_lib_calls"
+
+(** See the [llvm::createTailCallEliminationPass] function. *)
+external add_tail_call_elimination
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_tail_call_elimination"
+
+(** See the [llvm::createConstantPropagationPass] function. *)
+external add_constant_propagation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_constant_propagation"
+
+(** See the [llvm::createDemoteMemoryToRegisterPass] function. *)
+external add_memory_to_register_demotion
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_demote_memory_to_register"
+
+(** See the [llvm::createVerifierPass] function. *)
+external add_verifier
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_verifier"
+
+(** See the [llvm::createCorrelatedValuePropagationPass] function. *)
+external add_correlated_value_propagation
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_correlated_value_propagation"
+
+(** See the [llvm::createEarlyCSE] function. *)
+external add_early_cse
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_early_cse"
+
+(** See the [llvm::createLowerExpectIntrinsicPass] function. *)
+external add_lower_expect_intrinsic
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_lower_expect_intrinsic"
+
+(** See the [llvm::createTypeBasedAliasAnalysisPass] function. *)
+external add_type_based_alias_analysis
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_type_based_alias_analysis"
+
+(** See the [llvm::createScopedNoAliasAAPass] function. *)
+external add_scoped_no_alias_alias_analysis
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_scoped_no_alias_aa"
+
+(** See the [llvm::createBasicAliasAnalysisPass] function. *)
+external add_basic_alias_analysis
+ : [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
+ = "llvm_add_basic_alias_analysis"
diff --git a/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c b/bindings/ocaml/transforms/scalar_opts/scalar_opts_ocaml.c
index 0a71bd7..bae4e31 100644
--- a/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c
+++ b/bindings/ocaml/transforms/scalar_opts/scalar_opts_ocaml.c
@@ -20,69 +20,92 @@
#include "caml/misc.h"
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_constant_propagation(LLVMPassManagerRef PM) {
- LLVMAddConstantPropagationPass(PM);
+CAMLprim value llvm_add_aggressive_dce(LLVMPassManagerRef PM) {
+ LLVMAddAggressiveDCEPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_sccp(LLVMPassManagerRef PM) {
- LLVMAddSCCPPass(PM);
+CAMLprim value llvm_add_alignment_from_assumptions(LLVMPassManagerRef PM) {
+ LLVMAddAlignmentFromAssumptionsPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_dead_store_elimination(LLVMPassManagerRef PM) {
- LLVMAddDeadStoreEliminationPass(PM);
+CAMLprim value llvm_add_cfg_simplification(LLVMPassManagerRef PM) {
+ LLVMAddCFGSimplificationPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_aggressive_dce(LLVMPassManagerRef PM) {
- LLVMAddAggressiveDCEPass(PM);
+CAMLprim value llvm_add_dead_store_elimination(LLVMPassManagerRef PM) {
+ LLVMAddDeadStoreEliminationPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_scalar_repl_aggregation(LLVMPassManagerRef PM) {
- LLVMAddScalarReplAggregatesPass(PM);
+CAMLprim value llvm_add_scalarizer(LLVMPassManagerRef PM) {
+ LLVMAddScalarizerPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_scalar_repl_aggregation_ssa(LLVMPassManagerRef PM) {
- LLVMAddScalarReplAggregatesPassSSA(PM);
+CAMLprim value llvm_add_merged_load_store_motion(LLVMPassManagerRef PM) {
+ LLVMAddMergedLoadStoreMotionPass(PM);
return Val_unit;
}
-/* [<Llvm.PassManager.any] Llvm.PassManager.t -> int -> unit */
-CAMLprim value llvm_add_scalar_repl_aggregation_with_threshold(value threshold,
- LLVMPassManagerRef PM) {
- LLVMAddScalarReplAggregatesPassWithThreshold(PM, Int_val(threshold));
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_gvn(LLVMPassManagerRef PM) {
+ LLVMAddGVNPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_ind_var_simplification(LLVMPassManagerRef PM) {
+CAMLprim value llvm_add_ind_var_simplify(LLVMPassManagerRef PM) {
LLVMAddIndVarSimplifyPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_instruction_combination(LLVMPassManagerRef PM) {
+CAMLprim value llvm_add_instruction_combining(LLVMPassManagerRef PM) {
LLVMAddInstructionCombiningPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_jump_threading(LLVMPassManagerRef PM) {
+ LLVMAddJumpThreadingPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_licm(LLVMPassManagerRef PM) {
LLVMAddLICMPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_loop_unswitch(LLVMPassManagerRef PM) {
- LLVMAddLoopUnswitchPass(PM);
+CAMLprim value llvm_add_loop_deletion(LLVMPassManagerRef PM) {
+ LLVMAddLoopDeletionPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_loop_idiom(LLVMPassManagerRef PM) {
+ LLVMAddLoopIdiomPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_loop_rotate(LLVMPassManagerRef PM) {
+ LLVMAddLoopRotatePass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_loop_reroll(LLVMPassManagerRef PM) {
+ LLVMAddLoopRerollPass(PM);
return Val_unit;
}
@@ -93,20 +116,32 @@ CAMLprim value llvm_add_loop_unroll(LLVMPassManagerRef PM) {
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_loop_rotation(LLVMPassManagerRef PM) {
- LLVMAddLoopRotatePass(PM);
+CAMLprim value llvm_add_loop_unswitch(LLVMPassManagerRef PM) {
+ LLVMAddLoopUnswitchPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_memory_to_register_promotion(LLVMPassManagerRef PM) {
- LLVMAddPromoteMemoryToRegisterPass(PM);
+CAMLprim value llvm_add_memcpy_opt(LLVMPassManagerRef PM) {
+ LLVMAddMemCpyOptPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_memory_to_register_demotion(LLVMPassManagerRef PM) {
- LLVMAddDemoteMemoryToRegisterPass(PM);
+CAMLprim value llvm_add_partially_inline_lib_calls(LLVMPassManagerRef PM) {
+ LLVMAddPartiallyInlineLibCallsPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_lower_switch(LLVMPassManagerRef PM) {
+ LLVMAddLowerSwitchPass(PM);
+ return Val_unit;
+}
+
+/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_promote_memory_to_register(LLVMPassManagerRef PM) {
+ LLVMAddPromoteMemoryToRegisterPass(PM);
return Val_unit;
}
@@ -117,50 +152,51 @@ CAMLprim value llvm_add_reassociation(LLVMPassManagerRef PM) {
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_jump_threading(LLVMPassManagerRef PM) {
- LLVMAddJumpThreadingPass(PM);
+CAMLprim value llvm_add_sccp(LLVMPassManagerRef PM) {
+ LLVMAddSCCPPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_cfg_simplification(LLVMPassManagerRef PM) {
- LLVMAddCFGSimplificationPass(PM);
+CAMLprim value llvm_add_scalar_repl_aggregates(LLVMPassManagerRef PM) {
+ LLVMAddScalarReplAggregatesPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_tail_call_elimination(LLVMPassManagerRef PM) {
- LLVMAddTailCallEliminationPass(PM);
+CAMLprim value llvm_add_scalar_repl_aggregates_ssa(LLVMPassManagerRef PM) {
+ LLVMAddScalarReplAggregatesPassSSA(PM);
return Val_unit;
}
-/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_gvn(LLVMPassManagerRef PM) {
- LLVMAddGVNPass(PM);
+/* int -> [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+CAMLprim value llvm_add_scalar_repl_aggregates_with_threshold(value threshold,
+ LLVMPassManagerRef PM) {
+ LLVMAddScalarReplAggregatesPassWithThreshold(PM, Int_val(threshold));
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_memcpy_opt(LLVMPassManagerRef PM) {
- LLVMAddMemCpyOptPass(PM);
+CAMLprim value llvm_add_simplify_lib_calls(LLVMPassManagerRef PM) {
+ LLVMAddSimplifyLibCallsPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_loop_deletion(LLVMPassManagerRef PM) {
- LLVMAddLoopDeletionPass(PM);
+CAMLprim value llvm_add_tail_call_elimination(LLVMPassManagerRef PM) {
+ LLVMAddTailCallEliminationPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_loop_idiom(LLVMPassManagerRef PM) {
- LLVMAddLoopIdiomPass(PM);
+CAMLprim value llvm_add_constant_propagation(LLVMPassManagerRef PM) {
+ LLVMAddConstantPropagationPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_lib_call_simplification(LLVMPassManagerRef PM) {
- LLVMAddSimplifyLibCallsPass(PM);
+CAMLprim value llvm_add_demote_memory_to_register(LLVMPassManagerRef PM) {
+ LLVMAddDemoteMemoryToRegisterPass(PM);
return Val_unit;
}
@@ -195,13 +231,13 @@ CAMLprim value llvm_add_type_based_alias_analysis(LLVMPassManagerRef PM) {
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_basic_alias_analysis(LLVMPassManagerRef PM) {
- LLVMAddBasicAliasAnalysisPass(PM);
+CAMLprim value llvm_add_scoped_no_alias_aa(LLVMPassManagerRef PM) {
+ LLVMAddScopedNoAliasAAPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
-CAMLprim value llvm_add_partially_inline_lib_calls(LLVMPassManagerRef PM) {
- LLVMAddPartiallyInlineLibCallsPass(PM);
+CAMLprim value llvm_add_basic_alias_analysis(LLVMPassManagerRef PM) {
+ LLVMAddBasicAliasAnalysisPass(PM);
return Val_unit;
}
diff --git a/bindings/ocaml/transforms/vectorize/Makefile b/bindings/ocaml/transforms/vectorize/Makefile
index 5a854d1..64ac5c3 100644
--- a/bindings/ocaml/transforms/vectorize/Makefile
+++ b/bindings/ocaml/transforms/vectorize/Makefile
@@ -7,7 +7,7 @@
#
##===----------------------------------------------------------------------===##
#
-# This is the makefile for the Objective Caml Llvm_vectorize_opts interface.
+# This is the makefile for the Objective Caml Llvm_vectorize interface.
#
##===----------------------------------------------------------------------===##
diff --git a/bindings/ocaml/transforms/vectorize/llvm_vectorize.ml b/bindings/ocaml/transforms/vectorize/llvm_vectorize.ml
index 4fc53c6..88831da 100644
--- a/bindings/ocaml/transforms/vectorize/llvm_vectorize.ml
+++ b/bindings/ocaml/transforms/vectorize/llvm_vectorize.ml
@@ -7,9 +7,12 @@
*
*===----------------------------------------------------------------------===*)
-external add_bb_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_bb_vectorize"
-external add_loop_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_loop_vectorize"
-external add_slp_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_slp_vectorize"
+external add_bb_vectorize
+ : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_bb_vectorize"
+external add_loop_vectorize
+ : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_vectorize"
+external add_slp_vectorize
+ : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_slp_vectorize"
diff --git a/bindings/ocaml/transforms/vectorize/llvm_vectorize.mli b/bindings/ocaml/transforms/vectorize/llvm_vectorize.mli
index 0253039..23a68a2 100644
--- a/bindings/ocaml/transforms/vectorize/llvm_vectorize.mli
+++ b/bindings/ocaml/transforms/vectorize/llvm_vectorize.mli
@@ -13,13 +13,16 @@
classes in the [LLVMVectorize] library. *)
(** See the [llvm::createBBVectorizePass] function. *)
-external add_bb_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_bb_vectorize"
+external add_bb_vectorize
+ : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_bb_vectorize"
(** See the [llvm::createLoopVectorizePass] function. *)
-external add_loop_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_loop_vectorize"
+external add_loop_vectorize
+ : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_loop_vectorize"
-(** See [llvm::createSLPVectorizerPass] function. *)
-external add_slp_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
- = "llvm_add_slp_vectorize"
+(** See the [llvm::createSLPVectorizerPass] function. *)
+external add_slp_vectorize
+ : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
+ = "llvm_add_slp_vectorize"