Vendor import of llvm RELEASE_360/rc1 tag r226102 (effectively, 3.6.0 RC1):

https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_360/rc1@226102
This commit is contained in:
dim 2015-01-18 16:17:27 +00:00
parent 3c7e7a1538
commit 081af4da16
5899 changed files with 337345 additions and 129067 deletions

1
.clang-tidy Normal file
View File

@ -0,0 +1 @@
Checks: '-*,clang-diagnostic-*,llvm-*,misc-*'

15
.gitignore vendored
View File

@ -24,6 +24,13 @@
#==============================================================================#
# Explicit files to ignore (only matches one).
#==============================================================================#
# Various tag programs
/tags
/TAGS
/GPATH
/GRTAGS
/GSYMS
/GTAGS
.gitusers
autom4te.cache
cscope.files
@ -45,7 +52,15 @@ tools/clang
tools/lldb
# lld, which is tracked independently.
tools/lld
# llgo, which is tracked independently.
tools/llgo
# Polly, which is tracked independently.
tools/polly
# Sphinx build tree, if building in-source dir.
docs/_build
#==============================================================================#
# Files created in tree by the Go bindings.
#==============================================================================#
bindings/go/llvm/llvm_config.go
bindings/go/llvm/workdir

View File

@ -16,8 +16,29 @@ else()
endif()
endif()
if(CMAKE_VERSION VERSION_LESS 3.1.20141117)
set(cmake_3_2_USES_TERMINAL)
else()
set(cmake_3_2_USES_TERMINAL USES_TERMINAL)
endif()
project(LLVM)
# The following only works with the Ninja generator in CMake >= 3.0.
set(LLVM_PARALLEL_COMPILE_JOBS "" CACHE STRING
"Define the maximum number of concurrent compilation jobs.")
if(LLVM_PARALLEL_COMPILE_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${LLVM_PARALLEL_COMPILE_JOBS})
set(CMAKE_JOB_POOL_COMPILE compile_job_pool)
endif()
set(LLVM_PARALLEL_LINK_JOBS "" CACHE STRING
"Define the maximum number of concurrent link jobs.")
if(LLVM_PARALLEL_LINK_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${LLVM_PARALLEL_LINK_JOBS})
set(CMAKE_JOB_POOL_LINK link_job_pool)
endif()
# Add path for custom modules
set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
@ -26,11 +47,11 @@ set(CMAKE_MODULE_PATH
)
set(LLVM_VERSION_MAJOR 3)
set(LLVM_VERSION_MINOR 5)
set(LLVM_VERSION_PATCH 1)
set(LLVM_VERSION_MINOR 6)
set(LLVM_VERSION_PATCH 0)
if (NOT PACKAGE_VERSION)
set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}svn")
set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
endif()
option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF)
@ -111,9 +132,11 @@ endif()
string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
set(LLVM_LIBDIR_SUFFIX "" CACHE STRING "Define suffix of library directory name (32/64)" )
# They are used as destination of target generators.
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
if(WIN32 OR CYGWIN)
# DLL platform -- put DLLs into bin.
set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
@ -130,7 +153,6 @@ set(LLVM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ) # --prefix
set(LLVM_EXAMPLES_BINARY_DIR ${LLVM_BINARY_DIR}/examples)
set(LLVM_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
set(LLVM_LIBDIR_SUFFIX "" CACHE STRING "Define suffix of library directory name (32/64)" )
set(LLVM_ALL_TARGETS
AArch64
@ -208,6 +230,7 @@ else()
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
endif()
option(LLVM_ENABLE_MODULES "Compile with C++ modules enabled." OFF)
option(LLVM_ENABLE_CXX1Y "Compile with C++1y enabled." OFF)
option(LLVM_ENABLE_LIBCXX "Use libc++ if available." OFF)
option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
@ -301,6 +324,12 @@ option (LLVM_ENABLE_SPHINX "Use Sphinx to generate llvm documentation." OFF)
option (LLVM_BUILD_EXTERNAL_COMPILER_RT
"Build compiler-rt as an external project." OFF)
option(LLVM_BUILD_LLVM_DYLIB "Build libllvm dynamic library" OFF)
option(LLVM_DISABLE_LLVM_DYLIB_ATEXIT "Disable llvm-shlib's atexit destructors." ON)
if(LLVM_DISABLE_LLVM_DYLIB_ATEXIT)
set(DISABLE_LLVM_DYLIB_ATEXIT 1)
endif()
# All options referred to from HandleLLVMOptions have to be specified
# BEFORE this include, otherwise options will not be correctly set on
# first cmake run
@ -315,7 +344,9 @@ set(TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}")
include(HandleLLVMOptions)
# Verify that we can find a Python 2 interpreter. Python 3 is unsupported.
set(Python_ADDITIONAL_VERSIONS 2.7 2.6 2.5)
# FIXME: We should support systems with only Python 3, but that requires work
# on LLDB.
set(Python_ADDITIONAL_VERSIONS 2.7)
include(FindPythonInterp)
if( NOT PYTHONINTERP_FOUND )
message(FATAL_ERROR
@ -324,6 +355,10 @@ if( NOT PYTHONINTERP_FOUND )
Please install Python or specify the PYTHON_EXECUTABLE CMake variable.")
endif()
if( ${PYTHON_VERSION_STRING} VERSION_LESS 2.7 )
message(FATAL_ERROR "Python 2.7 or newer is required")
endif()
######
# LLVMBuild Integration
#
@ -449,8 +484,8 @@ configure_file(
# They are not referenced. See set_output_directory().
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/bin )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX} )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX} )
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
if (APPLE)
@ -458,17 +493,33 @@ if (APPLE)
set(CMAKE_INSTALL_RPATH "@executable_path/../lib")
else(UNIX)
if(NOT DEFINED CMAKE_INSTALL_RPATH)
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib")
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}")
if (${CMAKE_SYSTEM_NAME} MATCHES FreeBSD)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,origin")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,origin")
endif()
endif(NOT DEFINED CMAKE_INSTALL_RPATH)
endif()
# Work around a broken bfd ld behavior. When linking a binary with a
# foo.so library, it will try to find any library that foo.so uses and
# check its symbols. This is wasteful (the check was done when foo.so
# was created) and can fail since it is not the dynamic linker and
# doesn't know how to handle search paths correctly.
if (UNIX AND NOT APPLE)
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -Wl,-allow-shlib-undefined")
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories( ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR})
# when crosscompiling import the executable targets from a file
if(CMAKE_CROSSCOMPILING)
include(CrossCompile)
endif(CMAKE_CROSSCOMPILING)
if( ${CMAKE_SYSTEM_NAME} MATCHES FreeBSD )
# On FreeBSD, /usr/local/* is not used by default. In order to build LLVM
# with libxml2, iconv.h, etc., we must add /usr/local paths.
@ -521,6 +572,12 @@ if(LLVM_INCLUDE_TESTS)
add_subdirectory(utils/unittest)
endif()
foreach( binding ${LLVM_BINDINGS_LIST} )
if( EXISTS "${LLVM_MAIN_SRC_DIR}/bindings/${binding}/CMakeLists.txt" )
add_subdirectory(bindings/${binding})
endif()
endforeach()
add_subdirectory(projects)
if(WITH_POLLY)

View File

@ -6,7 +6,7 @@ what goes in or not.
The list is sorted by surname and formatted to allow easy grepping and
beautification by scripts. The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
(S).
(S). Each entry should contain at least the (N), (E) and (D) fields.
N: Joe Abbey
E: jabbey@arxan.com
@ -20,6 +20,10 @@ N: Rafael Avila de Espindola
E: rafael.espindola@gmail.com
D: Gold plugin (tools/gold/*)
N: Justin Bogner
E: mail@justinbogner.com
D: InstrProfiling and related parts of ProfileData
N: Chandler Carruth
E: chandlerc@gmail.com
E: chandlerc@google.com
@ -29,43 +33,50 @@ N: Evan Cheng
E: evan.cheng@apple.com
D: ARM target, parts of code generator not covered by someone else
N: Renato Golin
E: renato.golin@linaro.org
D: ARM Linux support
N: Eric Christopher
E: echristo@gmail.com
D: Debug Information, autotools/configure/make build, inline assembly
N: Greg Clayton
E: gclayton@apple.com
D: LLDB
N: Marshall Clow
E: mclow.lists@gmail.com
D: libc++
N: Peter Collingbourne
D: libclc
E: peter@pcc.me.uk
D: llgo
N: Anshuman Dasgupta
E: adasgupt@codeaurora.org
D: Hexagon Backend
N: Duncan P. N. Exon Smith
E: dexonsmith@apple.com
D: Branch weights and BlockFrequencyInfo
N: Hal Finkel
E: hfinkel@anl.gov
D: BBVectorize, the loop reroller and the PowerPC target
D: BBVectorize, the loop reroller, alias analysis and the PowerPC target
N: Renato Golin
E: renato.golin@linaro.org
D: ARM Linux support
N: Venkatraman Govindaraju
E: venkatra@cs.wisc.edu
D: Sparc Backend (lib/Target/Sparc/*)
N: Tobias Grosser
E: tobias@grosser.es
D: Polly
N: James Grosbach
E: grosbach@apple.com
D: MC layer
N: Marshall Clow
E: mclow.lists@gmail.com
D: libc++
N: Justin Holewinski
E: jholewinski@nvidia.com
D: NVPTX Target (lib/Target/NVPTX/*)
@ -99,7 +110,12 @@ N: Tim Northover
E: t.p.northover@gmail.com
D: AArch64 backend
N: Diego Novillo
E: dnovillo@google.com
D: SampleProfile and related parts of ProfileData
N: Jakob Olesen
E: stoklund@2pi.dk
D: Register allocators and TableGen
N: Richard Osborne
@ -118,10 +134,6 @@ N: Daniel Sanders
E: daniel.sanders@imgtec.com
D: MIPS Backend (lib/Target/Mips/*)
N: Richard Sandiford
E: rsandifo@linux.vnet.ibm.com
D: SystemZ Backend
N: Duncan Sands
E: baldrick@free.fr
D: DragonEgg
@ -137,7 +149,7 @@ D: Windows parts of Support, Object, ar, nm, objdump, ranlib, size
N: Tom Stellard
E: thomas.stellard@amd.com
E: mesa-dev@lists.freedesktop.org
D: R600 Backend
D: Release manager for the 3.5 branch, R600 Backend, libclc
N: Evgeniy Stepanov
E: eugenis@google.com
@ -147,6 +159,10 @@ N: Andrew Trick
E: atrick@apple.com
D: IndVar Simplify, Loop Strength Reduction, Instruction Scheduling
N: Ulrich Weigand
E: uweigand@de.ibm.com
D: SystemZ Backend
N: Bill Wendling
E: isanbard@gmail.com
D: libLTO, IR Linker

View File

@ -119,6 +119,10 @@ N: Hal Finkel
E: hfinkel@anl.gov
D: Basic-block autovectorization, PowerPC backend improvements
N: Eric Fiselier
E: eric@efcs.ca
D: LIT patches and documentation.
N: Ryan Flynn
E: pizza@parseerror.com
D: Miscellaneous bug fixes
@ -281,8 +285,11 @@ D: Backend for Qualcomm's Hexagon VLIW processor.
N: Bruno Cardoso Lopes
E: bruno.cardoso@gmail.com
W: http://www.brunocardoso.org
D: The Mips backend
I: bruno
W: http://brunocardoso.cc
D: Mips backend
D: Random ARM integrated assembler and assembly parser improvements
D: General X86 AVX1 support
N: Duraid Madina
E: duraid@octopus.com.au
@ -456,3 +463,4 @@ D: Bunches of stuff
N: Bob Wilson
E: bob.wilson@acm.org
D: Advanced SIMD (NEON) support in the ARM backend.

View File

@ -202,10 +202,8 @@ DOT := @DOT@
DOXYGEN := @DOXYGEN@
GROFF := @GROFF@
GZIPBIN := @GZIPBIN@
OCAMLC := @OCAMLC@
OCAMLOPT := @OCAMLOPT@
OCAMLDEP := @OCAMLDEP@
OCAMLDOC := @OCAMLDOC@
GO := @GO@
OCAMLFIND := @OCAMLFIND@
GAS := @GAS@
POD2HTML := @POD2HTML@
POD2MAN := @POD2MAN@
@ -217,6 +215,9 @@ HAVE_DLOPEN := @HAVE_DLOPEN@
HAVE_PTHREAD := @HAVE_PTHREAD@
HAVE_TERMINFO := @HAVE_TERMINFO@
HAVE_OCAMLOPT := @HAVE_OCAMLOPT@
HAVE_OCAML_OUNIT := @HAVE_OCAML_OUNIT@
LIBS := @LIBS@
# Targets that are possible to build
@ -370,7 +371,6 @@ HUGE_VAL_SANITY = @HUGE_VAL_SANITY@
# Bindings that we should build
BINDINGS_TO_BUILD := @BINDINGS_TO_BUILD@
ALL_BINDINGS := @ALL_BINDINGS@
OCAML_LIBDIR := @OCAML_LIBDIR@
# When compiling under Mingw/Cygwin, executables such as tblgen
@ -396,6 +396,8 @@ COVERED_SWITCH_DEFAULT = @COVERED_SWITCH_DEFAULT@
NO_UNINITIALIZED = @NO_UNINITIALIZED@
# -Wno-maybe-uninitialized
NO_MAYBE_UNINITIALIZED = @NO_MAYBE_UNINITIALIZED@
# -Wno-comment
NO_COMMENT = @NO_COMMENT@
# Was polly found in tools/polly?
LLVM_HAS_POLLY = @LLVM_HAS_POLLY@

View File

@ -449,7 +449,6 @@ ifeq ($(HOST_OS),MingW)
endif
endif
CXX.Flags += -Woverloaded-virtual
CPP.BaseFlags += $(CPP.Defines)
AR.Flags := cru
@ -680,7 +679,7 @@ endif
CompileCommonOpts += -Wall -W -Wno-unused-parameter -Wwrite-strings \
$(EXTRA_OPTIONS) $(COVERED_SWITCH_DEFAULT) \
$(NO_UNINITIALIZED) $(NO_MAYBE_UNINITIALIZED) \
$(NO_MISSING_FIELD_INITIALIZERS)
$(NO_MISSING_FIELD_INITIALIZERS) $(NO_COMMENT)
# Enable cast-qual for C++; the workaround is to use const_cast.
CXX.Flags += -Wcast-qual
@ -727,10 +726,6 @@ ifeq ($(HOST_OS),SunOS)
CPP.BaseFlags += -include llvm/Support/Solaris.h
endif
ifeq ($(HOST_OS),AuroraUX)
CPP.BaseFlags += -include llvm/Support/Solaris.h
endif # !HOST_OS - AuroraUX.
# On Windows, SharedLibDir != LibDir. The order is important.
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
LD.Flags += -L$(SharedLibDir) -L$(LibDir) -L$(LLVMToolDir) -L$(LLVMLibDir)
@ -1673,18 +1668,13 @@ $(ObjDir)/%GenAsmMatcher.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(TARGET:%=$(ObjDir)/%GenMCCodeEmitter.inc.tmp): \
$(ObjDir)/%GenMCCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) MC code emitter with tblgen"
$(Verb) $(LLVMTableGen) -gen-emitter -mc-emitter -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-emitter -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenMCPseudoLowering.inc.tmp): \
$(ObjDir)/%GenMCPseudoLowering.inc.tmp: %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) MC Pseudo instruction expander with tblgen"
$(Verb) $(LLVMTableGen) -gen-pseudo-lowering -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenCodeEmitter.inc.tmp): \
$(ObjDir)/%GenCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) code emitter with tblgen"
$(Verb) $(LLVMTableGen) -gen-emitter -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenDAGISel.inc.tmp): \
$(ObjDir)/%GenDAGISel.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) DAG instruction selector implementation with tblgen"
@ -1790,7 +1780,7 @@ endif
# CHECK: Running the test suite
###############################################################################
check:: all
check::
$(Verb) if test -d "$(PROJ_OBJ_ROOT)/test" ; then \
if test -f "$(PROJ_OBJ_ROOT)/test/Makefile" ; then \
$(EchoCmd) Running test suite ; \

View File

@ -1,8 +1,8 @@
Low Level Virtual Machine (LLVM)
================================
This directory and its subdirectories contain source code for the Low Level
Virtual Machine, a toolkit for the construction of highly optimized compilers,
This directory and its subdirectories contain source code for LLVM,
a toolkit for the construction of highly optimized compilers,
optimizers, and runtime environments.
LLVM is open source software. You may freely distribute it under the terms of
@ -15,3 +15,4 @@ documentation setup.
If you're writing a package for LLVM, see docs/Packaging.rst for our
suggestions.

4
autoconf/config.sub vendored
View File

@ -251,7 +251,7 @@ case $basic_machine in
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| aarch64 \
| aarch64 | aarch64_be \
| be32 | be64 \
| bfin \
| c4x | clipper \
@ -360,7 +360,7 @@ case $basic_machine in
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| aarch64-* \
| aarch64-* | aarch64_be-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \

View File

@ -32,16 +32,17 @@ dnl===-----------------------------------------------------------------------===
dnl Initialize autoconf and define the package name, version number and
dnl address for reporting bugs.
AC_INIT([LLVM],[3.5.1],[http://llvm.org/bugs/])
AC_INIT([LLVM],[3.6.0],[http://llvm.org/bugs/])
LLVM_VERSION_MAJOR=3
LLVM_VERSION_MINOR=5
LLVM_VERSION_PATCH=1
LLVM_VERSION_MINOR=6
LLVM_VERSION_PATCH=0
LLVM_VERSION_SUFFIX=
AC_DEFINE_UNQUOTED([LLVM_VERSION_MAJOR], $LLVM_VERSION_MAJOR, [Major version of the LLVM API])
AC_DEFINE_UNQUOTED([LLVM_VERSION_MINOR], $LLVM_VERSION_MINOR, [Minor version of the LLVM API])
AC_DEFINE_UNQUOTED([LLVM_VERSION_PATCH], $LLVM_VERSION_PATCH, [Patch version of the LLVM API])
AC_DEFINE_UNQUOTED([LLVM_VERSION_STRING], "$PACKAGE_VERSION", [LLVM version string])
AC_SUBST([LLVM_VERSION_MAJOR])
AC_SUBST([LLVM_VERSION_MINOR])
@ -291,11 +292,6 @@ AC_CACHE_CHECK([type of operating system we're going to host on],
llvm_cv_no_link_all_option="-Wl,-z,defaultextract"
llvm_cv_os_type="SunOS"
llvm_cv_platform_type="Unix" ;;
*-*-auroraux*)
llvm_cv_link_all_option="-Wl,-z,allextract"
llvm_cv_link_all_option="-Wl,-z,defaultextract"
llvm_cv_os_type="AuroraUX"
llvm_cv_platform_type="Unix" ;;
*-*-win32*)
llvm_cv_link_all_option="-Wl,--whole-archive"
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
@ -361,8 +357,6 @@ AC_CACHE_CHECK([type of operating system we're going to target],
llvm_cv_target_os_type="GNU" ;;
*-*-solaris*)
llvm_cv_target_os_type="SunOS" ;;
*-*-auroraux*)
llvm_cv_target_os_type="AuroraUX" ;;
*-*-win32*)
llvm_cv_target_os_type="Win32" ;;
*-*-mingw*)
@ -665,11 +659,11 @@ AC_ARG_ENABLE(clang-static-analyzer,
enableval="yes")
case "$enableval" in
yes) AC_SUBST(ENABLE_CLANG_STATIC_ANALYZER,[1]) ;;
no)
no)
if test ${clang_arcmt} != "no" ; then
AC_MSG_ERROR([Cannot enable clang ARC Migration Tool while disabling static analyzer.])
fi
AC_SUBST(ENABLE_CLANG_STATIC_ANALYZER,[0])
AC_SUBST(ENABLE_CLANG_STATIC_ANALYZER,[0])
;;
default) AC_SUBST(ENABLE_CLANG_STATIC_ANALYZER,[1]);;
*) AC_MSG_ERROR([Invalid setting for --enable-clang-static-analyzer. Use "yes" or "no"]) ;;
@ -1294,10 +1288,8 @@ AC_PATH_PROG(GROFF, [groff])
AC_PATH_PROG(GZIPBIN, [gzip])
AC_PATH_PROG(PDFROFF, [pdfroff])
AC_PATH_PROG(ZIP, [zip])
AC_PATH_PROGS(OCAMLC, [ocamlc])
AC_PATH_PROGS(OCAMLOPT, [ocamlopt])
AC_PATH_PROGS(OCAMLDEP, [ocamldep])
AC_PATH_PROGS(OCAMLDOC, [ocamldoc])
AC_PATH_PROG(GO, [go])
AC_PATH_PROGS(OCAMLFIND, [ocamlfind])
AC_PATH_PROGS(GAS, [gas as])
dnl Get the version of the linker in use.
@ -1395,7 +1387,27 @@ then
CXX_FLAG_CHECK(NO_UNINITIALIZED, [-Wno-uninitialized])
fi
fi
AC_MSG_RESULT([$NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS $COVERED_SWITCH_DEFAULT $NO_UNINITIALIZED $NO_MAYBE_UNINITIALIZED])
dnl Check for misbehaving -Wcomment (gcc-4.7 has this) and maybe add
dnl -Wno-comment to the flags.
no_comment=
llvm_cv_old_cxxflags="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -Wcomment -Werror"
AC_COMPILE_IFELSE(
[
AC_LANG_SOURCE([[// Comment \o\
// Another comment
int main() { return 0; }
]])
],
[
no_comment=-Wno-comment
],
[])
AC_SUBST(NO_COMMENT, [$no_comment])
CXXFLAGS="$llvm_cv_old_cxxflags"
AC_MSG_RESULT([$NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS $COVERED_SWITCH_DEFAULT $NO_UNINITIALIZED $NO_MAYBE_UNINITIALIZED $NO_COMMENT])
AC_ARG_WITH([python],
[AS_HELP_STRING([--with-python], [path to python])],
@ -1409,23 +1421,23 @@ else
AC_MSG_WARN([specified python ($PYTHON) is not usable, searching path])
fi
AC_PATH_PROG([PYTHON], [python python2 python26],
AC_PATH_PROG([PYTHON], [python python2 python27],
[AC_MSG_RESULT([not found])
AC_MSG_ERROR([could not find python 2.5 or higher])])
AC_MSG_ERROR([could not find python 2.7 or higher])])
fi
AC_MSG_CHECKING([for python >= 2.5])
AC_MSG_CHECKING([for python >= 2.7])
ac_python_version=`$PYTHON -V 2>&1 | cut -d' ' -f2`
ac_python_version_major=`echo $ac_python_version | cut -d'.' -f1`
ac_python_version_minor=`echo $ac_python_version | cut -d'.' -f2`
ac_python_version_patch=`echo $ac_python_version | cut -d'.' -f3`
if test "$ac_python_version_major" -gt "2" || \
(test "$ac_python_version_major" -eq "2" && \
test "$ac_python_version_minor" -ge "5") ; then
test "$ac_python_version_minor" -ge "7") ; then
AC_MSG_RESULT([$PYTHON ($ac_python_version)])
else
AC_MSG_RESULT([not found])
AC_MSG_FAILURE([found python $ac_python_version ($PYTHON); required >= 2.5])
AC_MSG_FAILURE([found python $ac_python_version ($PYTHON); required >= 2.7])
fi
dnl===-----------------------------------------------------------------------===
@ -1530,7 +1542,7 @@ AC_ARG_WITH(oprofile,
fi ;;
*)
AC_MSG_ERROR([OProfile support is available on Linux only.]) ;;
esac
esac
],
[
AC_SUBST(USE_OPROFILE, [0])
@ -1598,8 +1610,12 @@ AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_LANG_PUSH([C++])
AC_CHECK_HEADERS([cxxabi.h])
dnl size_t must be defined before including cxxabi.h on FreeBSD 10.0.
AC_CHECK_HEADERS([cxxabi.h], [], [],
[#include <stddef.h>
])
AC_LANG_POP([C++])
AC_CHECK_HEADERS([dlfcn.h execinfo.h fcntl.h inttypes.h link.h])
AC_CHECK_HEADERS([malloc.h setjmp.h signal.h stdint.h termios.h unistd.h])
AC_CHECK_HEADERS([utime.h])
@ -1871,37 +1887,52 @@ AC_DEFINE_UNQUOTED(LLVM_DEFAULT_TARGET_TRIPLE, "$target",
dnl Determine which bindings to build.
if test "$BINDINGS_TO_BUILD" = auto ; then
BINDINGS_TO_BUILD=""
if test "x$OCAMLC" != x -a "x$OCAMLDEP" != x ; then
if test "x$OCAMLFIND" != x ; then
BINDINGS_TO_BUILD="ocaml $BINDINGS_TO_BUILD"
fi
if test "x$GO" != x ; then
if $GO run ${srcdir}/bindings/go/conftest.go ; then
BINDINGS_TO_BUILD="go $BINDINGS_TO_BUILD"
fi
fi
fi
AC_SUBST(BINDINGS_TO_BUILD,$BINDINGS_TO_BUILD)
dnl This isn't really configurey, but it avoids having to repeat the list in
dnl other files.
AC_SUBST(ALL_BINDINGS,ocaml)
dnl Do any work necessary to ensure that bindings have what they need.
binding_prereqs_failed=0
for a_binding in $BINDINGS_TO_BUILD ; do
case "$a_binding" in
ocaml)
if test "x$OCAMLC" = x ; then
AC_MSG_WARN([--enable-bindings=ocaml specified, but ocamlc not found. Try configure OCAMLC=/path/to/ocamlc])
if test "x$OCAMLFIND" = x ; then
AC_MSG_WARN([--enable-bindings=ocaml specified, but ocamlfind not found. Try configure OCAMLFIND=/path/to/ocamlfind])
binding_prereqs_failed=1
fi
if test "x$OCAMLDEP" = x ; then
AC_MSG_WARN([--enable-bindings=ocaml specified, but ocamldep not found. Try configure OCAMLDEP=/path/to/ocamldep])
if $OCAMLFIND opt -version >/dev/null 2>/dev/null ; then
HAVE_OCAMLOPT=1
else
HAVE_OCAMLOPT=0
fi
AC_SUBST(HAVE_OCAMLOPT)
if ! $OCAMLFIND query ctypes >/dev/null 2>/dev/null; then
AC_MSG_WARN([--enable-bindings=ocaml specified, but ctypes is not installed])
binding_prereqs_failed=1
fi
if test "x$OCAMLOPT" = x ; then
AC_MSG_WARN([--enable-bindings=ocaml specified, but ocamlopt not found. Try configure OCAMLOPT=/path/to/ocamlopt])
dnl ocamlopt is optional!
if $OCAMLFIND query oUnit >/dev/null 2>/dev/null; then
HAVE_OCAML_OUNIT=1
else
HAVE_OCAML_OUNIT=0
AC_MSG_WARN([--enable-bindings=ocaml specified, but OUnit 2 is not installed. Tests will not run])
dnl oUnit is optional!
fi
AC_SUBST(HAVE_OCAML_OUNIT)
if test "x$with_ocaml_libdir" != xauto ; then
AC_SUBST(OCAML_LIBDIR,$with_ocaml_libdir)
else
ocaml_stdlib="`"$OCAMLC" -where`"
ocaml_stdlib="`"$OCAMLFIND" ocamlc -where`"
if test "$LLVM_PREFIX" '<' "$ocaml_stdlib" -a "$ocaml_stdlib" '<' "$LLVM_PREFIX~"
then
# ocaml stdlib is beneath our prefix; use stdlib
@ -1912,6 +1943,19 @@ for a_binding in $BINDINGS_TO_BUILD ; do
fi
fi
;;
go)
if test "x$GO" = x ; then
AC_MSG_WARN([--enable-bindings=go specified, but go not found. Try configure GO=/path/to/go])
binding_prereqs_failed=1
else
if $GO run ${srcdir}/bindings/go/conftest.go ; then
:
else
AC_MSG_WARN([--enable-bindings=go specified, but need at least Go 1.2. Try configure GO=/path/to/go])
binding_prereqs_failed=1
fi
fi
;;
esac
done
if test "$binding_prereqs_failed" = 1 ; then
@ -1973,6 +2017,11 @@ if test "${clang_src_root}" = ""; then
clang_src_root="$srcdir/tools/clang"
fi
if test -f ${clang_src_root}/README.txt; then
dnl Clang supports build systems which use the multilib libdir suffix.
dnl The autoconf system doesn't support this so stub out that variable.
AC_DEFINE_UNQUOTED(CLANG_LIBDIR_SUFFIX,"",
[Multilib suffix for libdir.])
dnl Use variables to stay under 80 columns.
configh="include/clang/Config/config.h"
doxy="docs/doxygen.cfg"

View File

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

53
bindings/go/README.txt Normal file
View File

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

28
bindings/go/build.sh Executable file
View File

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

16
bindings/go/conftest.go Normal file
View File

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

View File

@ -0,0 +1,242 @@
//===- 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 "IRBindings.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/DIBuilder.h"
using namespace llvm;
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef)
namespace {
template <typename T> T unwrapDI(LLVMMetadataRef v) {
return v ? T(unwrap<MDNode>(v)) : T();
}
}
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(); }
LLVMMetadataRef 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);
}
LLVMMetadataRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Dref, const char *File,
const char *Dir) {
DIBuilder *D = unwrap(Dref);
DIFile F = D->createFile(File, Dir);
return wrap(F);
}
LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
LLVMMetadataRef Scope,
LLVMMetadataRef File,
unsigned Line,
unsigned Column) {
DIBuilder *D = unwrap(Dref);
DILexicalBlock LB = D->createLexicalBlock(
unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Column);
return wrap(LB);
}
LLVMMetadataRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref,
LLVMMetadataRef Scope,
LLVMMetadataRef File,
unsigned Discriminator) {
DIBuilder *D = unwrap(Dref);
DILexicalBlockFile LBF = D->createLexicalBlockFile(
unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Discriminator);
return wrap(LBF);
}
LLVMMetadataRef LLVMDIBuilderCreateFunction(
LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name,
const char *LinkageName, LLVMMetadataRef File, unsigned Line,
LLVMMetadataRef 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);
}
LLVMMetadataRef LLVMDIBuilderCreateLocalVariable(
LLVMDIBuilderRef Dref, unsigned Tag, LLVMMetadataRef Scope,
const char *Name, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef 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);
}
LLVMMetadataRef 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);
}
LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
LLVMMetadataRef 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);
}
LLVMMetadataRef
LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref, LLVMMetadataRef File,
LLVMMetadataRef ParameterTypes) {
DIBuilder *D = unwrap(Dref);
DICompositeType CT = D->createSubroutineType(
unwrapDI<DIFile>(File), unwrapDI<DITypeArray>(ParameterTypes));
return wrap(CT);
}
LLVMMetadataRef LLVMDIBuilderCreateStructType(
LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name,
LLVMMetadataRef File, unsigned Line, uint64_t SizeInBits,
uint64_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom,
LLVMMetadataRef 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);
}
LLVMMetadataRef
LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef Dref, LLVMMetadataRef Scope,
const char *Name, LLVMMetadataRef File,
unsigned Line, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, LLVMMetadataRef 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);
}
LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref,
uint64_t SizeInBits,
uint64_t AlignInBits,
LLVMMetadataRef ElementType,
LLVMMetadataRef Subscripts) {
DIBuilder *D = unwrap(Dref);
DICompositeType CT =
D->createArrayType(SizeInBits, AlignInBits, unwrapDI<DIType>(ElementType),
unwrapDI<DIArray>(Subscripts));
return wrap(CT);
}
LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref,
LLVMMetadataRef Ty, const char *Name,
LLVMMetadataRef File, unsigned Line,
LLVMMetadataRef Context) {
DIBuilder *D = unwrap(Dref);
DIDerivedType DT =
D->createTypedef(unwrapDI<DIType>(Ty), Name, unwrapDI<DIFile>(File), Line,
unwrapDI<DIDescriptor>(Context));
return wrap(DT);
}
LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Dref,
int64_t Lo, int64_t Count) {
DIBuilder *D = unwrap(Dref);
DISubrange S = D->getOrCreateSubrange(Lo, Count);
return wrap(S);
}
LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref,
LLVMMetadataRef *Data,
size_t Length) {
DIBuilder *D = unwrap(Dref);
Metadata **DataValue = unwrap(Data);
ArrayRef<Metadata *> Elements(DataValue, Length);
DIArray A = D->getOrCreateArray(Elements);
return wrap(A);
}
LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref,
LLVMMetadataRef *Data,
size_t Length) {
DIBuilder *D = unwrap(Dref);
Metadata **DataValue = unwrap(Data);
ArrayRef<Metadata *> Elements(DataValue, Length);
DITypeArray A = D->getOrCreateTypeArray(Elements);
return wrap(A);
}
LLVMMetadataRef 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,
LLVMMetadataRef VarInfo,
LLVMMetadataRef Expr,
LLVMBasicBlockRef Block) {
DIBuilder *D = unwrap(Dref);
Instruction *Instr =
D->insertDeclare(unwrap(Storage), unwrapDI<DIVariable>(VarInfo),
unwrapDI<DIExpression>(Expr), unwrap(Block));
return wrap(Instr);
}
LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef Dref,
LLVMValueRef Val, uint64_t Offset,
LLVMMetadataRef VarInfo,
LLVMMetadataRef Expr,
LLVMBasicBlockRef Block) {
DIBuilder *D = unwrap(Dref);
Instruction *Instr = D->insertDbgValueIntrinsic(
unwrap(Val), Offset, unwrapDI<DIVariable>(VarInfo),
unwrapDI<DIExpression>(Expr), unwrap(Block));
return wrap(Instr);
}

View File

@ -0,0 +1,135 @@
//===- 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"
#include "IRBindings.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);
LLVMMetadataRef
LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef D, unsigned Language,
const char *File, const char *Dir,
const char *Producer, int Optimized,
const char *Flags, unsigned RuntimeVersion);
LLVMMetadataRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef D, const char *File,
const char *Dir);
LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef D,
LLVMMetadataRef Scope,
LLVMMetadataRef File,
unsigned Line, unsigned Column);
LLVMMetadataRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef D,
LLVMMetadataRef Scope,
LLVMMetadataRef File,
unsigned Discriminator);
LLVMMetadataRef LLVMDIBuilderCreateFunction(
LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name,
const char *LinkageName, LLVMMetadataRef File, unsigned Line,
LLVMMetadataRef CompositeType, int IsLocalToUnit, int IsDefinition,
unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Function);
LLVMMetadataRef LLVMDIBuilderCreateLocalVariable(
LLVMDIBuilderRef D, unsigned Tag, LLVMMetadataRef Scope, const char *Name,
LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve,
unsigned Flags, unsigned ArgNo);
LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef D,
const char *Name,
uint64_t SizeInBits,
uint64_t AlignInBits,
unsigned Encoding);
LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef D,
LLVMMetadataRef PointeeType,
uint64_t SizeInBits,
uint64_t AlignInBits,
const char *Name);
LLVMMetadataRef
LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef D, LLVMMetadataRef File,
LLVMMetadataRef ParameterTypes);
LLVMMetadataRef LLVMDIBuilderCreateStructType(
LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name,
LLVMMetadataRef File, unsigned Line, uint64_t SizeInBits,
uint64_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom,
LLVMMetadataRef ElementTypes);
LLVMMetadataRef
LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef D, LLVMMetadataRef Scope,
const char *Name, LLVMMetadataRef File,
unsigned Line, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, LLVMMetadataRef Ty);
LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef D,
uint64_t SizeInBits,
uint64_t AlignInBits,
LLVMMetadataRef ElementType,
LLVMMetadataRef Subscripts);
LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef D,
LLVMMetadataRef Ty, const char *Name,
LLVMMetadataRef File, unsigned Line,
LLVMMetadataRef Context);
LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef D, int64_t Lo,
int64_t Count);
LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef D,
LLVMMetadataRef *Data,
size_t Length);
LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef D,
LLVMMetadataRef *Data,
size_t Length);
LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref,
int64_t *Addr, size_t Length);
LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef D,
LLVMValueRef Storage,
LLVMMetadataRef VarInfo,
LLVMMetadataRef Expr,
LLVMBasicBlockRef Block);
LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef D, LLVMValueRef Val,
uint64_t Offset,
LLVMMetadataRef VarInfo,
LLVMMetadataRef Expr,
LLVMBasicBlockRef Block);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -0,0 +1,100 @@
//===- 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/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.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);
}
LLVMMetadataRef LLVMConstantAsMetadata(LLVMValueRef C) {
return wrap(ConstantAsMetadata::get(unwrap<Constant>(C)));
}
LLVMMetadataRef LLVMMDString2(LLVMContextRef C, const char *Str, unsigned SLen) {
return wrap(MDString::get(*unwrap(C), StringRef(Str, SLen)));
}
LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs,
unsigned Count) {
return wrap(
MDNode::get(*unwrap(C), ArrayRef<Metadata *>(unwrap(MDs), Count)));
}
LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs,
unsigned Count) {
return wrap(MDNode::getTemporary(*unwrap(C),
ArrayRef<Metadata *>(unwrap(MDs), Count)));
}
void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name,
LLVMMetadataRef Val) {
NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name);
if (!N)
return;
if (!Val)
return;
N->addOperand(unwrap<MDNode>(Val));
}
void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) {
MDNode *N = MD ? unwrap<MDNode>(MD) : nullptr;
unwrap<Instruction>(Inst)->setMetadata(KindID, N);
}
void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New) {
auto *Node = unwrap<MDNodeFwdDecl>(MD);
Node->replaceAllUsesWith(unwrap<MDNode>(New));
MDNode::deleteTemporary(Node);
}
void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Bref, unsigned Line,
unsigned Col, LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt) {
unwrap(Bref)->SetCurrentDebugLocation(
DebugLoc::get(Line, Col, Scope ? unwrap<MDNode>(Scope) : nullptr,
InlinedAt ? unwrap<MDNode>(InlinedAt) : nullptr));
}

View File

@ -0,0 +1,73 @@
//===- 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"
#ifdef __cplusplus
#include "llvm/IR/Metadata.h"
#include "llvm/Support/CBindingWrapping.h"
#endif
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
// 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);
LLVMMetadataRef LLVMConstantAsMetadata(LLVMValueRef Val);
LLVMMetadataRef LLVMMDString2(LLVMContextRef C, const char *Str, unsigned SLen);
LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs,
unsigned Count);
LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs,
unsigned Count);
void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name,
LLVMMetadataRef Val);
void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD);
void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New);
void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Bref, unsigned Line,
unsigned Col, LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt);
#ifdef __cplusplus
}
namespace llvm {
DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
inline Metadata **unwrap(LLVMMetadataRef *Vals) {
return reinterpret_cast<Metadata**>(Vals);
}
}
#endif
#endif

View File

@ -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));
}

View File

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

View File

@ -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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,491 @@
//===- 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) Metadata {
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 Metadata{C: result}
}
// CreateCompileUnit creates file debug metadata.
func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
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 Metadata{C: result}
}
// DILexicalBlock holds the values for creating lexical block debug metadata.
type DILexicalBlock struct {
File Metadata
Line int
Column int
}
// CreateCompileUnit creates lexical block debug metadata.
func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
result := C.LLVMDIBuilderCreateLexicalBlock(
d.ref,
diScope.C,
b.File.C,
C.unsigned(b.Line),
C.unsigned(b.Column),
)
return Metadata{C: result}
}
func (d *DIBuilder) CreateLexicalBlockFile(diScope Metadata, diFile Metadata, discriminator int) Metadata {
result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
C.unsigned(discriminator))
return Metadata{C: result}
}
// DIFunction holds the values for creating function debug metadata.
type DIFunction struct {
Name string
LinkageName string
File Metadata
Line int
Type Metadata
LocalToUnit bool
IsDefinition bool
ScopeLine int
Flags int
Optimized bool
Function Value
}
// CreateCompileUnit creates function debug metadata.
func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata {
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 Metadata{C: result}
}
// DILocalVariable holds the values for creating local variable debug metadata.
type DILocalVariable struct {
Tag dwarf.Tag
Name string
File Metadata
Line int
Type Metadata
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 Metadata, v DILocalVariable) Metadata {
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 Metadata{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) Metadata {
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 Metadata{C: result}
}
// DIPointerType holds the values for creating pointer type debug metadata.
type DIPointerType struct {
Pointee Metadata
SizeInBits uint64
AlignInBits uint64 // optional
Name string // optional
}
// CreateBasicType creates basic type debug metadata.
func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
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 Metadata{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 Metadata
// Parameters contains the subroutine parameter types,
// including the return type at the 0th index.
Parameters []Metadata
}
// CreateSubroutineType creates subroutine type debug metadata.
func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
params := d.getOrCreateTypeArray(t.Parameters)
result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C)
return Metadata{C: result}
}
// DIStructType holds the values for creating struct type debug metadata.
type DIStructType struct {
Name string
File Metadata
Line int
SizeInBits uint64
AlignInBits uint64
Flags int
DerivedFrom Metadata
Elements []Metadata
}
// CreateStructType creates struct type debug metadata.
func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
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 Metadata{C: result}
}
// DIMemberType holds the values for creating member type debug metadata.
type DIMemberType struct {
Name string
File Metadata
Line int
SizeInBits uint64
AlignInBits uint64
OffsetInBits uint64
Flags int
Type Metadata
}
// CreateMemberType creates struct type debug metadata.
func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
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 Metadata{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 Metadata
Subscripts []DISubrange
}
// CreateArrayType creates struct type debug metadata.
func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
subscriptsSlice := make([]Metadata, 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 Metadata{C: result}
}
// DITypedef holds the values for creating typedef type debug metadata.
type DITypedef struct {
Type Metadata
Name string
File Metadata
Line int
Context Metadata
}
// CreateTypedef creates typedef type debug metadata.
func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
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 Metadata{C: result}
}
// getOrCreateSubrange gets a metadata node for the specified subrange,
// creating if required.
func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
return Metadata{C: result}
}
// getOrCreateArray gets a metadata node containing the specified values,
// creating if required.
func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
if len(values) == 0 {
return Metadata{}
}
data, length := llvmMetadataRefs(values)
result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
return Metadata{C: result}
}
// getOrCreateTypeArray gets a metadata node for a type array containing the
// specified values, creating if required.
func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
if len(values) == 0 {
return Metadata{}
}
data, length := llvmMetadataRefs(values)
result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
return Metadata{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) Metadata {
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 Metadata{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 Value, diVarInfo, expr Metadata, bb BasicBlock) Value {
result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
return Value{C: result}
}
// InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
// specified basic block for the given value and associated debug metadata.
func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, offset uint64, bb BasicBlock) Value {
result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, C.uint64_t(offset), diVarInfo.C, expr.C, bb.C)
return Value{C: result}
}
func boolToCInt(v bool) C.int {
if v {
return 1
}
return 0
}

View File

@ -0,0 +1,177 @@
//===- 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 {
C C.struct_LLVMMCJITCompilerOptions
}
func (options *MCJITCompilerOptions) SetMCJITOptimizationLevel(level uint) {
options.C.OptLevel = C.uint(level)
}
func (options *MCJITCompilerOptions) SetMCJITNoFramePointerElim(nfp bool) {
options.C.NoFramePointerElim = boolToLLVMBool(nfp)
}
func (options *MCJITCompilerOptions) SetMCJITEnableFastISel(fastisel bool) {
options.C.EnableFastISel = boolToLLVMBool(fastisel)
}
func (options *MCJITCompilerOptions) SetMCJITCodeModel(CodeModel CodeModel) {
options.C.CodeModel = C.LLVMCodeModel(CodeModel)
}
// 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 NewMCJITCompilerOptions() MCJITCompilerOptions {
var options C.struct_LLVMMCJITCompilerOptions
C.LLVMInitializeMCJITCompilerOptions(&options, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{})))
return MCJITCompilerOptions{options}
}
func NewMCJITCompiler(m Module, options MCJITCompilerOptions) (ee ExecutionEngine, err error) {
var cmsg *C.char
fail := C.LLVMCreateMCJITCompilerForModule(&ee.C, m.C, &options.C, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{})), &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)
}

View File

@ -0,0 +1,98 @@
//===- 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
}
options := NewMCJITCompilerOptions()
options.SetMCJITOptimizationLevel(2)
options.SetMCJITEnableFastISel(true)
options.SetMCJITNoFramePointerElim(true)
options.SetMCJITCodeModel(CodeModelJITDefault)
engine, err := NewMCJITCompiler(mod, options)
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))
}
}

1846
bindings/go/llvm/ir.go Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,32 @@
//===- 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"
func LinkModules(Dest, Src Module) error {
var cmsg *C.char
failed := C.LLVMLinkModules(Dest.C, Src.C, 0, &cmsg)
if failed != 0 {
err := errors.New(C.GoString(cmsg))
C.LLVMDisposeMessage(cmsg)
return err
}
return nil
}

View File

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

View File

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

105
bindings/go/llvm/string.go Normal file
View File

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

View File

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

View File

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

300
bindings/go/llvm/target.go Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,11 @@
add_subdirectory(llvm)
add_subdirectory(all_backends)
add_subdirectory(analysis)
add_subdirectory(backends)
add_subdirectory(bitreader)
add_subdirectory(bitwriter)
add_subdirectory(irreader)
add_subdirectory(linker)
add_subdirectory(target)
add_subdirectory(transforms)
add_subdirectory(executionengine)

View File

@ -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 := ../..

View File

@ -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
@ -29,6 +32,12 @@ endif
include $(LEVEL)/Makefile.common
# Used in out-of-tree builds of OCaml bindings only.
ifdef SYSTEM_LLVM_CONFIG
LLVM_CONFIG = $(SYSTEM_LLVM_CONFIG)
LLVMLibsOptions += $(shell $(LLVM_CONFIG) --ldflags)
endif
# Intentionally ignore PROJ_prefix here. We want the ocaml stdlib. However, the
# user can override this with OCAML_LIBDIR or configure --with-ocaml-libdir=.
PROJ_libocamldir := $(DESTDIR)$(OCAML_LIBDIR)
@ -50,64 +59,61 @@ 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
# See http://caml.inria.fr/mantis/view.php?id=6642
OCAMLORIGIN := -ccopt -L'$$CAMLORIGIN/..' \
-ccopt $(RPATH) -ccopt -Wl,'$$CAMLORIGIN/..'
# 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)
ifneq ($(DEBUG_SYMBOLS),1)
OCAMLDEBUGFLAG := -g
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
# 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
# -dllib is engaged with ocamlc builds, $(OCAMLSTUBFLAGS) in ocamlc -custom builds.
Archive.CMA := $(strip $(OCAMLFIND) c -a -dllib -l$(LIBRARYNAME) $(OCAMLSTUBFLAGS) \
$(OCAMLDEBUGFLAG) $(OCAMLORIGIN) -o)
else
Archive.CMA := $(strip $(OCAMLFIND) c -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
$(OCAMLORIGIN) -o)
endif
ifdef OCAMLSTUBS
Archive.CMA := $(strip $(OCAMLC) -a -dllib -l$(LIBRARYNAME) $(OCAMLDEBUGFLAG) \
-o)
Archive.CMXA := $(strip $(OCAMLFIND) opt -a $(OCAMLSTUBFLAGS) $(OCAMLDEBUGFLAG) \
$(OCAMLORIGIN) -o)
else
Archive.CMA := $(strip $(OCAMLC) -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
-o)
endif
ifdef OCAMLSTUBS
Archive.CMXA := $(strip $(OCAMLOPT) -a $(patsubst %,-cclib %, \
$(LLVMLibsOptions) -l$(LIBRARYNAME) \
-L$(SharedLibDir) $(OCAMLRPATH)) \
$(OCAMLDEBUGFLAG) -o)
else
Archive.CMXA := $(strip $(OCAMLOPT) -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) -o)
endif
ifdef OCAMLOPT
Archive.EXE := $(strip $(OCAMLOPT) -cc $(CXX) $(OCAMLCFLAGS) $(UsedOcamlLibs:%=%.cmxa) $(OCAMLDEBUGFLAG) -o)
else
Archive.EXE := $(strip $(OCAMLC) -cc $(CXX) $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG:%=%.cma) -o)
Archive.CMXA := $(strip $(OCAMLFIND) opt -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
$(OCAMLORIGIN) -o)
endif
# Source files
@ -191,7 +197,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 +205,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 +231,7 @@ install-a:: $(LibraryA)
$(Echo) "Installing $(BuildMode) $(DestA)"
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) $(INSTALL) $(LibraryA) $(DestA)
$(Verb)
$(Verb)
uninstall-a::
$(Echo) "Uninstalling $(DestA)"
@ -243,8 +249,8 @@ uninstall-local:: uninstall-shared
$(SharedLib): $(ObjectsO) $(OcamlDir)/.dir
$(Echo) "Building $(BuildMode) $(notdir $@)"
$(Verb) $(Link) $(SharedLinkOptions) $(OCAMLRPATH) $(LLVMLibsOptions) \
-o $@ $(ObjectsO)
$(Verb) $(Link) $(SharedLinkOptions) $(OCAMLRPATH) -o $@ $(ObjectsO) \
$(LLVMLibsOptions)
clean-shared::
-$(Verb) $(RM) -f $(SharedLib)
@ -261,8 +267,9 @@ uninstall-shared::
endif
##===- Deposit dependent libraries adjacent to Ocaml libs -----------------===##
##===- Deposit dependent libraries adjacent to OCaml libs -----------------===##
ifndef SYSTEM_LLVM_CONFIG
all-local:: build-deplibs
clean-local:: clean-deplibs
install-local:: install-deplibs
@ -287,7 +294,7 @@ install-deplibs:
uninstall-deplibs:
$(Verb) $(RM) -f $(DestLibs)
endif
##===- Build ocaml interfaces (.mli's -> .cmi's) --------------------------===##
@ -368,8 +375,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 +426,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 +441,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 +471,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 \

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_all_backends
OCAML llvm_all_backends
OCAMLDEP llvm
C all_backends_ocaml
LLVM ${LLVM_TARGETS_TO_BUILD})

View File

@ -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.
#
##===----------------------------------------------------------------------===##

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_analysis
OCAML llvm_analysis
OCAMLDEP llvm
C analysis_ocaml
LLVM analysis)

View File

@ -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 := ../../..

View File

@ -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);
}

View File

@ -1,4 +1,4 @@
(*===-- llvm_analysis.ml - LLVM OCaml Interface -----------------*- C++ -*-===*
(*===-- llvm_analysis.ml - LLVM OCaml Interface ---------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*

View File

@ -1,4 +1,4 @@
(*===-- llvm_analysis.mli - LLVM OCaml Interface ----------------*- C++ -*-===*
(*===-- llvm_analysis.mli - LLVM OCaml Interface --------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*

View File

@ -0,0 +1,27 @@
foreach(TARGET ${LLVM_TARGETS_TO_BUILD})
set(OCAML_LLVM_TARGET ${TARGET})
foreach( ext ml mli )
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/llvm_backend.${ext}.in"
"${CMAKE_CURRENT_BINARY_DIR}/llvm_${TARGET}.${ext}")
endforeach()
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/backend_ocaml.c"
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_ocaml.c")
add_ocaml_library(llvm_${TARGET}
OCAML llvm_${TARGET}
C ${TARGET}_ocaml
CFLAGS -DTARGET=${TARGET}
LLVM ${TARGET}
NOCOPY)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/META.llvm_backend.in"
"${LLVM_LIBRARY_DIR}/ocaml/META.llvm_${TARGET}")
install(FILES "${LLVM_LIBRARY_DIR}/ocaml/META.llvm_${TARGET}"
DESTINATION lib/ocaml)
endforeach()

View File

@ -5,4 +5,3 @@ requires = "llvm"
archive(byte) = "llvm_@TARGET@.cma"
archive(native) = "llvm_@TARGET@.cmxa"
directory = "."
linkopts = "-ccopt -lstdc++"

View File

@ -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) { \

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_bitreader
OCAML llvm_bitreader
OCAMLDEP llvm
C bitreader_ocaml
LLVM bitreader)

View File

@ -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 := ../../..

View File

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

View File

@ -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 "")
let () = Callback.register_exception "Llvm_bitreader.Error" (Error "")
external get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
= "llvm_get_module"
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"

View File

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

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_bitwriter
OCAML llvm_bitwriter
OCAMLDEP llvm
C bitwriter_ocaml
LLVM bitwriter)

View File

@ -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 := ../../..

View File

@ -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);
}

View File

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

View File

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

View File

@ -0,0 +1,6 @@
add_ocaml_library(llvm_executionengine
OCAML llvm_executionengine
OCAMLDEP llvm llvm_target
C executionengine_ocaml
LLVM executionengine mcjit native
PKG ctypes)

View File

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

View File

@ -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());
CAMLprim value llvm_ee_initialize(value Unit) {
LLVMLinkInMCJIT();
return Val_bool(!LLVMInitializeNativeTarget() &&
!LLVMInitializeNativeAsmParser() &&
!LLVMInitializeNativeAsmPrinter());
}
/* 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;
}
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
}
/*--... 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;
/* llmodule -> llcompileroption -> ExecutionEngine.t */
CAMLprim LLVMExecutionEngineRef llvm_ee_create(value OptRecordOpt, LLVMModuleRef M) {
value OptRecord;
LLVMExecutionEngineRef MCJIT;
char *Error;
if (LLVMCreateExecutionEngineForModule(&Interp, M, &Error))
llvm_raise(llvm_ee_error_exn, Error);
return Interp;
}
struct LLVMMCJITCompilerOptions Options;
/* llmodule -> ExecutionEngine.t */
CAMLprim LLVMExecutionEngineRef
llvm_ee_create_interpreter(LLVMModuleRef M) {
LLVMExecutionEngineRef Interp;
char *Error;
if (LLVMCreateInterpreterForModule(&Interp, M, &Error))
llvm_raise(llvm_ee_error_exn, Error);
return Interp;
}
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,35 @@ 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;
}
CAMLprim value llvm_ee_get_global_value_address(value Name,
LLVMExecutionEngineRef EE) {
return caml_copy_int64((int64_t) LLVMGetGlobalValueAddress(EE, String_val(Name)));
}
CAMLprim value llvm_ee_get_function_address(value Name,
LLVMExecutionEngineRef EE) {
return caml_copy_int64((int64_t) LLVMGetFunctionAddress(EE, String_val(Name)));
}

View File

@ -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,66 @@
*
*===----------------------------------------------------------------------===*)
exception Error of string
external register_exns: exn -> unit
= "llvm_register_ee_exns"
let () = Callback.register_exception "Llvm_executionengine.Error" (Error "")
external initialize : unit -> bool
= "llvm_ee_initialize"
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
type llexecutionengine
type llcompileroptions = {
opt_level: int;
code_model: Llvm_target.CodeModel.t;
no_framepointer_elim: bool;
enable_fast_isel: bool;
}
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"
let default_compiler_options = {
opt_level = 0;
code_model = Llvm_target.CodeModel.JITDefault;
no_framepointer_elim = false;
enable_fast_isel = false }
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 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_global_value_address_ : string -> llexecutionengine -> int64
= "llvm_ee_get_global_value_address"
external get_function_address_ : string -> llexecutionengine -> int64
= "llvm_ee_get_function_address"
external initialize_native_target : unit -> bool
= "llvm_initialize_native_target"
let add_global_mapping llval ptr ee =
add_global_mapping_ llval (Ctypes.raw_address_of_ptr (Ctypes.to_voidp ptr)) ee
let get_global_value_address name typ ee =
let vptr = get_global_value_address_ name ee in
if Int64.to_int vptr <> 0 then
let open Ctypes in !@ (coerce (ptr void) (ptr typ) (ptr_of_raw_address vptr))
else
raise (Error ("Value " ^ name ^ " not found"))
let get_function_address name typ ee =
let fptr = get_function_address_ name ee in
if Int64.to_int fptr <> 0 then
let open Ctypes in coerce (ptr void) typ (ptr_of_raw_address fptr)
else
raise (Error ("Function " ^ name ^ " not found"))
(* The following are not bound. Patches are welcome.
target_machine : llexecutionengine -> Llvm_target.TargetMachine.t
*)

View File

@ -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,84 @@
(** 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
(** [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
(** [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
(** 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
(** [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
(** 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
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
(** [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].
(** [dispose ee] releases the memory used by the execution engine and must be
invoked to avoid memory leaks. *)
val dispose : t -> unit
Run {!initialize} before using this function.
(** [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
See the function [llvm::EngineBuilder::create]. *)
val create : ?options:llcompileroptions -> Llvm.llmodule -> llexecutionengine
(** [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
(** [dispose ee] releases the memory used by the execution engine and must be
invoked to avoid memory leaks. *)
val dispose : llexecutionengine -> unit
(** [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
(** [add_module m ee] adds the module [m] to the execution engine [ee]. *)
val add_module : Llvm.llmodule -> llexecutionengine -> unit
(** [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
(** [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
(** [data_layout ee] is the data layout of the execution engine [ee]. *)
val data_layout : t -> Llvm_target.DataLayout.t
end
(** [run_static_ctors ee] executes the static constructors of each module in
the execution engine [ee]. *)
val run_static_ctors : llexecutionengine -> unit
(** [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
(** [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_global_value_address id typ ee] returns a pointer to the
identifier [id] as type [typ], which will be a pointer type for a
value, and which will be live as long as [id] and [ee]
are. Caution: this function finalizes, i.e. forces code
generation, all loaded modules. Further modifications to the
modules will not have any effect. *)
val get_global_value_address : string -> 'a Ctypes.typ -> llexecutionengine -> 'a
(** [get_function_address fn typ ee] returns a pointer to the function
[fn] as type [typ], which will be a pointer type for a function
(e.g. [(int -> int) typ]), and which will be live as long as [fn]
and [ee] are. Caution: this function finalizes, i.e. forces code
generation, all loaded modules. Further modifications to the
modules will not have any effect. *)
val get_function_address : string -> 'a Ctypes.typ -> llexecutionengine -> 'a

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_irreader
OCAML llvm_irreader
OCAMLDEP llvm
C irreader_ocaml
LLVM irreader)

View File

@ -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);
}

View File

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

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_linker
OCAML llvm_linker
OCAMLDEP llvm
C linker_ocaml
LLVM linker)

View File

@ -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 */
CAMLprim value llvm_link_modules(LLVMModuleRef Dst, LLVMModuleRef Src, value Mode) {
/* llmodule -> llmodule -> unit */
CAMLprim value llvm_link_modules(LLVMModuleRef Dst, LLVMModuleRef Src) {
char* Message;
if (LLVMLinkModules(Dst, Src, Int_val(Mode), &Message))
llvm_raise(llvm_linker_error_exn, Message);
if (LLVMLinkModules(Dst, Src, 0, &Message))
llvm_raise(*caml_named_value("Llvm_linker.Error"), Message);
return Val_unit;
}

View File

@ -9,14 +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 =
| DestroySource
| PreserveSource
end
external link_modules : Llvm.llmodule -> Llvm.llmodule -> Mode.t -> unit
= "llvm_link_modules"
external link_modules : Llvm.llmodule -> Llvm.llmodule -> unit
= "llvm_link_modules"

View File

@ -14,13 +14,6 @@
exception Error of string
(** Linking mode. *)
module Mode : sig
type t =
| DestroySource
| PreserveSource
end
(** [link_modules dst src mode] links [src] into [dst], raising [Error]
if the linking fails. *)
val link_modules : Llvm.llmodule -> Llvm.llmodule -> Mode.t -> unit
val link_modules : Llvm.llmodule -> Llvm.llmodule -> unit

View File

@ -0,0 +1,11 @@
add_ocaml_library(llvm
OCAML llvm
C llvm_ocaml
LLVM core support)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/META.llvm.in"
"${LLVM_LIBRARY_DIR}/ocaml/META.llvm")
install(FILES "${LLVM_LIBRARY_DIR}/ocaml/META.llvm"
DESTINATION lib/ocaml)

View File

@ -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"
@ -62,6 +61,14 @@ package "scalar_opts" (
archive(native) = "llvm_scalar_opts.cmxa"
)
package "transform_utils" (
requires = "llvm"
version = "@PACKAGE_VERSION@"
description = "Transform utilities for LLVM"
archive(byte) = "llvm_transform_utils.cma"
archive(native) = "llvm_transform_utils.cmxa"
)
package "vectorize" (
requires = "llvm"
version = "@PACKAGE_VERSION@"

View File

@ -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
UsedOcamlLibs := llvm
ExtraLibs := -lstdc++
include ../Makefile.ocaml

View File

@ -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
@ -428,6 +436,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"
@ -450,6 +459,7 @@ external clear_metadata : llvalue -> llmdkind -> unit = "llvm_clear_metadata"
(*--... Operations on metadata .......,.....................................--*)
external mdstring : llcontext -> string -> llvalue = "llvm_mdstring"
external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode"
external mdnull : llcontext -> llvalue = "llvm_mdnull"
external get_mdstring : llvalue -> string option = "llvm_get_mdstring"
external get_named_metadata : llmodule -> string -> llvalue array
= "llvm_get_namedmd"
@ -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"

View File

@ -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
@ -651,7 +668,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 +699,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 +731,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]. *)
@ -797,6 +819,9 @@ val mdstring : llcontext -> string -> llvalue
See the method [llvm::MDNode::get]. *)
val mdnode : llcontext -> llvalue array -> llvalue
(** [mdnull c ] returns a null MDNode in context [c]. *)
val mdnull : llcontext -> llvalue
(** [get_mdstring v] returns the MDString.
See the method [llvm::MDString::getString] *)
val get_mdstring : llvalue -> string option
@ -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]. *)

View File

@ -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>
value llvm_string_of_message(char* Message) {
value String = caml_copy_string(Message);
LLVMDisposeMessage(Message);
/* 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);
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);
@ -657,6 +666,11 @@ CAMLprim LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) {
Wosize_val(ElementVals));
}
/* llcontext -> llvalue */
CAMLprim LLVMValueRef llvm_mdnull(LLVMContextRef C) {
return NULL;
}
/* llvalue -> string option */
CAMLprim value llvm_get_mdstring(LLVMValueRef V) {
CAMLparam0();
@ -695,7 +709,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 +743,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 +818,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 +942,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 +962,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 +1223,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 +1400,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 +1477,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 +1530,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 +1562,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 +1598,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 +2174,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 +2187,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 +2223,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 +2275,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 +2288,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);

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_target
OCAML llvm_target
OCAMLDEP llvm
C target_ocaml
LLVM target)

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
add_subdirectory(ipo)
add_subdirectory(passmgr_builder)
add_subdirectory(scalar_opts)
add_subdirectory(utils)
add_subdirectory(vectorize)

View File

@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL := ../../..
DIRS = scalar ipo vectorize passmgr_builder
DIRS = ipo passmgr_builder scalar_opts utils vectorize
ocamldoc:
$(Verb) for i in $(DIRS) ; do \

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_ipo
OCAML llvm_ipo
OCAMLDEP llvm
C ipo_ocaml
LLVM ipo)

View File

@ -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.
#
##===----------------------------------------------------------------------===##

View File

@ -55,12 +55,6 @@ CAMLprim value llvm_add_always_inliner(LLVMPassManagerRef PM) {
return Val_unit;
}
/* [`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);
@ -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;

View File

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

View File

@ -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 the [llvm::createAddArgumentPromotionPass] function. *)
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 the [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 the [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 the [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 the [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 the [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 the [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 the [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 the [llvm::createIPConstantPropagationPass] function. *)
external add_ipc_propagation
: [ `Module ] Llvm.PassManager.t -> unit
= "llvm_add_ip_constant_propagation"
(** See llvm::createPruneEHPass function. *)
external add_prune_eh : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_prune_eh"
(** See the [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 the [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 the [llvm::createInternalizePass] function. *)
external add_internalize
: [ `Module ] Llvm.PassManager.t -> all_but_main: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 the [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::createStripSymbolsPass] function. *)
external add_strip_symbols
: [ `Module ] Llvm.PassManager.t -> unit
= "llvm_add_strip_symbols"

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_passmgr_builder
OCAML llvm_passmgr_builder
OCAMLDEP llvm
C passmgr_builder_ocaml
LLVM ipo)

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
add_ocaml_library(llvm_scalar_opts
OCAML llvm_scalar_opts
OCAMLDEP llvm
C scalar_opts_ocaml
LLVM scalaropts)

Some files were not shown because too many files have changed in this diff Show More