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:
parent
3c7e7a1538
commit
081af4da16
1
.clang-tidy
Normal file
1
.clang-tidy
Normal file
@ -0,0 +1 @@
|
||||
Checks: '-*,clang-diagnostic-*,llvm-*,misc-*'
|
15
.gitignore
vendored
15
.gitignore
vendored
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
12
CREDITS.TXT
12
CREDITS.TXT
@ -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.
|
||||
|
||||
|
@ -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@
|
||||
|
@ -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 ; \
|
||||
|
@ -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
4
autoconf/config.sub
vendored
@ -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-* \
|
||||
|
@ -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"
|
||||
|
@ -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
53
bindings/go/README.txt
Normal 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
28
bindings/go/build.sh
Executable 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
16
bindings/go/conftest.go
Normal 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)
|
||||
}
|
242
bindings/go/llvm/DIBuilderBindings.cpp
Normal file
242
bindings/go/llvm/DIBuilderBindings.cpp
Normal 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);
|
||||
}
|
135
bindings/go/llvm/DIBuilderBindings.h
Normal file
135
bindings/go/llvm/DIBuilderBindings.h
Normal 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
|
100
bindings/go/llvm/IRBindings.cpp
Normal file
100
bindings/go/llvm/IRBindings.cpp
Normal 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));
|
||||
}
|
73
bindings/go/llvm/IRBindings.h
Normal file
73
bindings/go/llvm/IRBindings.h
Normal 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
|
42
bindings/go/llvm/InstrumentationBindings.cpp
Normal file
42
bindings/go/llvm/InstrumentationBindings.cpp
Normal 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));
|
||||
}
|
38
bindings/go/llvm/InstrumentationBindings.h
Normal file
38
bindings/go/llvm/InstrumentationBindings.h
Normal 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
|
27
bindings/go/llvm/SupportBindings.cpp
Normal file
27
bindings/go/llvm/SupportBindings.cpp
Normal 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);
|
||||
}
|
||||
}
|
30
bindings/go/llvm/SupportBindings.h
Normal file
30
bindings/go/llvm/SupportBindings.h
Normal 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
|
68
bindings/go/llvm/analysis.go
Normal file
68
bindings/go/llvm/analysis.go
Normal 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) }
|
50
bindings/go/llvm/bitreader.go
Normal file
50
bindings/go/llvm/bitreader.go
Normal 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
|
||||
}
|
39
bindings/go/llvm/bitwriter.go
Normal file
39
bindings/go/llvm/bitwriter.go
Normal 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
|
491
bindings/go/llvm/dibuilder.go
Normal file
491
bindings/go/llvm/dibuilder.go
Normal 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
|
||||
}
|
177
bindings/go/llvm/executionengine.go
Normal file
177
bindings/go/llvm/executionengine.go
Normal 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)
|
||||
}
|
98
bindings/go/llvm/executionengine_test.go
Normal file
98
bindings/go/llvm/executionengine_test.go
Normal 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
1846
bindings/go/llvm/ir.go
Normal file
File diff suppressed because it is too large
Load Diff
95
bindings/go/llvm/ir_test.go
Normal file
95
bindings/go/llvm/ir_test.go
Normal 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)
|
||||
}
|
||||
}
|
32
bindings/go/llvm/linker.go
Normal file
32
bindings/go/llvm/linker.go
Normal 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
|
||||
}
|
12
bindings/go/llvm/llvm_config.go.in
Normal file
12
bindings/go/llvm/llvm_config.go.in
Normal 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)
|
19
bindings/go/llvm/llvm_dep.go
Normal file
19
bindings/go/llvm/llvm_dep.go
Normal 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
105
bindings/go/llvm/string.go
Normal 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
|
||||
}
|
28
bindings/go/llvm/string_test.go
Normal file
28
bindings/go/llvm/string_test.go
Normal 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)
|
||||
}
|
||||
}
|
54
bindings/go/llvm/support.go
Normal file
54
bindings/go/llvm/support.go
Normal 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
300
bindings/go/llvm/target.go
Normal 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
|
||||
}
|
43
bindings/go/llvm/transforms_instrumentation.go
Normal file
43
bindings/go/llvm/transforms_instrumentation.go
Normal 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)
|
||||
}
|
42
bindings/go/llvm/transforms_ipo.go
Normal file
42
bindings/go/llvm/transforms_ipo.go
Normal 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) }
|
48
bindings/go/llvm/transforms_pmbuilder.go
Normal file
48
bindings/go/llvm/transforms_pmbuilder.go
Normal 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)
|
||||
}
|
45
bindings/go/llvm/transforms_scalar.go
Normal file
45
bindings/go/llvm/transforms_scalar.go
Normal 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) }
|
21
bindings/go/llvm/version.go
Normal file
21
bindings/go/llvm/version.go
Normal 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
|
11
bindings/ocaml/CMakeLists.txt
Normal file
11
bindings/ocaml/CMakeLists.txt
Normal 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)
|
@ -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 := ../..
|
||||
|
@ -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 \
|
||||
|
5
bindings/ocaml/all_backends/CMakeLists.txt
Normal file
5
bindings/ocaml/all_backends/CMakeLists.txt
Normal 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})
|
@ -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.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
|
5
bindings/ocaml/analysis/CMakeLists.txt
Normal file
5
bindings/ocaml/analysis/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_ocaml_library(llvm_analysis
|
||||
OCAML llvm_analysis
|
||||
OCAMLDEP llvm
|
||||
C analysis_ocaml
|
||||
LLVM analysis)
|
@ -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 := ../../..
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_analysis.ml - LLVM OCaml Interface -----------------*- C++ -*-===*
|
||||
(*===-- llvm_analysis.ml - LLVM OCaml Interface ---------------*- OCaml -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_analysis.mli - LLVM OCaml Interface ----------------*- C++ -*-===*
|
||||
(*===-- llvm_analysis.mli - LLVM OCaml Interface --------------*- OCaml -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
|
27
bindings/ocaml/backends/CMakeLists.txt
Normal file
27
bindings/ocaml/backends/CMakeLists.txt
Normal 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()
|
@ -5,4 +5,3 @@ requires = "llvm"
|
||||
archive(byte) = "llvm_@TARGET@.cma"
|
||||
archive(native) = "llvm_@TARGET@.cmxa"
|
||||
directory = "."
|
||||
linkopts = "-ccopt -lstdc++"
|
@ -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) { \
|
||||
|
5
bindings/ocaml/bitreader/CMakeLists.txt
Normal file
5
bindings/ocaml/bitreader/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_ocaml_library(llvm_bitreader
|
||||
OCAML llvm_bitreader
|
||||
OCAMLDEP llvm
|
||||
C bitreader_ocaml
|
||||
LLVM bitreader)
|
@ -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 := ../../..
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
5
bindings/ocaml/bitwriter/CMakeLists.txt
Normal file
5
bindings/ocaml/bitwriter/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_ocaml_library(llvm_bitwriter
|
||||
OCAML llvm_bitwriter
|
||||
OCAMLDEP llvm
|
||||
C bitwriter_ocaml
|
||||
LLVM bitwriter)
|
@ -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 := ../../..
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
6
bindings/ocaml/executionengine/CMakeLists.txt
Normal file
6
bindings/ocaml/executionengine/CMakeLists.txt
Normal 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)
|
@ -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
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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
|
||||
*)
|
||||
|
@ -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
|
||||
|
5
bindings/ocaml/irreader/CMakeLists.txt
Normal file
5
bindings/ocaml/irreader/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_ocaml_library(llvm_irreader
|
||||
OCAML llvm_irreader
|
||||
OCAMLDEP llvm
|
||||
C irreader_ocaml
|
||||
LLVM irreader)
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
5
bindings/ocaml/linker/CMakeLists.txt
Normal file
5
bindings/ocaml/linker/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_ocaml_library(llvm_linker
|
||||
OCAML llvm_linker
|
||||
OCAMLDEP llvm
|
||||
C linker_ocaml
|
||||
LLVM linker)
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
11
bindings/ocaml/llvm/CMakeLists.txt
Normal file
11
bindings/ocaml/llvm/CMakeLists.txt
Normal 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)
|
@ -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@"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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]. *)
|
||||
|
@ -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);
|
||||
|
||||
|
5
bindings/ocaml/target/CMakeLists.txt
Normal file
5
bindings/ocaml/target/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_ocaml_library(llvm_target
|
||||
OCAML llvm_target
|
||||
OCAMLDEP llvm
|
||||
C target_ocaml
|
||||
LLVM target)
|
@ -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 ->
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
5
bindings/ocaml/transforms/CMakeLists.txt
Normal file
5
bindings/ocaml/transforms/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_subdirectory(ipo)
|
||||
add_subdirectory(passmgr_builder)
|
||||
add_subdirectory(scalar_opts)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(vectorize)
|
@ -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 \
|
||||
|
5
bindings/ocaml/transforms/ipo/CMakeLists.txt
Normal file
5
bindings/ocaml/transforms/ipo/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_ocaml_library(llvm_ipo
|
||||
OCAML llvm_ipo
|
||||
OCAMLDEP llvm
|
||||
C ipo_ocaml
|
||||
LLVM ipo)
|
@ -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.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
5
bindings/ocaml/transforms/passmgr_builder/CMakeLists.txt
Normal file
5
bindings/ocaml/transforms/passmgr_builder/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_ocaml_library(llvm_passmgr_builder
|
||||
OCAML llvm_passmgr_builder
|
||||
OCAMLDEP llvm
|
||||
C passmgr_builder_ocaml
|
||||
LLVM ipo)
|
@ -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"
|
||||
|
@ -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) {
|
||||
|
@ -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"
|
@ -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"
|
5
bindings/ocaml/transforms/scalar_opts/CMakeLists.txt
Normal file
5
bindings/ocaml/transforms/scalar_opts/CMakeLists.txt
Normal 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
Loading…
Reference in New Issue
Block a user