Vendor import of llvm release_34 branch r197841 (effectively, 3.4 RC3):
https://llvm.org/svn/llvm-project/llvm/branches/release_34@197841
This commit is contained in:
parent
59d6cff90e
commit
f8af5cf600
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/llvm/dist/; revision=259698 svn path=/vendor/llvm/llvm-release_34-r197841/; revision=259700; tag=vendor/llvm/llvm-release_34-r197841
1
.clang-format
Normal file
1
.clang-format
Normal file
@ -0,0 +1 @@
|
||||
BasedOnStyle: LLVM
|
144
CMakeLists.txt
144
CMakeLists.txt
@ -11,9 +11,13 @@ set(CMAKE_MODULE_PATH
|
||||
)
|
||||
|
||||
set(LLVM_VERSION_MAJOR 3)
|
||||
set(LLVM_VERSION_MINOR 3)
|
||||
set(LLVM_VERSION_MINOR 4)
|
||||
|
||||
set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}svn")
|
||||
if (NOT PACKAGE_VERSION)
|
||||
set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}svn")
|
||||
endif()
|
||||
|
||||
option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF)
|
||||
|
||||
option(LLVM_USE_FOLDERS "Enable solution folders in Visual Studio. Disable for Express versions." ON)
|
||||
if ( LLVM_USE_FOLDERS )
|
||||
@ -33,6 +37,25 @@ set(PACKAGE_NAME LLVM)
|
||||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
set(PACKAGE_BUGREPORT "http://llvm.org/bugs/")
|
||||
|
||||
# Configure CPack.
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "LLVM")
|
||||
set(CPACK_PACKAGE_VENDOR "LLVM")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${LLVM_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${LLVM_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION ${PACKAGE_VERSION})
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.TXT")
|
||||
if(WIN32 AND NOT UNIX)
|
||||
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "LLVM")
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\cmake\\\\nsis_logo.bmp")
|
||||
set(CPACK_NSIS_MODIFY_PATH "ON")
|
||||
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON")
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
|
||||
"ExecWait '$INSTDIR/tools/msbuild/install.bat'")
|
||||
set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
|
||||
"ExecWait '$INSTDIR/tools/msbuild/uninstall.bat'")
|
||||
endif()
|
||||
include(CPack)
|
||||
|
||||
# Sanity check our source directory to make sure that we are not trying to
|
||||
# generate an in-tree build (unless on MSVC_IDE, where it is ok), and to make
|
||||
# sure that we don't have any stray generated files lying around in the tree
|
||||
@ -79,10 +102,10 @@ set(LLVM_ALL_TARGETS
|
||||
CppBackend
|
||||
Hexagon
|
||||
Mips
|
||||
MBlaze
|
||||
MSP430
|
||||
NVPTX
|
||||
PowerPC
|
||||
R600
|
||||
Sparc
|
||||
SystemZ
|
||||
X86
|
||||
@ -90,7 +113,7 @@ set(LLVM_ALL_TARGETS
|
||||
)
|
||||
|
||||
# List of targets with JIT support:
|
||||
set(LLVM_TARGETS_WITH_JIT X86 PowerPC ARM Mips SystemZ)
|
||||
set(LLVM_TARGETS_WITH_JIT X86 PowerPC AArch64 ARM Mips SystemZ)
|
||||
|
||||
set(LLVM_TARGETS_TO_BUILD "all"
|
||||
CACHE STRING "Semicolon-separated list of targets to build, or \"all\".")
|
||||
@ -116,6 +139,11 @@ if(LLVM_ENABLE_BACKTRACES)
|
||||
set(ENABLE_BACKTRACES 1)
|
||||
endif()
|
||||
|
||||
option(LLVM_ENABLE_CRASH_OVERRIDES "Enable crash overrides." ON)
|
||||
if(LLVM_ENABLE_CRASH_OVERRIDES)
|
||||
set(ENABLE_CRASH_OVERRIDES 1)
|
||||
endif()
|
||||
|
||||
option(LLVM_ENABLE_FFI "Use libffi to call external functions from the interpreter" OFF)
|
||||
set(FFI_LIBRARY_DIR "" CACHE PATH "Additional directory, where CMake should search for libffi.so")
|
||||
set(FFI_INCLUDE_DIR "" CACHE PATH "Additional directory, where CMake should search for ffi.h or ffi/ffi.h")
|
||||
@ -123,6 +151,8 @@ set(FFI_INCLUDE_DIR "" CACHE PATH "Additional directory, where CMake should sear
|
||||
set(LLVM_TARGET_ARCH "host"
|
||||
CACHE STRING "Set target to use for LLVM JIT or use \"host\" for automatic detection.")
|
||||
|
||||
option(LLVM_ENABLE_TERMINFO "Use terminfo database if available." ON)
|
||||
|
||||
option(LLVM_ENABLE_THREADS "Use threads if available." ON)
|
||||
|
||||
option(LLVM_ENABLE_ZLIB "Use zlib for compression/decompression if available." ON)
|
||||
@ -134,18 +164,7 @@ endif()
|
||||
set(LLVM_TARGETS_TO_BUILD
|
||||
${LLVM_TARGETS_TO_BUILD}
|
||||
${LLVM_EXPERIMENTAL_TARGETS_TO_BUILD})
|
||||
|
||||
set(LLVM_ENUM_TARGETS "")
|
||||
foreach(c ${LLVM_TARGETS_TO_BUILD})
|
||||
list(FIND LLVM_ALL_TARGETS ${c} idx)
|
||||
list(FIND LLVM_EXPERIMENTAL_TARGETS_TO_BUILD ${c} idy)
|
||||
if( idx LESS 0 AND idy LESS 0 )
|
||||
message(FATAL_ERROR "The target `${c}' does not exist.
|
||||
It should be one of\n${LLVM_ALL_TARGETS}")
|
||||
else()
|
||||
set(LLVM_ENUM_TARGETS "${LLVM_ENUM_TARGETS}LLVM_TARGET(${c})\n")
|
||||
endif()
|
||||
endforeach(c)
|
||||
list(REMOVE_DUPLICATES LLVM_TARGETS_TO_BUILD)
|
||||
|
||||
set(llvm_builded_incs_dir ${LLVM_BINARY_DIR}/include/llvm)
|
||||
|
||||
@ -163,7 +182,7 @@ endif()
|
||||
option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
|
||||
option(LLVM_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
|
||||
|
||||
if( uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE" )
|
||||
if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
|
||||
option(LLVM_ENABLE_ASSERTIONS "Enable assertions" OFF)
|
||||
else()
|
||||
option(LLVM_ENABLE_ASSERTIONS "Enable assertions" ON)
|
||||
@ -194,6 +213,9 @@ endif( LLVM_USE_OPROFILE )
|
||||
set(LLVM_USE_SANITIZER "" CACHE STRING
|
||||
"Define the sanitizer used to build binaries and tests.")
|
||||
|
||||
option(LLVM_USE_SPLIT_DWARF
|
||||
"Use -gsplit-dwarf when compiling llvm." OFF)
|
||||
|
||||
# Define an option controlling whether we should build for 32-bit on 64-bit
|
||||
# platforms, where supported.
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
|
||||
@ -215,18 +237,15 @@ if( WIN32 AND NOT CYGWIN )
|
||||
endif()
|
||||
|
||||
# Define options to control the inclusion and default build behavior for
|
||||
# components which may not strictly be necessary (tools, runtime, examples, and
|
||||
# tests).
|
||||
# components which may not strictly be necessary (tools, examples, and tests).
|
||||
#
|
||||
# This is primarily to support building smaller or faster project files.
|
||||
option(LLVM_INCLUDE_TOOLS "Generate build targets for the LLVM tools." ON)
|
||||
option(LLVM_BUILD_TOOLS
|
||||
"Build the LLVM tools. If OFF, just generate build targets." ON)
|
||||
|
||||
option(LLVM_INCLUDE_RUNTIME "Generate build targets for the LLVM runtimes" ON)
|
||||
option(LLVM_BUILD_RUNTIME
|
||||
"Build the LLVM runtime libraries. If OFF, just generate build targets." ON)
|
||||
|
||||
"Build the LLVM runtime libraries." ON)
|
||||
option(LLVM_BUILD_EXAMPLES
|
||||
"Build the LLVM example programs. If OFF, just generate build targets." OFF)
|
||||
option(LLVM_INCLUDE_EXAMPLES "Generate build targets for the LLVM examples" ON)
|
||||
@ -235,6 +254,10 @@ option(LLVM_BUILD_TESTS
|
||||
"Build LLVM unit tests. If OFF, just generate build targets." OFF)
|
||||
option(LLVM_INCLUDE_TESTS "Generate build targets for the LLVM unit tests." ON)
|
||||
|
||||
option (LLVM_BUILD_DOCS "Build the llvm documentation." OFF)
|
||||
option (LLVM_INCLUDE_DOCS "Generate build targets for llvm documentation." ON)
|
||||
option (LLVM_ENABLE_DOXYGEN "Use doxygen to generate llvm documentation." OFF)
|
||||
|
||||
# All options referred to from HandleLLVMOptions have to be specified
|
||||
# BEFORE this include, otherwise options will not be correctly set on
|
||||
# first cmake run
|
||||
@ -248,7 +271,8 @@ set(TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}")
|
||||
|
||||
include(HandleLLVMOptions)
|
||||
|
||||
# Verify that we can find a Python interpreter,
|
||||
# Verify that we can find a Python 2 interpreter. Python 3 is unsupported.
|
||||
set(Python_ADDITIONAL_VERSIONS 2.7 2.6 2.5)
|
||||
include(FindPythonInterp)
|
||||
if( NOT PYTHONINTERP_FOUND )
|
||||
message(FATAL_ERROR
|
||||
@ -293,7 +317,7 @@ execute_process(
|
||||
--enable-optional-components "${LLVMOPTIONALCOMPONENTS}"
|
||||
--write-library-table ${LLVMCONFIGLIBRARYDEPENDENCIESINC}
|
||||
--write-cmake-fragment ${LLVMBUILDCMAKEFRAG}
|
||||
ERROR_VARIABLE LLVMBUILDOUTPUT
|
||||
OUTPUT_VARIABLE LLVMBUILDOUTPUT
|
||||
ERROR_VARIABLE LLVMBUILDERRORS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_STRIP_TRAILING_WHITESPACE
|
||||
@ -319,11 +343,22 @@ include(${LLVMBUILDCMAKEFRAG})
|
||||
|
||||
# Configure all of the various header file fragments LLVM uses which depend on
|
||||
# configuration variables.
|
||||
set(LLVM_ENUM_TARGETS "")
|
||||
set(LLVM_ENUM_ASM_PRINTERS "")
|
||||
set(LLVM_ENUM_ASM_PARSERS "")
|
||||
set(LLVM_ENUM_DISASSEMBLERS "")
|
||||
foreach(t ${LLVM_TARGETS_TO_BUILD})
|
||||
set( td ${LLVM_MAIN_SRC_DIR}/lib/Target/${t} )
|
||||
|
||||
list(FIND LLVM_ALL_TARGETS ${t} idx)
|
||||
list(FIND LLVM_EXPERIMENTAL_TARGETS_TO_BUILD ${t} idy)
|
||||
if( idx LESS 0 AND idy LESS 0 )
|
||||
message(FATAL_ERROR "The target `${t}' does not exist.
|
||||
It should be one of\n${LLVM_ALL_TARGETS}")
|
||||
else()
|
||||
set(LLVM_ENUM_TARGETS "${LLVM_ENUM_TARGETS}LLVM_TARGET(${t})\n")
|
||||
endif()
|
||||
|
||||
file(GLOB asmp_file "${td}/*AsmPrinter.cpp")
|
||||
if( asmp_file )
|
||||
set(LLVM_ENUM_ASM_PRINTERS
|
||||
@ -424,10 +459,6 @@ if( LLVM_INCLUDE_TOOLS )
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
|
||||
if( LLVM_INCLUDE_RUNTIME )
|
||||
add_subdirectory(runtime)
|
||||
endif()
|
||||
|
||||
if( LLVM_INCLUDE_EXAMPLES )
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
@ -457,38 +488,36 @@ if( LLVM_INCLUDE_TESTS )
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LLVM_INCLUDE_DOCS)
|
||||
add_subdirectory(docs)
|
||||
endif()
|
||||
|
||||
add_subdirectory(cmake/modules)
|
||||
|
||||
install(DIRECTORY include/
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*.def"
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.td"
|
||||
PATTERN "*.inc"
|
||||
PATTERN "LICENSE.TXT"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
install(DIRECTORY include/
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*.def"
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.td"
|
||||
PATTERN "*.inc"
|
||||
PATTERN "LICENSE.TXT"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*.def"
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.gen"
|
||||
PATTERN "*.inc"
|
||||
# Exclude include/llvm/CMakeFiles/intrinsics_gen.dir, matched by "*.def"
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
# TODO: make and install documentation.
|
||||
|
||||
set(CPACK_PACKAGE_VENDOR "LLVM")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${LLVM_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${LLVM_VERSION_MINOR})
|
||||
add_version_info_from_vcs(CPACK_PACKAGE_VERSION_PATCH)
|
||||
include(CPack)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*.def"
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.gen"
|
||||
PATTERN "*.inc"
|
||||
# Exclude include/llvm/CMakeFiles/intrinsics_gen.dir, matched by "*.def"
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
endif()
|
||||
|
||||
# Workaround for MSVS10 to avoid the Dialog Hell
|
||||
# FIXME: This could be removed with future version of CMake.
|
||||
@ -498,3 +527,4 @@ if(MSVC_VERSION EQUAL 1600)
|
||||
file(APPEND "${LLVM_SLN_FILENAME}" "\n# This should be regenerated!\n")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -102,13 +102,17 @@ E: richard@xmos.com
|
||||
D: XCore Backend
|
||||
|
||||
N: Chad Rosier
|
||||
E: mcrosier@apple.com
|
||||
E: mcrosier@codeaurora.org
|
||||
D: Fast-Isel
|
||||
|
||||
N: Nadav Rotem
|
||||
E: nrotem@apple.com
|
||||
D: X86 Backend, Loop Vectorizer
|
||||
|
||||
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
|
||||
@ -117,6 +121,10 @@ N: Duncan Sands
|
||||
E: baldrick@free.fr
|
||||
D: DragonEgg
|
||||
|
||||
N: Kostya Serebryany
|
||||
E: kcc@google.com
|
||||
D: AddressSanitizer, ThreadSanitizer (LLVM parts)
|
||||
|
||||
N: Michael Spencer
|
||||
E: bigcheesegs@gmail.com
|
||||
D: Windows parts of Support, Object, ar, nm, objdump, ranlib, size
|
||||
@ -126,10 +134,18 @@ E: thomas.stellard@amd.com
|
||||
E: mesa-dev@lists.freedesktop.org
|
||||
D: R600 Backend
|
||||
|
||||
N: Evgeniy Stepanov
|
||||
E: eugenis@google.com
|
||||
D: MemorySanitizer (LLVM part)
|
||||
|
||||
N: Andrew Trick
|
||||
E: atrick@apple.com
|
||||
D: IndVar Simplify, Loop Strength Reduction, Instruction Scheduling
|
||||
|
||||
N: Bill Wendling
|
||||
E: wendling@apple.com
|
||||
E: isanbard@gmail.com
|
||||
D: libLTO, IR Linker
|
||||
|
||||
N: Peter Zotov
|
||||
E: whitequark@whitequark.org
|
||||
D: OCaml bindings
|
||||
|
18
CREDITS.TXT
18
CREDITS.TXT
@ -253,7 +253,8 @@ D: Release manager (1.7+)
|
||||
|
||||
N: Sylvestre Ledru
|
||||
E: sylvestre@debian.org
|
||||
W: http://sylvesre.ledru.info/
|
||||
W: http://sylvestre.ledru.info/
|
||||
W: http://llvm.org/apt/
|
||||
D: Debian and Ubuntu packaging
|
||||
D: Continous integration with jenkins
|
||||
|
||||
@ -300,6 +301,7 @@ D: Added STI Cell SPU backend.
|
||||
N: Kai Nacke
|
||||
E: kai@redstar.de
|
||||
D: Support for implicit TLS model used with MS VC runtime
|
||||
D: Dumping of Win64 EH structures
|
||||
|
||||
N: Takumi Nakamura
|
||||
E: geek4civic@gmail.com
|
||||
@ -364,7 +366,7 @@ I: arosenberg
|
||||
D: ARM calling conventions rewrite, hard float support
|
||||
|
||||
N: Chad Rosier
|
||||
E: mcrosier@apple.com
|
||||
E: mcrosier@codeaurora.org
|
||||
D: ARM fast-isel improvements
|
||||
D: Performance monitoring
|
||||
|
||||
@ -410,6 +412,11 @@ E: rspencer@reidspencer.com
|
||||
W: http://reidspencer.com/
|
||||
D: Lots of stuff, see: http://wiki.llvm.org/index.php/User:Reid
|
||||
|
||||
N: Alp Toker
|
||||
E: alp@nuanti.com
|
||||
W: http://atoker.com/
|
||||
D: C++ frontend next generation standards implementation
|
||||
|
||||
N: Craig Topper
|
||||
E: craig.topper@gmail.com
|
||||
D: X86 codegen and disassembler improvements. AVX2 support.
|
||||
@ -428,10 +435,11 @@ D: ARM backend improvements
|
||||
D: Thread Local Storage implementation
|
||||
|
||||
N: Bill Wendling
|
||||
E: wendling@apple.com
|
||||
D: Release manager
|
||||
I: wendling
|
||||
E: isanbard@gmail.com
|
||||
D: Release manager, IR Linker, LTO
|
||||
D: Bunches of stuff
|
||||
|
||||
N: Bob Wilson
|
||||
E: bob.wilson@acm.org
|
||||
D: Advanced SIMD (NEON) support in the ARM backend
|
||||
D: Advanced SIMD (NEON) support in the ARM backend.
|
||||
|
@ -68,3 +68,4 @@ Google Test llvm/utils/unittest/googletest
|
||||
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
|
||||
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
|
||||
ARM contributions llvm/lib/Target/ARM/LICENSE.TXT
|
||||
md5 contributions llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
|
||||
|
@ -16,7 +16,7 @@
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[common]
|
||||
subdirectories = bindings docs examples lib projects runtime tools utils
|
||||
subdirectories = bindings docs examples lib projects tools utils
|
||||
|
||||
[component_0]
|
||||
type = Group
|
||||
|
16
Makefile
16
Makefile
@ -15,7 +15,7 @@ LEVEL := .
|
||||
# 3. Build IR, which builds the Intrinsics.inc file used by libs.
|
||||
# 4. Build libs, which are needed by llvm-config.
|
||||
# 5. Build llvm-config, which determines inter-lib dependencies for tools.
|
||||
# 6. Build tools, runtime, docs.
|
||||
# 6. Build tools and docs.
|
||||
#
|
||||
# When cross-compiling, there are some things (tablegen) that need to
|
||||
# be build for the build system first.
|
||||
@ -31,7 +31,7 @@ ifeq ($(BUILD_DIRS_ONLY),1)
|
||||
OPTIONAL_DIRS := tools/clang/utils/TableGen
|
||||
else
|
||||
DIRS := lib/Support lib/TableGen utils lib/IR lib tools/llvm-shlib \
|
||||
tools/llvm-config tools runtime docs unittests
|
||||
tools/llvm-config tools docs unittests
|
||||
OPTIONAL_DIRS := projects bindings
|
||||
endif
|
||||
|
||||
@ -52,17 +52,17 @@ ifneq ($(ENABLE_DOCS),1)
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),libs-only)
|
||||
DIRS := $(filter-out tools runtime docs, $(DIRS))
|
||||
DIRS := $(filter-out tools docs, $(DIRS))
|
||||
OPTIONAL_DIRS :=
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),install-libs)
|
||||
DIRS := $(filter-out tools runtime docs, $(DIRS))
|
||||
DIRS := $(filter-out tools docs, $(DIRS))
|
||||
OPTIONAL_DIRS := $(filter bindings, $(OPTIONAL_DIRS))
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),tools-only)
|
||||
DIRS := $(filter-out runtime docs, $(DIRS))
|
||||
DIRS := $(filter-out docs, $(DIRS))
|
||||
OPTIONAL_DIRS :=
|
||||
endif
|
||||
|
||||
@ -72,7 +72,7 @@ ifeq ($(MAKECMDGOALS),install-clang)
|
||||
tools/clang/tools/c-index-test \
|
||||
tools/clang/include/clang-c \
|
||||
tools/clang/runtime tools/clang/docs \
|
||||
tools/lto runtime
|
||||
tools/lto
|
||||
OPTIONAL_DIRS :=
|
||||
NO_INSTALL = 1
|
||||
endif
|
||||
@ -84,7 +84,7 @@ ifeq ($(MAKECMDGOALS),clang-only)
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),unittests)
|
||||
DIRS := $(filter-out tools runtime docs, $(DIRS)) utils unittests
|
||||
DIRS := $(filter-out tools docs, $(DIRS)) utils unittests
|
||||
OPTIONAL_DIRS :=
|
||||
endif
|
||||
|
||||
@ -253,7 +253,7 @@ AWK = awk
|
||||
# a given path. svnup() requires one argument: the root to search from.
|
||||
define SUB_SVN_DIRS
|
||||
svnup() {
|
||||
dirs=`svn status --no-ignore $$1 | awk '/I|\? / {print $$2}' | LC_ALL=C xargs svn info 2>/dev/null | awk '/^Path:\ / {print $$2}'`;
|
||||
dirs=`svn status --no-ignore $$1 | awk '/^(I|\?) / {print $$2}' | LC_ALL=C xargs svn info 2>/dev/null | awk '/^Path:\ / {print $$2}'`;
|
||||
if [ "$$dirs" = "" ]; then
|
||||
return;
|
||||
fi;
|
||||
|
@ -235,6 +235,9 @@ ENABLE_LIBCPP = @ENABLE_LIBCPP@
|
||||
# When ENABLE_CXX11 is enabled, LLVM uses c++11 mode by default to build.
|
||||
ENABLE_CXX11 = @ENABLE_CXX11@
|
||||
|
||||
# When ENABLE_SPLIT_DWARF is enabled, LLVM uses -gfission to build in debug mode.
|
||||
ENABLE_SPLIT_DWARF = @ENABLE_SPLIT_DWARF@
|
||||
|
||||
# When ENABLE_CLANG_ARCMT is enabled, clang will have ARCMigrationTool.
|
||||
ENABLE_CLANG_ARCMT = @ENABLE_CLANG_ARCMT@
|
||||
|
||||
|
362
Makefile.rules
362
Makefile.rules
@ -42,7 +42,7 @@ VPATH=$(PROJ_SRC_DIR)
|
||||
# Reset the list of suffixes we know how to build.
|
||||
#--------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .cpp .cc .h .hpp .o .a .bc .td .ps .dot .ll .m .mm
|
||||
.SUFFIXES: .c .cpp .cc .h .hpp .o .a .td .ps .dot .m .mm
|
||||
.SUFFIXES: $(SHLIBEXT) $(SUFFIXES)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
@ -274,11 +274,9 @@ CPP.Defines :=
|
||||
ifeq ($(ENABLE_OPTIMIZED),1)
|
||||
BuildMode := Release
|
||||
# Don't use -fomit-frame-pointer on Darwin or FreeBSD.
|
||||
ifneq ($(HOST_OS),FreeBSD)
|
||||
ifneq ($(HOST_OS),Darwin)
|
||||
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin Darwin DragonFly FreeBSD GNU/kFreeBSD))
|
||||
OmitFramePointer := -fomit-frame-pointer
|
||||
endif
|
||||
endif
|
||||
|
||||
CXX.Flags += $(OPTIMIZE_OPTION) $(OmitFramePointer)
|
||||
C.Flags += $(OPTIMIZE_OPTION) $(OmitFramePointer)
|
||||
@ -287,7 +285,6 @@ ifeq ($(ENABLE_OPTIMIZED),1)
|
||||
BuildMode := $(BuildMode)+Debug
|
||||
CXX.Flags += -g
|
||||
C.Flags += -g
|
||||
LD.Flags += -g
|
||||
KEEP_SYMBOLS := 1
|
||||
endif
|
||||
else
|
||||
@ -295,13 +292,16 @@ else
|
||||
BuildMode := Unoptimized
|
||||
CXX.Flags +=
|
||||
C.Flags +=
|
||||
LD.Flags +=
|
||||
KEEP_SYMBOLS := 1
|
||||
else
|
||||
BuildMode := Debug
|
||||
ifeq ($(ENABLE_SPLIT_DWARF), 1)
|
||||
CXX.Flags += -gsplit-dwarf
|
||||
C.Flags += -gsplit-dwarf
|
||||
else
|
||||
CXX.Flags += -g
|
||||
C.Flags += -g
|
||||
LD.Flags += -g
|
||||
endif
|
||||
KEEP_SYMBOLS := 1
|
||||
endif
|
||||
endif
|
||||
@ -324,7 +324,7 @@ ifeq ($(ENABLE_PROFILING),1)
|
||||
BuildMode := $(BuildMode)+Profile
|
||||
CXX.Flags := $(filter-out -fomit-frame-pointer,$(CXX.Flags)) -pg -g
|
||||
C.Flags := $(filter-out -fomit-frame-pointer,$(C.Flags)) -pg -g
|
||||
LD.Flags := $(filter-out -fomit-frame-pointer,$(LD.Flags)) -pg -g
|
||||
LD.Flags := $(filter-out -fomit-frame-pointer,$(LD.Flags)) -pg
|
||||
KEEP_SYMBOLS := 1
|
||||
endif
|
||||
|
||||
@ -496,27 +496,6 @@ ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
endif
|
||||
endif
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# LLVM Capable Compiler
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
ifneq ($(findstring llvm-gcc,$(LLVMCC_OPTION)),)
|
||||
LLVMCC := $(LLVMGCC)
|
||||
LLVMCXX := $(LLVMGXX)
|
||||
else
|
||||
ifneq ($(findstring clang,$(LLVMCC_OPTION)),)
|
||||
ifneq ($(CLANGPATH),)
|
||||
LLVMCC := $(CLANGPATH)
|
||||
LLVMCXX := $(CLANGXXPATH)
|
||||
else
|
||||
ifeq ($(ENABLE_BUILT_CLANG),1)
|
||||
LLVMCC := $(LLVMToolDir)/clang
|
||||
LLVMCXX := $(LLVMToolDir)/clang++
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Full Paths To Compiled Tools and Utilities
|
||||
#--------------------------------------------------------------------
|
||||
@ -571,9 +550,9 @@ ifeq ($(HOST_OS),Darwin)
|
||||
DARWIN_VERSION := `sw_vers -productVersion`
|
||||
endif
|
||||
# Strip a number like 10.4.7 to 10.4
|
||||
DARWIN_VERSION := $(shell echo $(DARWIN_VERSION)| sed -E 's/(10.[0-9]).*/\1/')
|
||||
DARWIN_VERSION := $(shell echo $(DARWIN_VERSION)| sed -E 's/(10.[0-9]+).*/\1/')
|
||||
# Get "4" out of 10.4 for later pieces in the makefile.
|
||||
DARWIN_MAJVERS := $(shell echo $(DARWIN_VERSION)| sed -E 's/10.([0-9]).*/\1/')
|
||||
DARWIN_MAJVERS := $(shell echo $(DARWIN_VERSION)| sed -E 's/10.([0-9]+).*/\1/')
|
||||
|
||||
LoadableModuleOptions := -Wl,-flat_namespace -Wl,-undefined,suppress
|
||||
SharedLinkOptions := -dynamiclib
|
||||
@ -629,32 +608,24 @@ ifndef KEEP_SYMBOLS
|
||||
Install.StripFlag += -s
|
||||
endif
|
||||
|
||||
ifdef TOOL_NO_EXPORTS
|
||||
DynamicFlags :=
|
||||
else
|
||||
DynamicFlag := $(RDYNAMIC)
|
||||
endif
|
||||
|
||||
# Adjust linker flags for building an executable
|
||||
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
ifndef TOOL_NO_EXPORTS
|
||||
LD.Flags += $(RDYNAMIC)
|
||||
endif
|
||||
ifneq ($(HOST_OS), Darwin)
|
||||
ifdef TOOLNAME
|
||||
LD.Flags += $(RPATH) -Wl,'$$ORIGIN/../lib'
|
||||
ifdef EXAMPLE_TOOL
|
||||
LD.Flags += $(RPATH) -Wl,$(ExmplDir) $(DynamicFlag)
|
||||
else
|
||||
LD.Flags += $(RPATH) -Wl,$(ToolDir) $(DynamicFlag)
|
||||
endif
|
||||
else
|
||||
ifneq ($(DARWIN_MAJVERS),4)
|
||||
LD.Flags += $(RPATH) -Wl,@executable_path/../lib
|
||||
endif
|
||||
ifeq ($(RC_XBS),YES)
|
||||
TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/llvm-lto.XXXXXX)
|
||||
LD.Flags += -Wl,-object_path_lto -Wl,$(TempFile)
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifneq ($(DARWIN_MAJVERS),4)
|
||||
LD.Flags += $(RPATH) -Wl,@executable_path/../lib
|
||||
endif
|
||||
ifeq ($(RC_XBS),YES)
|
||||
TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/llvm-lto.XXXXXX)
|
||||
LD.Flags += -Wl,-object_path_lto -Wl,$(TempFile)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@ -696,9 +667,9 @@ ifdef UNIVERSAL
|
||||
UNIVERSAL_ARCH := i386 ppc
|
||||
endif
|
||||
UNIVERSAL_ARCH_OPTIONS := $(UNIVERSAL_ARCH:%=-arch %)
|
||||
CompileCommonOpts += $(UNIVERSAL_ARCH_OPTIONS)
|
||||
TargetCommonOpts += $(UNIVERSAL_ARCH_OPTIONS)
|
||||
ifdef UNIVERSAL_SDK_PATH
|
||||
CompileCommonOpts += -isysroot $(UNIVERSAL_SDK_PATH)
|
||||
TargetCommonOpts += -isysroot $(UNIVERSAL_SDK_PATH)
|
||||
endif
|
||||
|
||||
# Building universal cannot compute dependencies automatically.
|
||||
@ -760,17 +731,12 @@ Preprocess.CXX= $(Compile.Wrapper) \
|
||||
$(CXX) $(CPP.Flags) $(TargetCommonOpts) $(CPPFLAGS) \
|
||||
$(CompileCommonOpts) $(CXX.Flags) -E
|
||||
Link = $(Compile.Wrapper) \
|
||||
$(CXX) $(CPP.Flags) $(CXX.Flags) $(CXXFLAGS) $(LD.Flags) \
|
||||
$(LDFLAGS) $(TargetCommonOpts) $(CompileCommonOpts) $(Strip)
|
||||
$(CXX) $(CXXFLAGS) $(LD.Flags) $(LDFLAGS) \
|
||||
$(TargetCommonOpts) $(Strip)
|
||||
|
||||
BCCompile.C = $(LLVMCC) $(CPP.Flags) $(C.Flags) $(CFLAGS) $(CPPFLAGS) \
|
||||
$(TargetCommonOpts) $(CompileCommonOpts)
|
||||
Preprocess.C = $(CC) $(CPP.Flags) $(C.Flags) $(CPPFLAGS) \
|
||||
$(TargetCommonOpts) $(CompileCommonOpts) -E
|
||||
|
||||
BCCompile.CXX = $(LLVMCXX) $(CPP.Flags) $(CXX.Flags) $(CXXFLAGS) $(CPPFLAGS) \
|
||||
$(TargetCommonOpts) $(CompileCommonOpts)
|
||||
|
||||
ProgInstall = $(INSTALL) $(Install.StripFlag) -m 0755
|
||||
ScriptInstall = $(INSTALL) -m 0755
|
||||
DataInstall = $(INSTALL) -m 0644
|
||||
@ -785,7 +751,6 @@ TableGen.Flags= -I $(call SYSPATH, $(PROJ_SRC_DIR)) \
|
||||
LLVMTableGen = $(LLVM_TBLGEN) $(TableGen.Flags)
|
||||
|
||||
Archive = $(AR) $(AR.Flags)
|
||||
LArchive = $(LLVMToolDir)/llvm-ar rcsf
|
||||
ifdef RANLIB
|
||||
Ranlib = $(RANLIB)
|
||||
else
|
||||
@ -811,9 +776,10 @@ Sources += $(filter %.cpp %.c %.cc,$(BUILT_SOURCES))
|
||||
endif
|
||||
|
||||
BaseNameSources := $(sort $(basename $(Sources)))
|
||||
SourceDirs := $(sort $(dir $(Sources)))
|
||||
|
||||
ObjectsO := $(BaseNameSources:%=$(ObjDir)/%.o)
|
||||
ObjectsBC := $(BaseNameSources:%=$(ObjDir)/%.bc)
|
||||
ObjectDirs := $(SourceDirs:%=$(ObjDir)/%)
|
||||
|
||||
#----------------------------------------------------------
|
||||
# For Mingw MSYS bash and Python/w32:
|
||||
@ -850,9 +816,18 @@ $(DESTDIR)$(PROJ_bindir) $(DESTDIR)$(PROJ_libdir) $(DESTDIR)$(PROJ_includedir) $
|
||||
$(Verb) $(MKDIR) $* > /dev/null
|
||||
$(Verb) $(DOTDIR_TIMESTAMP_COMMAND) > $@
|
||||
|
||||
.PRECIOUS: $(ObjDir)/.dir $(LibDir)/.dir $(ToolDir)/.dir $(ExmplDir)/.dir
|
||||
.PRECIOUS: $(LibDir)/.dir $(ToolDir)/.dir $(ExmplDir)/.dir
|
||||
.PRECIOUS: $(LLVMLibDir)/.dir $(LLVMToolDir)/.dir $(LLVMExmplDir)/.dir
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Collect the object directories (as there may be more
|
||||
# than one if the source code is spread across
|
||||
# subdirectories).
|
||||
#---------------------------------------------------------
|
||||
|
||||
OBJECT_DIRS := $(ObjDir)/.dir $(ObjectDirs:%=%/.dir)
|
||||
.PRECIOUS: $(OBJECT_DIRS)
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Handle the DIRS options for sequential construction
|
||||
#---------------------------------------------------------
|
||||
@ -1141,67 +1116,6 @@ endif
|
||||
# Library Build Rules: Four ways to build a library
|
||||
###############################################################################
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Bytecode Module Targets:
|
||||
# If the user set MODULE_NAME then they want to build a
|
||||
# bytecode module from the sources. We compile all the
|
||||
# sources and link it together into a single bytecode
|
||||
# module.
|
||||
#---------------------------------------------------------
|
||||
|
||||
ifdef MODULE_NAME
|
||||
ifeq ($(strip $(LLVMCC)),)
|
||||
$(warning Modules require LLVM capable compiler but none is available ****)
|
||||
else
|
||||
|
||||
Module := $(LibDir)/$(MODULE_NAME).bc
|
||||
LinkModule := $(LLVMLINK)
|
||||
|
||||
|
||||
ifdef EXPORTED_SYMBOL_FILE
|
||||
LinkModule += -internalize-public-api-file=$(EXPORTED_SYMBOL_FILE)
|
||||
endif
|
||||
|
||||
$(Module): $(BUILT_SOURCES) $(ObjectsBC) $(LibDir)/.dir $(LLVMLINK)
|
||||
$(Echo) Building $(BuildMode) Bytecode Module $(notdir $@)
|
||||
$(Verb) $(LinkModule) -o $@ $(ObjectsBC)
|
||||
|
||||
all-local:: $(Module)
|
||||
|
||||
clean-local::
|
||||
ifneq ($(strip $(Module)),)
|
||||
-$(Verb) $(RM) -f $(Module)
|
||||
endif
|
||||
|
||||
ifdef BYTECODE_DESTINATION
|
||||
ModuleDestDir := $(BYTECODE_DESTINATION)
|
||||
else
|
||||
ModuleDestDir := $(DESTDIR)$(PROJ_libdir)
|
||||
endif
|
||||
|
||||
ifdef NO_INSTALL
|
||||
install-local::
|
||||
$(Echo) Install circumvented with NO_INSTALL
|
||||
uninstall-local::
|
||||
$(Echo) Uninstall circumvented with NO_INSTALL
|
||||
else
|
||||
DestModule := $(ModuleDestDir)/$(MODULE_NAME).bc
|
||||
|
||||
install-module:: $(DestModule)
|
||||
install-local:: $(DestModule)
|
||||
|
||||
$(DestModule): $(ModuleDestDir) $(Module)
|
||||
$(Echo) Installing $(BuildMode) Bytecode Module $(DestModule)
|
||||
$(Verb) $(DataInstall) $(Module) $(DestModule)
|
||||
|
||||
uninstall-local::
|
||||
$(Echo) Uninstalling $(BuildMode) Bytecode Module $(DestModule)
|
||||
-$(Verb) $(RM) -f $(DestModule)
|
||||
endif
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
# if we're building a library ...
|
||||
ifdef LIBRARYNAME
|
||||
|
||||
@ -1217,7 +1131,6 @@ endif
|
||||
LibName.A := $(LibDir)/$(BaseLibName.A)
|
||||
LibName.SO := $(SharedLibDir)/$(BaseLibName.SO)
|
||||
LibName.O := $(LibDir)/$(LIBRARYNAME).o
|
||||
LibName.BCA:= $(LibDir)/lib$(LIBRARYNAME).bca
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Shared Library Targets:
|
||||
@ -1279,73 +1192,7 @@ $(DestSharedLib): $(LibName.SO) $(DestSharedLibDir)
|
||||
|
||||
uninstall-local::
|
||||
$(Echo) Uninstalling $(BuildMode) Shared Library $(DestSharedLib)
|
||||
-$(Verb) $(RM) -f $(DestSharedLibDir)/$(SharedPrefix)$(LIBRARYNAME).*
|
||||
endif
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Bytecode Library Targets:
|
||||
# If the user asked for a bytecode library to be built
|
||||
# with the BYTECODE_LIBRARY variable, then we provide
|
||||
# targets for building them.
|
||||
#---------------------------------------------------------
|
||||
ifdef BYTECODE_LIBRARY
|
||||
ifeq ($(strip $(LLVMCC)),)
|
||||
$(warning Bytecode libraries require LLVM capable compiler but none is available ****)
|
||||
else
|
||||
|
||||
all-local:: $(LibName.BCA)
|
||||
|
||||
ifdef EXPORTED_SYMBOL_FILE
|
||||
BCLinkLib = $(LLVMLINK) -internalize-public-api-file=$(EXPORTED_SYMBOL_FILE)
|
||||
|
||||
$(LibName.BCA): $(ObjectsBC) $(LibDir)/.dir $(LLVMLINK) \
|
||||
$(LLVMToolDir)/llvm-ar
|
||||
$(Echo) Building $(BuildMode) Bytecode Archive $(notdir $@) \
|
||||
"(internalize)"
|
||||
$(Verb) $(BCLinkLib) -o $(ObjDir)/$(LIBRARYNAME).internalize $(ObjectsBC)
|
||||
$(Verb) $(RM) -f $@
|
||||
$(Verb) $(LArchive) $@ $(ObjDir)/$(LIBRARYNAME).internalize.bc
|
||||
else
|
||||
$(LibName.BCA): $(ObjectsBC) $(LibDir)/.dir \
|
||||
$(LLVMToolDir)/llvm-ar
|
||||
$(Echo) Building $(BuildMode) Bytecode Archive $(notdir $@)
|
||||
$(Verb) $(RM) -f $@
|
||||
$(Verb) $(LArchive) $@ $(ObjectsBC)
|
||||
|
||||
endif
|
||||
|
||||
clean-local::
|
||||
ifneq ($(strip $(LibName.BCA)),)
|
||||
-$(Verb) $(RM) -f $(LibName.BCA)
|
||||
endif
|
||||
|
||||
ifdef BYTECODE_DESTINATION
|
||||
BytecodeDestDir := $(BYTECODE_DESTINATION)
|
||||
else
|
||||
BytecodeDestDir := $(DESTDIR)$(PROJ_libdir)
|
||||
endif
|
||||
|
||||
DestBytecodeLib = $(BytecodeDestDir)/lib$(LIBRARYNAME).bca
|
||||
|
||||
install-bytecode-local:: $(DestBytecodeLib)
|
||||
|
||||
ifdef NO_INSTALL
|
||||
install-local::
|
||||
$(Echo) Install circumvented with NO_INSTALL
|
||||
uninstall-local::
|
||||
$(Echo) Uninstall circumvented with NO_INSTALL
|
||||
else
|
||||
install-local:: $(DestBytecodeLib)
|
||||
|
||||
$(DestBytecodeLib): $(LibName.BCA) $(BytecodeDestDir)
|
||||
$(Echo) Installing $(BuildMode) Bytecode Archive $(DestBytecodeLib)
|
||||
$(Verb) $(DataInstall) $(LibName.BCA) $(DestBytecodeLib)
|
||||
|
||||
uninstall-local::
|
||||
$(Echo) Uninstalling $(BuildMode) Bytecode Archive $(DestBytecodeLib)
|
||||
-$(Verb) $(RM) -f $(DestBytecodeLib)
|
||||
endif
|
||||
-$(Verb) $(RM) -f $(DestSharedLib)
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1454,7 +1301,7 @@ LD.Flags += -Wl,-exported_symbol,_main
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux NetBSD FreeBSD GNU))
|
||||
ifeq ($(HOST_OS), $(filter $(HOST_OS), DragonFly Linux NetBSD FreeBSD GNU/kFreeBSD GNU))
|
||||
ifneq ($(ARCH), Mips)
|
||||
LD.Flags += -Wl,--version-script=$(LLVM_SRC_ROOT)/autoconf/ExportMap.map
|
||||
endif
|
||||
@ -1596,6 +1443,8 @@ ifeq ($(HOST_OS),HP-UX)
|
||||
DISABLE_AUTO_DEPENDENCIES=1
|
||||
endif
|
||||
|
||||
COMPILE_DEPS = $(OBJECT_DIRS) $(BUILT_SOURCES) $(PROJ_MAKEFILE)
|
||||
|
||||
# Provide rule sets for when dependency generation is enabled
|
||||
ifndef DISABLE_AUTO_DEPENDENCIES
|
||||
|
||||
@ -1611,182 +1460,98 @@ DEPEND_OPTIONS = -MMD -MP -MF "$(ObjDir)/$*.d.tmp" \
|
||||
DEPEND_MOVEFILE = then $(MV) -f "$(ObjDir)/$*.d.tmp" "$(ObjDir)/$*.d"; \
|
||||
else $(RM) "$(ObjDir)/$*.d.tmp"; exit 1; fi
|
||||
|
||||
$(ObjDir)/%.o: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(PROJ_MAKEFILE)
|
||||
$(ObjDir)/%.o: %.cpp $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.cpp for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Verb) if $(Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \
|
||||
$(DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.o: %.mm $(ObjDir)/.dir $(BUILT_SOURCES) $(PROJ_MAKEFILE)
|
||||
$(ObjDir)/%.o: %.mm $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.mm for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Verb) if $(Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \
|
||||
$(DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.o: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(PROJ_MAKEFILE)
|
||||
$(ObjDir)/%.o: %.cc $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.cc for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Verb) if $(Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \
|
||||
$(DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.o: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(PROJ_MAKEFILE)
|
||||
$(ObjDir)/%.o: %.c $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Verb) if $(Compile.C) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \
|
||||
$(DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.o: %.m $(ObjDir)/.dir $(BUILT_SOURCES) $(PROJ_MAKEFILE)
|
||||
$(ObjDir)/%.o: %.m $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.m for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Verb) if $(Compile.C) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \
|
||||
$(DEPEND_MOVEFILE)
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Create .bc files in the ObjDir directory from .cpp .cc and .c files...
|
||||
#---------------------------------------------------------
|
||||
|
||||
BC_DEPEND_OPTIONS = -MMD -MP -MF "$(ObjDir)/$*.bc.d.tmp" \
|
||||
-MT "$(ObjDir)/$*.ll" -MT "$(ObjDir)/$*.bc.d"
|
||||
|
||||
# If the build succeeded, move the dependency file over, otherwise
|
||||
# remove it.
|
||||
BC_DEPEND_MOVEFILE = then $(MV) -f "$(ObjDir)/$*.bc.d.tmp" "$(ObjDir)/$*.bc.d"; \
|
||||
else $(RM) "$(ObjDir)/$*.bc.d.tmp"; exit 1; fi
|
||||
|
||||
$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.cpp for $(BuildMode) build (bytecode)"
|
||||
$(Verb) if $(BCCompile.CXX) $(BC_DEPEND_OPTIONS) \
|
||||
$< -o $(ObjDir)/$*.ll -S $(LLVMCC_EMITIR_FLAG) ; \
|
||||
$(BC_DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.ll: %.mm $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.mm for $(BuildMode) build (bytecode)"
|
||||
$(Verb) if $(BCCompile.CXX) $(BC_DEPEND_OPTIONS) \
|
||||
$< -o $(ObjDir)/$*.ll -S $(LLVMCC_EMITIR_FLAG) ; \
|
||||
$(BC_DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.cc for $(BuildMode) build (bytecode)"
|
||||
$(Verb) if $(BCCompile.CXX) $(BC_DEPEND_OPTIONS) \
|
||||
$< -o $(ObjDir)/$*.ll -S $(LLVMCC_EMITIR_FLAG) ; \
|
||||
$(BC_DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCC)
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build (bytecode)"
|
||||
$(Verb) if $(BCCompile.C) $(BC_DEPEND_OPTIONS) \
|
||||
$< -o $(ObjDir)/$*.ll -S $(LLVMCC_EMITIR_FLAG) ; \
|
||||
$(BC_DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.ll: %.m $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCC)
|
||||
$(Echo) "Compiling $*.m for $(BuildMode) build (bytecode)"
|
||||
$(Verb) if $(BCCompile.C) $(BC_DEPEND_OPTIONS) \
|
||||
$< -o $(ObjDir)/$*.ll -S $(LLVMCC_EMITIR_FLAG) ; \
|
||||
$(BC_DEPEND_MOVEFILE)
|
||||
|
||||
# Provide alternate rule sets if dependencies are disabled
|
||||
else
|
||||
|
||||
$(ObjDir)/%.o: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.o: %.cpp $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.cpp for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.CXX) $< -o $@
|
||||
|
||||
$(ObjDir)/%.o: %.mm $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.o: %.mm $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.mm for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.CXX) $< -o $@
|
||||
|
||||
$(ObjDir)/%.o: %.cc $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.o: %.cc $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.cc for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.CXX) $< -o $@
|
||||
|
||||
$(ObjDir)/%.o: %.c $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.o: %.c $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.C) $< -o $@
|
||||
|
||||
$(ObjDir)/%.o: %.m $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.o: %.m $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.m for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.C) $< -o $@
|
||||
|
||||
$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.cpp for $(BuildMode) build (bytecode)"
|
||||
$(BCCompile.CXX) $< -o $@ -S $(LLVMCC_EMITIR_FLAG)
|
||||
|
||||
$(ObjDir)/%.ll: %.mm $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.mm for $(BuildMode) build (bytecode)"
|
||||
$(BCCompile.CXX) $< -o $@ -S $(LLVMCC_EMITIR_FLAG)
|
||||
|
||||
$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.cc for $(BuildMode) build (bytecode)"
|
||||
$(BCCompile.CXX) $< -o $@ -S $(LLVMCC_EMITIR_FLAG)
|
||||
|
||||
$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCC)
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build (bytecode)"
|
||||
$(BCCompile.C) $< -o $@ -S $(LLVMCC_EMITIR_FLAG)
|
||||
|
||||
$(ObjDir)/%.ll: %.m $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCC)
|
||||
$(Echo) "Compiling $*.m for $(BuildMode) build (bytecode)"
|
||||
$(BCCompile.C) $< -o $@ -S $(LLVMCC_EMITIR_FLAG)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
## Rules for building preprocessed (.i/.ii) outputs.
|
||||
$(BuildMode)/%.ii: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(BuildMode)/%.ii: %.cpp $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.cpp for $(BuildMode) build to .ii file"
|
||||
$(Verb) $(Preprocess.CXX) $< -o $@
|
||||
|
||||
$(BuildMode)/%.ii: %.mm $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(BuildMode)/%.ii: %.mm $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.mm for $(BuildMode) build to .ii file"
|
||||
$(Verb) $(Preprocess.CXX) $< -o $@
|
||||
|
||||
$(BuildMode)/%.ii: %.cc $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(BuildMode)/%.ii: %.cc $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.cc for $(BuildMode) build to .ii file"
|
||||
$(Verb) $(Preprocess.CXX) $< -o $@
|
||||
|
||||
$(BuildMode)/%.i: %.c $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(BuildMode)/%.i: %.c $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build to .i file"
|
||||
$(Verb) $(Preprocess.C) $< -o $@
|
||||
|
||||
$(BuildMode)/%.i: %.m $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(BuildMode)/%.i: %.m $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.m for $(BuildMode) build to .i file"
|
||||
$(Verb) $(Preprocess.C) $< -o $@
|
||||
|
||||
|
||||
$(ObjDir)/%.s: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.s: %.cpp $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.cpp to asm for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.CXX) $< -o $@ -S
|
||||
|
||||
$(ObjDir)/%.s: %.mm $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.s: %.mm $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.mm to asm for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.CXX) $< -o $@ -S
|
||||
|
||||
$(ObjDir)/%.s: %.cc $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.s: %.cc $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.cc to asm for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.CXX) $< -o $@ -S
|
||||
|
||||
$(ObjDir)/%.s: %.c $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.s: %.c $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.c to asm for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.C) $< -o $@ -S
|
||||
|
||||
$(ObjDir)/%.s: %.m $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(ObjDir)/%.s: %.m $(COMPILE_DEPS)
|
||||
$(Echo) "Compiling $*.m to asm for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.C) $< -o $@ -S
|
||||
|
||||
|
||||
# make the C and C++ compilers strip debug info out of bytecode libraries.
|
||||
ifdef DEBUG_RUNTIME
|
||||
$(ObjectsBC): $(ObjDir)/%.bc: $(ObjDir)/%.ll $(LOPT)
|
||||
$(Echo) "Compiling $*.ll to $*.bc for $(BuildMode) build (bytecode)"
|
||||
$(Verb) $(LOPT) $< -std-compile-opts -o $@
|
||||
else
|
||||
$(ObjectsBC): $(ObjDir)/%.bc: $(ObjDir)/%.ll $(LOPT)
|
||||
$(Echo) "Compiling $*.ll to $*.bc for $(BuildMode) build (bytecode)"
|
||||
$(Verb) $(LOPT) $< -std-compile-opts -strip-debug -o $@
|
||||
endif
|
||||
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Provide rule to build .bc files from .ll sources,
|
||||
# regardless of dependencies
|
||||
#---------------------------------------------------------
|
||||
$(ObjDir)/%.bc: %.ll $(ObjDir)/.dir $(LLVMAS)
|
||||
$(Echo) "Compiling $*.ll for $(BuildMode) build"
|
||||
$(Verb) $(LLVMAS) $< -f -o $@
|
||||
|
||||
###############################################################################
|
||||
# TABLEGEN: Provide rules for running tblgen to produce *.inc files
|
||||
###############################################################################
|
||||
@ -1954,11 +1719,6 @@ ifndef IS_CLEANING_TARGET
|
||||
DependSourceFiles := $(basename $(filter %.cpp %.c %.cc %.m %.mm, $(Sources)))
|
||||
DependFiles := $(DependSourceFiles:%=$(PROJ_OBJ_DIR)/$(BuildMode)/%.d)
|
||||
|
||||
# Include bitcode dependency files if using bitcode libraries
|
||||
ifdef BYTECODE_LIBRARY
|
||||
DependFiles += $(DependSourceFiles:%=$(PROJ_OBJ_DIR)/$(BuildMode)/%.bc.d)
|
||||
endif
|
||||
|
||||
-include $(DependFiles) ""
|
||||
|
||||
endif
|
||||
|
3
autoconf/config.guess
vendored
3
autoconf/config.guess
vendored
@ -965,6 +965,9 @@ EOF
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc64le:Linux:*:*)
|
||||
echo powerpc64le-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
|
@ -31,9 +31,9 @@ dnl===
|
||||
dnl===-----------------------------------------------------------------------===
|
||||
dnl Initialize autoconf and define the package name, version number and
|
||||
dnl address for reporting bugs.
|
||||
AC_INIT([LLVM],[3.3],[http://llvm.org/bugs/])
|
||||
AC_INIT([LLVM],[3.4],[http://llvm.org/bugs/])
|
||||
AC_DEFINE([LLVM_VERSION_MAJOR], [3], [Major version of the LLVM API])
|
||||
AC_DEFINE([LLVM_VERSION_MINOR], [3], [Minor version of the LLVM API])
|
||||
AC_DEFINE([LLVM_VERSION_MINOR], [4], [Minor version of the LLVM API])
|
||||
|
||||
dnl Provide a copyright substitution and ensure the copyright notice is included
|
||||
dnl in the output of --version option of the generated configure script.
|
||||
@ -61,8 +61,8 @@ fi
|
||||
|
||||
dnl Default to empty (i.e. assigning the null string to) CFLAGS and CXXFLAGS,
|
||||
dnl instead of the autoconf default (for example, '-g -O2' for CC=gcc).
|
||||
${CFLAGS=}
|
||||
${CXXFLAGS=}
|
||||
: ${CFLAGS=}
|
||||
: ${CXXFLAGS=}
|
||||
|
||||
dnl We need to check for the compiler up here to avoid anything else
|
||||
dnl starting with a different one.
|
||||
@ -222,11 +222,16 @@ AC_CACHE_CHECK([type of operating system we're going to host on],
|
||||
llvm_cv_no_link_all_option="-Wl,-noall_load"
|
||||
llvm_cv_os_type="Minix"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-freebsd* | *-*-kfreebsd-gnu)
|
||||
*-*-freebsd*)
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
llvm_cv_os_type="FreeBSD"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-kfreebsd-gnu)
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
llvm_cv_os_type="GNU/kFreeBSD"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-openbsd*)
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
@ -317,8 +322,10 @@ AC_CACHE_CHECK([type of operating system we're going to target],
|
||||
llvm_cv_target_os_type="Darwin" ;;
|
||||
*-*-minix*)
|
||||
llvm_cv_target_os_type="Minix" ;;
|
||||
*-*-freebsd* | *-*-kfreebsd-gnu)
|
||||
*-*-freebsd*)
|
||||
llvm_cv_target_os_type="FreeBSD" ;;
|
||||
*-*-kfreebsd-gnu)
|
||||
llvm_cv_target_os_type="GNU/kFreeBSD" ;;
|
||||
*-*-openbsd*)
|
||||
llvm_cv_target_os_type="OpenBSD" ;;
|
||||
*-*-netbsd*)
|
||||
@ -400,7 +407,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
hexagon-*) llvm_cv_target_arch="Hexagon" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
nvptx-*) llvm_cv_target_arch="NVPTX" ;;
|
||||
s390x-*) llvm_cv_target_arch="SystemZ" ;;
|
||||
*) llvm_cv_target_arch="Unknown" ;;
|
||||
@ -435,7 +441,6 @@ case $host in
|
||||
xcore-*) host_arch="XCore" ;;
|
||||
msp430-*) host_arch="MSP430" ;;
|
||||
hexagon-*) host_arch="Hexagon" ;;
|
||||
mblaze-*) host_arch="MBlaze" ;;
|
||||
s390x-*) host_arch="SystemZ" ;;
|
||||
*) host_arch="Unknown" ;;
|
||||
esac
|
||||
@ -510,6 +515,19 @@ case "$enableval" in
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-cxx11. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
|
||||
dnl --enable-fission : check whether or not to use -gsplit-dwarf on the command
|
||||
dnl line
|
||||
AC_ARG_ENABLE(split-dwarf,
|
||||
AS_HELP_STRING([--enable-split-dwarf],
|
||||
[Use split-dwarf if available (default is NO)]),,
|
||||
enableval=default)
|
||||
case "$enableval" in
|
||||
yes) AC_SUBST(ENABLE_SPLIT_DWARF,[1]) ;;
|
||||
no) AC_SUBST(ENABLE_SPLIT_DWARF,[0]) ;;
|
||||
default) AC_SUBST(ENABLE_SPLIT_DWARF,[0]);;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-split-dwarf. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
|
||||
dnl --enable-clang-arcmt: check whether to enable clang arcmt
|
||||
clang_arcmt="yes"
|
||||
AC_ARG_ENABLE(clang-arcmt,
|
||||
@ -533,7 +551,12 @@ AC_ARG_ENABLE(clang-static-analyzer,
|
||||
enableval="yes")
|
||||
case "$enableval" in
|
||||
yes) AC_SUBST(ENABLE_CLANG_STATIC_ANALYZER,[1]) ;;
|
||||
no) AC_SUBST(ENABLE_CLANG_STATIC_ANALYZER,[0]) ;;
|
||||
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])
|
||||
;;
|
||||
default) AC_SUBST(ENABLE_CLANG_STATIC_ANALYZER,[1]);;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-clang-static-analyzer. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
@ -654,7 +677,6 @@ else
|
||||
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
Hexagon) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
NVPTX) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
SystemZ) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
*) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
@ -778,33 +800,50 @@ esac
|
||||
AC_DEFINE_UNQUOTED([ENABLE_TIMESTAMPS],$ENABLE_TIMESTAMPS,
|
||||
[Define if timestamp information (e.g., __DATE__) is allowed])
|
||||
|
||||
dnl Enable embedding timestamp information into build.
|
||||
dnl Enable support for showing backtraces.
|
||||
AC_ARG_ENABLE(backtraces, AS_HELP_STRING(
|
||||
[--enable-backtraces],
|
||||
[Enable embedding backtraces on crash (default is YES)]),
|
||||
[case "$enableval" in
|
||||
yes) llvm_cv_enable_backtraces="yes" ;;
|
||||
no) llvm_cv_enable_backtraces="no" ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-backtraces. Use "yes" or "no"]) ;;
|
||||
esac],
|
||||
llvm_cv_enable_backtraces="yes")
|
||||
if test "$llvm_cv_enable_backtraces" = "yes" ; then
|
||||
AC_DEFINE([ENABLE_BACKTRACES],[1],
|
||||
[Define if you want backtraces on crash])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(backtraces,
|
||||
AS_HELP_STRING([--enable-backtraces],
|
||||
[Enable embedding backtraces on crash (default is YES)]),,
|
||||
enableval=default)
|
||||
case "$enableval" in
|
||||
yes) AC_SUBST(ENABLE_BACKTRACES,[1]) ;;
|
||||
no) AC_SUBST(ENABLE_BACKTRACES,[0]) ;;
|
||||
default) AC_SUBST(ENABLE_BACKTRACES,[1]) ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-backtraces. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
AC_DEFINE_UNQUOTED([ENABLE_BACKTRACES],$ENABLE_BACKTRACES,
|
||||
[Define if you want backtraces on crash])
|
||||
dnl Enable installing platform specific signal handling overrides, for improved
|
||||
dnl CrashRecovery support or interaction with crash reporting software. This
|
||||
dnl support may be inappropriate for some clients embedding LLVM as a library.
|
||||
AC_ARG_ENABLE(crash-overrides, AS_HELP_STRING(
|
||||
[--enable-crash-overrides],
|
||||
[Enable crash handling overrides (default is YES)]),
|
||||
[case "$enableval" in
|
||||
yes) llvm_cv_enable_crash_overrides="yes" ;;
|
||||
no) llvm_cv_enable_crash_overrides="no" ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-crash-overrides. Use "yes" or "no"]) ;;
|
||||
esac],
|
||||
llvm_cv_enable_crash_overrides="yes")
|
||||
if test "$llvm_cv_enable_crash_overrides" = "yes" ; then
|
||||
AC_DEFINE([ENABLE_CRASH_OVERRIDES],[1],
|
||||
[Define to enable crash handling overrides])
|
||||
fi
|
||||
|
||||
dnl Allow specific targets to be specified for building (or not)
|
||||
TARGETS_TO_BUILD=""
|
||||
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
|
||||
[Build specific host targets: all or target1,target2,... Valid targets are:
|
||||
host, x86, x86_64, sparc, powerpc, arm, aarch64, mips, hexagon,
|
||||
xcore, msp430, nvptx, systemz, and cpp (default=all)]),,
|
||||
xcore, msp430, nvptx, systemz, r600, and cpp (default=all)]),,
|
||||
enableval=all)
|
||||
if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon SystemZ" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600" ;;
|
||||
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -821,9 +860,9 @@ case "$enableval" in
|
||||
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
|
||||
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
|
||||
host) case "$llvm_cv_target_arch" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -832,7 +871,6 @@ case "$enableval" in
|
||||
AArch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
|
||||
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
|
||||
@ -1056,6 +1094,17 @@ AC_ARG_WITH(bug-report-url,
|
||||
AC_DEFINE_UNQUOTED(BUG_REPORT_URL,"$withval",
|
||||
[Bug report URL.])
|
||||
|
||||
dnl --enable-terminfo: check whether the user wants to control use of terminfo:
|
||||
AC_ARG_ENABLE(terminfo,AS_HELP_STRING(
|
||||
[--enable-terminfo],
|
||||
[Query the terminfo database if available (default is YES)]),
|
||||
[case "$enableval" in
|
||||
yes) llvm_cv_enable_terminfo="yes" ;;
|
||||
no) llvm_cv_enable_terminfo="no" ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-terminfo. Use "yes" or "no"]) ;;
|
||||
esac],
|
||||
llvm_cv_enable_terminfo="yes")
|
||||
|
||||
dnl --enable-libffi : check whether the user wants to turn off libffi:
|
||||
AC_ARG_ENABLE(libffi,AS_HELP_STRING(
|
||||
--enable-libffi,[Check for the presence of libffi (default is NO)]),
|
||||
@ -1179,15 +1228,15 @@ if test "$DOTTY" != "echo dotty" ; then
|
||||
AC_DEFINE_UNQUOTED([LLVM_PATH_DOTTY],"$DOTTY${EXEEXT}",
|
||||
[Define to path to dotty program if found or 'echo dotty' otherwise])
|
||||
fi
|
||||
AC_PATH_PROG(XDOT_PY, [xdot.py], [echo xdot.py])
|
||||
if test "$XDOT_PY" != "echo xdot.py" ; then
|
||||
AC_DEFINE([HAVE_XDOT_PY],[1],[Define if the xdot.py program is available])
|
||||
AC_PATH_PROGS(XDOT, [xdot xdot.py], [echo xdot])
|
||||
if test "$XDOT" != "echo xdot" ; then
|
||||
AC_DEFINE([HAVE_XDOT],[1],[Define if the xdot program is available])
|
||||
dnl If we're targeting for mingw we should emit windows paths, not msys
|
||||
if test "$llvm_cv_os_type" = "MingW" ; then
|
||||
XDOT_PY=`echo $XDOT_PY | sed 's/^\/\([[A-Za-z]]\)\//\1:\//' `
|
||||
XDOT=`echo $XDOT | sed 's/^\/\([[A-Za-z]]\)\//\1:\//' `
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([LLVM_PATH_XDOT_PY],"$XDOT_PY${EXEEXT}",
|
||||
[Define to path to xdot.py program if found or 'echo xdot.py' otherwise])
|
||||
AC_DEFINE_UNQUOTED([LLVM_PATH_XDOT],"$XDOT${EXEEXT}",
|
||||
[Define to path to xdot program if found or 'echo xdot' otherwise])
|
||||
fi
|
||||
|
||||
dnl Find the install program
|
||||
@ -1223,7 +1272,7 @@ AC_LINK_GET_VERSION
|
||||
dnl Determine whether the linker supports the -R option.
|
||||
AC_LINK_USE_R
|
||||
|
||||
dnl Determine whether the linker supports the -export-dynamic option.
|
||||
dnl Determine whether the compiler supports the -rdynamic option.
|
||||
AC_LINK_EXPORT_DYNAMIC
|
||||
|
||||
dnl Determine whether the linker supports the --version-script option.
|
||||
@ -1328,12 +1377,13 @@ else
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for python >= 2.5])
|
||||
ac_python_version=`$PYTHON -c 'import sys; print sys.version.split()[[0]]'`
|
||||
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" -eq "2" \
|
||||
&& test "$ac_python_version_minor" -ge "5" ; then
|
||||
if test "$ac_python_version_major" -gt "2" || \
|
||||
(test "$ac_python_version_major" -eq "2" && \
|
||||
test "$ac_python_version_minor" -ge "5") ; then
|
||||
AC_MSG_RESULT([$PYTHON ($ac_python_version)])
|
||||
else
|
||||
AC_MSG_RESULT([not found])
|
||||
@ -1350,6 +1400,7 @@ AC_CHECK_LIB(m,sin)
|
||||
if test "$llvm_cv_os_type" = "MingW" ; then
|
||||
AC_CHECK_LIB(imagehlp, main)
|
||||
AC_CHECK_LIB(psapi, main)
|
||||
AC_CHECK_LIB(shell32, main)
|
||||
fi
|
||||
|
||||
dnl dlopen() is required for plugin support.
|
||||
@ -1362,6 +1413,14 @@ dnl macros to detect whether clock_gettime is available, this just finds the
|
||||
dnl right libraries to link with.
|
||||
AC_SEARCH_LIBS(clock_gettime,rt)
|
||||
|
||||
dnl The curses library is optional; used for querying terminal info
|
||||
if test "$llvm_cv_enable_terminfo" = "yes" ; then
|
||||
dnl We need the has_color functionality in curses for it to be useful.
|
||||
AC_SEARCH_LIBS(setupterm,tinfo terminfo curses ncurses ncursesw,
|
||||
AC_DEFINE([HAVE_TERMINFO],[1],
|
||||
[Define if the setupterm() function is supported this platform.]))
|
||||
fi
|
||||
|
||||
dnl libffi is optional; used to call external functions from the interpreter
|
||||
if test "$llvm_cv_enable_libffi" = "yes" ; then
|
||||
AC_SEARCH_LIBS(ffi_call,ffi,AC_DEFINE([HAVE_FFI_CALL],[1],
|
||||
@ -1515,11 +1574,11 @@ AC_HEADER_TIME
|
||||
AC_LANG_PUSH([C++])
|
||||
AC_CHECK_HEADERS([cxxabi.h])
|
||||
AC_LANG_POP([C++])
|
||||
AC_CHECK_HEADERS([dlfcn.h execinfo.h fcntl.h inttypes.h limits.h link.h])
|
||||
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 windows.h])
|
||||
AC_CHECK_HEADERS([utime.h])
|
||||
AC_CHECK_HEADERS([sys/mman.h sys/param.h sys/resource.h sys/time.h sys/uio.h])
|
||||
AC_CHECK_HEADERS([sys/types.h sys/ioctl.h malloc/malloc.h mach/mach.h])
|
||||
AC_CHECK_HEADERS([sys/ioctl.h malloc/malloc.h mach/mach.h])
|
||||
AC_CHECK_HEADERS([valgrind/valgrind.h])
|
||||
AC_CHECK_HEADERS([fenv.h])
|
||||
AC_CHECK_DECLS([FE_ALL_EXCEPT, FE_INEXACT], [], [], [[#include <fenv.h>]])
|
||||
@ -1594,10 +1653,11 @@ AC_CHECK_FUNCS([powf fmodf strtof round ])
|
||||
AC_CHECK_FUNCS([log log2 log10 exp exp2])
|
||||
AC_CHECK_FUNCS([getpagesize getrusage getrlimit setrlimit gettimeofday ])
|
||||
AC_CHECK_FUNCS([isatty mkdtemp mkstemp ])
|
||||
AC_CHECK_FUNCS([mktemp posix_spawn pread realpath sbrk setrlimit strdup ])
|
||||
AC_CHECK_FUNCS([mktemp posix_spawn pread realpath sbrk setrlimit ])
|
||||
AC_CHECK_FUNCS([strerror strerror_r setenv arc4random ])
|
||||
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
|
||||
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp writev])
|
||||
AC_CHECK_FUNCS([futimes futimens])
|
||||
AC_C_PRINTF_A
|
||||
AC_FUNC_RAND48
|
||||
|
||||
@ -1736,7 +1796,6 @@ if test "${prefix}" = "NONE" ; then
|
||||
fi
|
||||
eval LLVM_PREFIX="${prefix}";
|
||||
eval LLVM_BINDIR="${prefix}/bin";
|
||||
eval LLVM_LIBDIR="${prefix}/lib";
|
||||
eval LLVM_DATADIR="${prefix}/share/llvm";
|
||||
eval LLVM_DOCSDIR="${prefix}/share/doc/llvm";
|
||||
eval LLVM_ETCDIR="${prefix}/etc/llvm";
|
||||
@ -1746,7 +1805,6 @@ eval LLVM_MANDIR="${prefix}/man";
|
||||
LLVM_CONFIGTIME=`date`
|
||||
AC_SUBST(LLVM_PREFIX)
|
||||
AC_SUBST(LLVM_BINDIR)
|
||||
AC_SUBST(LLVM_LIBDIR)
|
||||
AC_SUBST(LLVM_DATADIR)
|
||||
AC_SUBST(LLVM_DOCSDIR)
|
||||
AC_SUBST(LLVM_ETCDIR)
|
||||
@ -1766,8 +1824,6 @@ AC_DEFINE_UNQUOTED(LLVM_PREFIX,"$LLVM_PREFIX",
|
||||
[Installation prefix directory])
|
||||
AC_DEFINE_UNQUOTED(LLVM_BINDIR, "$LLVM_BINDIR",
|
||||
[Installation directory for binary executables])
|
||||
AC_DEFINE_UNQUOTED(LLVM_LIBDIR, "$LLVM_LIBDIR",
|
||||
[Installation directory for libraries])
|
||||
AC_DEFINE_UNQUOTED(LLVM_DATADIR, "$LLVM_DATADIR",
|
||||
[Installation directory for data files])
|
||||
AC_DEFINE_UNQUOTED(LLVM_DOCSDIR, "$LLVM_DOCSDIR",
|
||||
@ -1827,7 +1883,7 @@ for a_binding in $BINDINGS_TO_BUILD ; do
|
||||
AC_SUBST(OCAML_LIBDIR,$ocaml_stdlib)
|
||||
else
|
||||
# ocaml stdlib is outside our prefix; use libdir/ocaml
|
||||
AC_SUBST(OCAML_LIBDIR,$LLVM_LIBDIR/ocaml)
|
||||
AC_SUBST(OCAML_LIBDIR,${prefix}/lib/ocaml)
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
@ -1850,7 +1906,7 @@ AC_SUBST(RPATH)
|
||||
|
||||
dnl Determine linker rdynamic flag
|
||||
if test "$llvm_cv_link_use_export_dynamic" = "yes" ; then
|
||||
RDYNAMIC="-Wl,-export-dynamic"
|
||||
RDYNAMIC="-rdynamic"
|
||||
else
|
||||
RDYNAMIC=""
|
||||
fi
|
||||
@ -1913,7 +1969,6 @@ AC_CONFIG_MAKEFILE(Makefile)
|
||||
AC_CONFIG_MAKEFILE(Makefile.common)
|
||||
AC_CONFIG_MAKEFILE(examples/Makefile)
|
||||
AC_CONFIG_MAKEFILE(lib/Makefile)
|
||||
AC_CONFIG_MAKEFILE(runtime/Makefile)
|
||||
AC_CONFIG_MAKEFILE(test/Makefile)
|
||||
AC_CONFIG_MAKEFILE(test/Makefile.tests)
|
||||
AC_CONFIG_MAKEFILE(unittests/Makefile)
|
||||
|
2
autoconf/m4/libtool.m4
vendored
2
autoconf/m4/libtool.m4
vendored
@ -530,7 +530,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
|
||||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_i386"
|
||||
;;
|
||||
ppc64-*linux*|powerpc64-*linux*)
|
||||
ppc64-*linux*|powerpc64-*linux*|ppc64le-*linux*|powerpc64le-*linux*)
|
||||
LD="${LD-ld} -m elf32ppclinux"
|
||||
;;
|
||||
s390x-*linux*)
|
||||
|
@ -40,23 +40,24 @@ if test "$llvm_cv_link_use_r" = yes ; then
|
||||
])
|
||||
|
||||
#
|
||||
# Determine if the system can handle the -R option being passed to the linker.
|
||||
# Determine if the system can handle the -rdynamic option being passed
|
||||
# to the compiler.
|
||||
#
|
||||
# This macro is specific to LLVM.
|
||||
#
|
||||
AC_DEFUN([AC_LINK_EXPORT_DYNAMIC],
|
||||
[AC_CACHE_CHECK([for compiler -Wl,-export-dynamic option],
|
||||
[AC_CACHE_CHECK([for compiler -rdynamic option],
|
||||
[llvm_cv_link_use_export_dynamic],
|
||||
[ AC_LANG_PUSH([C])
|
||||
oldcflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Wl,-export-dynamic"
|
||||
CFLAGS="$CFLAGS -rdynamic"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],
|
||||
[llvm_cv_link_use_export_dynamic=yes],[llvm_cv_link_use_export_dynamic=no])
|
||||
CFLAGS="$oldcflags"
|
||||
AC_LANG_POP([C])
|
||||
])
|
||||
if test "$llvm_cv_link_use_export_dynamic" = yes ; then
|
||||
AC_DEFINE([HAVE_LINK_EXPORT_DYNAMIC],[1],[Define if you can use -Wl,-export-dynamic.])
|
||||
AC_DEFINE([HAVE_LINK_EXPORT_DYNAMIC],[1],[Define if you can use -rdynamic.])
|
||||
fi
|
||||
])
|
||||
|
||||
|
@ -68,7 +68,6 @@ AC_REQUIRE([AC_HEADER_DIRENT])
|
||||
AC_REQUIRE([_LT_AC_CHECK_DLFCN])
|
||||
AC_REQUIRE([AC_LTDL_ENABLE_INSTALL])
|
||||
AC_REQUIRE([AC_LTDL_SHLIBEXT])
|
||||
AC_REQUIRE([AC_LTDL_SHLIBPATH])
|
||||
AC_REQUIRE([AC_LTDL_SYSSEARCHPATH])
|
||||
AC_REQUIRE([AC_LTDL_OBJDIR])
|
||||
AC_REQUIRE([AC_LTDL_DLPREOPEN])
|
||||
@ -78,15 +77,9 @@ AC_REQUIRE([AC_LTDL_DLSYM_USCORE])
|
||||
AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS])
|
||||
AC_REQUIRE([AC_LTDL_FUNC_ARGZ])
|
||||
|
||||
AC_CHECK_HEADERS([assert.h ctype.h errno.h malloc.h memory.h stdlib.h \
|
||||
stdio.h unistd.h])
|
||||
AC_CHECK_HEADERS([dl.h sys/dl.h dld.h mach-o/dyld.h])
|
||||
AC_CHECK_HEADERS([string.h strings.h], [break])
|
||||
AC_CHECK_HEADERS([errno.h malloc.h memory.h unistd.h])
|
||||
AC_CHECK_HEADERS([mach-o/dyld.h])
|
||||
|
||||
AC_CHECK_FUNCS([strchr index], [break])
|
||||
AC_CHECK_FUNCS([strrchr rindex], [break])
|
||||
AC_CHECK_FUNCS([memcpy bcopy], [break])
|
||||
AC_CHECK_FUNCS([memmove strcmp])
|
||||
AC_CHECK_FUNCS([closedir opendir readdir])
|
||||
])# AC_LIB_LTDL
|
||||
|
||||
@ -206,20 +199,6 @@ if test -n "$libltdl_cv_shlibext"; then
|
||||
fi
|
||||
])# AC_LTDL_SHLIBEXT
|
||||
|
||||
|
||||
# AC_LTDL_SHLIBPATH
|
||||
# -----------------
|
||||
AC_DEFUN([AC_LTDL_SHLIBPATH],
|
||||
[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER])
|
||||
AC_CACHE_CHECK([which variable specifies run-time library path],
|
||||
[libltdl_cv_shlibpath_var], [libltdl_cv_shlibpath_var="$shlibpath_var"])
|
||||
if test -n "$libltdl_cv_shlibpath_var"; then
|
||||
AC_DEFINE_UNQUOTED([LTDL_SHLIBPATH_VAR], ["$libltdl_cv_shlibpath_var"],
|
||||
[Define to the name of the environment variable that determines the dynamic library search path.])
|
||||
fi
|
||||
])# AC_LTDL_SHLIBPATH
|
||||
|
||||
|
||||
# AC_LTDL_SYSSEARCHPATH
|
||||
# ---------------------
|
||||
AC_DEFUN([AC_LTDL_SYSSEARCHPATH],
|
||||
|
@ -8,7 +8,8 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../..
|
||||
DIRS = llvm bitreader bitwriter analysis target executionengine transforms
|
||||
DIRS = llvm bitreader bitwriter irreader analysis target executionengine \
|
||||
transforms linker backends
|
||||
ExtraMakefiles = $(PROJ_OBJ_DIR)/Makefile.ocaml
|
||||
|
||||
ocamldoc:
|
||||
|
@ -1,4 +1,4 @@
|
||||
##===- tools/ml/Makefile -----------------------------------*- Makefile -*-===##
|
||||
##===- bindings/ocaml/Makefile.ocaml -----------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
@ -7,10 +7,10 @@
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# An ocaml library is a unique project type in the context of LLVM, so rules are
|
||||
# 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:
|
||||
# Reference materials on installing OCaml libraries:
|
||||
#
|
||||
# https://fedoraproject.org/wiki/Packaging/OCaml
|
||||
# http://pkg-ocaml-maint.alioth.debian.org/ocaml_packaging_policy.txt
|
||||
@ -23,6 +23,10 @@ include $(LEVEL)/Makefile.config
|
||||
CXX.Flags += -I"$(shell $(OCAMLC) -where)"
|
||||
C.Flags += -I"$(shell $(OCAMLC) -where)"
|
||||
|
||||
ifeq ($(ENABLE_SHARED),1)
|
||||
LINK_COMPONENTS := all
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
# Intentionally ignore PROJ_prefix here. We want the ocaml stdlib. However, the
|
||||
@ -38,6 +42,18 @@ UsedLibNames = $(shell $(LLVM_CONFIG) --libnames $(UsedComponents))
|
||||
endif
|
||||
endif
|
||||
|
||||
# How do we link OCaml executables with LLVM?
|
||||
# 1) If this is a --enable-shared build, build stub libraries. This also allows
|
||||
# to use LLVM from toplevels.
|
||||
# 2) If this is a --disable-shared build, embed ocamlc options for building
|
||||
# a custom runtime and a static executable. It is not possible to use LLVM
|
||||
# from toplevels.
|
||||
ifneq ($(ObjectsO),)
|
||||
ifeq ($(ENABLE_SHARED),1)
|
||||
OCAMLSTUBS := 1
|
||||
endif
|
||||
endif
|
||||
|
||||
# Tools
|
||||
OCAMLCFLAGS += -I $(ObjDir) -I $(OcamlDir)
|
||||
ifndef IS_CLEANING_TARGET
|
||||
@ -60,14 +76,36 @@ endif
|
||||
|
||||
Compile.CMI := $(strip $(OCAMLC) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
|
||||
Compile.CMO := $(strip $(OCAMLC) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
|
||||
Compile.CMX := $(strip $(OCAMLOPT) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
|
||||
|
||||
ifdef OCAMLSTUBS
|
||||
# Avoid the need for LD_LIBRARY_PATH
|
||||
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
ifneq ($(HOST_OS),Darwin)
|
||||
OCAMLRPATH := $(RPATH) -Wl,'$(SharedLibDir)'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef OCAMLSTUBS
|
||||
Archive.CMA := $(strip $(OCAMLC) -a -dllib -l$(LIBRARYNAME) $(OCAMLDEBUGFLAG) \
|
||||
-o)
|
||||
else
|
||||
Archive.CMA := $(strip $(OCAMLC) -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
|
||||
-o)
|
||||
endif
|
||||
|
||||
Compile.CMX := $(strip $(OCAMLOPT) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
|
||||
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) $(UsedOcamLibs:%=%.cmxa) $(OCAMLDEBUGFLAG) -o)
|
||||
Archive.EXE := $(strip $(OCAMLOPT) -cc $(CXX) $(OCAMLCFLAGS) $(UsedOcamlLibs:%=%.cmxa) $(OCAMLDEBUGFLAG) -o)
|
||||
else
|
||||
Archive.EXE := $(strip $(OCAMLC) -cc $(CXX) $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG:%=%.cma) -o)
|
||||
endif
|
||||
@ -113,6 +151,10 @@ OutputCMA := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma)
|
||||
OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa)
|
||||
endif
|
||||
|
||||
ifdef OCAMLSTUBS
|
||||
SharedLib := $(OcamlDir)/dll$(LIBRARYNAME)$(SHLIBEXT)
|
||||
endif
|
||||
|
||||
ifdef TOOLNAME
|
||||
ifdef EXAMPLE_TOOL
|
||||
OutputEXE := $(ExmplDir)/$(strip $(TOOLNAME))$(EXEEXT)
|
||||
@ -130,6 +172,10 @@ DestCMA := $(PROJ_libocamldir)/$(LIBRARYNAME).cma
|
||||
DestCMXA := $(PROJ_libocamldir)/$(LIBRARYNAME).cmxa
|
||||
endif
|
||||
|
||||
ifdef OCAMLSTUBS
|
||||
DestSharedLib := $(PROJ_libocamldir)/dll$(LIBRARYNAME)$(SHLIBEXT)
|
||||
endif
|
||||
|
||||
##===- Dependencies -------------------------------------------------------===##
|
||||
# Copy the sources into the intermediate directory because older ocamlc doesn't
|
||||
# support -o except when linking (outputs are placed next to inputs).
|
||||
@ -187,6 +233,34 @@ uninstall-a::
|
||||
endif
|
||||
|
||||
|
||||
##===- Build stub library from C sources ----------------------------------===##
|
||||
|
||||
ifdef SharedLib
|
||||
all-local:: $(SharedLib)
|
||||
clean-local:: clean-shared
|
||||
install-local:: install-shared
|
||||
uninstall-local:: uninstall-shared
|
||||
|
||||
$(SharedLib): $(ObjectsO) $(OcamlDir)/.dir
|
||||
$(Echo) "Building $(BuildMode) $(notdir $@)"
|
||||
$(Verb) $(Link) $(SharedLinkOptions) $(OCAMLRPATH) $(LLVMLibsOptions) \
|
||||
-o $@ $(ObjectsO)
|
||||
|
||||
clean-shared::
|
||||
-$(Verb) $(RM) -f $(SharedLib)
|
||||
|
||||
install-shared:: $(SharedLib)
|
||||
$(Echo) "Installing $(BuildMode) $(DestSharedLib)"
|
||||
$(Verb) $(MKDIR) $(PROJ_libocamldir)
|
||||
$(Verb) $(INSTALL) $(SharedLib) $(DestSharedLib)
|
||||
$(Verb)
|
||||
|
||||
uninstall-shared::
|
||||
$(Echo) "Uninstalling $(DestSharedLib)"
|
||||
-$(Verb) $(RM) -f $(DestSharedLib)
|
||||
endif
|
||||
|
||||
|
||||
##===- Deposit dependent libraries adjacent to Ocaml libs -----------------===##
|
||||
|
||||
all-local:: build-deplibs
|
||||
@ -391,6 +465,7 @@ printcamlvars::
|
||||
$(Echo) "CAML_LIBDIR : " '$(CAML_LIBDIR)'
|
||||
$(Echo) "LibraryCMA : " '$(LibraryCMA)'
|
||||
$(Echo) "LibraryCMXA : " '$(LibraryCMXA)'
|
||||
$(Echo) "SharedLib : " '$(SharedLib)'
|
||||
$(Echo) "OcamlSources1: " '$(OcamlSources1)'
|
||||
$(Echo) "OcamlSources2: " '$(OcamlSources2)'
|
||||
$(Echo) "OcamlSources : " '$(OcamlSources)'
|
||||
@ -404,6 +479,7 @@ printcamlvars::
|
||||
$(Echo) "DestA : " '$(DestA)'
|
||||
$(Echo) "DestCMA : " '$(DestCMA)'
|
||||
$(Echo) "DestCMXA : " '$(DestCMXA)'
|
||||
$(Echo) "DestSharedLib: " '$(DestSharedLib)'
|
||||
$(Echo) "UsedLibs : " '$(UsedLibs)'
|
||||
$(Echo) "UsedLibNames : " '$(UsedLibNames)'
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*===-- analysis_ocaml.c - LLVM Ocaml Glue ----------------------*- C++ -*-===*\
|
||||
/*===-- analysis_ocaml.c - LLVM OCaml Glue ----------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
@ -7,7 +7,7 @@
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_analysis.ml - LLVM Ocaml Interface -----------------*- C++ -*-===*
|
||||
(*===-- llvm_analysis.ml - LLVM OCaml Interface -----------------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_analysis.mli - LLVM Ocaml Interface ----------------*- C++ -*-===*
|
||||
(*===-- llvm_analysis.mli - LLVM OCaml Interface ----------------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
(** Intermediate representation analysis.
|
||||
|
||||
This interface provides an ocaml API for LLVM IR analyses, the classes in
|
||||
This interface provides an OCaml API for LLVM IR analyses, the classes in
|
||||
the Analysis library. *)
|
||||
|
||||
(** [verify_module m] returns [None] if the module [m] is valid, and
|
||||
|
8
bindings/ocaml/backends/META.llvm_backend.in
Normal file
8
bindings/ocaml/backends/META.llvm_backend.in
Normal file
@ -0,0 +1,8 @@
|
||||
name = "llvm_@TARGET@"
|
||||
version = "@PACKAGE_VERSION@"
|
||||
description = "@TARGET@ Backend for LLVM"
|
||||
requires = "llvm"
|
||||
archive(byte) = "llvm_@TARGET@.cma"
|
||||
archive(native) = "llvm_@TARGET@.cmxa"
|
||||
directory = "."
|
||||
linkopts = "-ccopt -lstdc++"
|
61
bindings/ocaml/backends/Makefile
Normal file
61
bindings/ocaml/backends/Makefile
Normal file
@ -0,0 +1,61 @@
|
||||
##===- bindings/ocaml/backends/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 master makefile for backend-specific bindings. It works by
|
||||
# creating a stub makefile for each configured target, e.g. Makefile.ARM, and
|
||||
# invoking it to compile the corresponding library, e.g. Llvm_ARM.
|
||||
#
|
||||
# This scheme allows to keep changes to Makefile.ocaml minimal.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../../..
|
||||
ExtraMakefiles = $(PROJ_OBJ_DIR)/Makefile.common
|
||||
|
||||
include $(LEVEL)/Makefile.config
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
all-local:: all-backends
|
||||
clean-local:: clean-backends
|
||||
install-local:: install-backends
|
||||
uninstall-local:: uninstall-backends
|
||||
|
||||
stubs:
|
||||
$(Verb) for i in $(TARGETS_TO_BUILD); do \
|
||||
$(ECHO) "TARGET := $$i" > Makefile.$$i; \
|
||||
$(ECHO) "include Makefile.common" >> Makefile.$$i; \
|
||||
done
|
||||
|
||||
all-backends: stubs
|
||||
$(Verb) for i in $(TARGETS_TO_BUILD); do \
|
||||
$(MAKE) -f Makefile.$$i all; \
|
||||
done
|
||||
|
||||
clean-backends: stubs
|
||||
$(Verb) for i in $(TARGETS_TO_BUILD); do \
|
||||
$(MAKE) -f Makefile.$$i clean; \
|
||||
$(RM) -f Makefile.$$i; \
|
||||
done
|
||||
|
||||
install-backends: stubs
|
||||
$(Verb) for i in $(TARGETS_TO_BUILD); do \
|
||||
$(MAKE) -f Makefile.$$i install; \
|
||||
done
|
||||
|
||||
uninstall-backends: stubs
|
||||
$(Verb) for i in $(TARGETS_TO_BUILD); do \
|
||||
$(MAKE) -f Makefile.$$i uninstall; \
|
||||
done
|
||||
|
||||
ocamldoc: stubs
|
||||
$(Verb) for i in $(TARGETS_TO_BUILD); do \
|
||||
$(MAKE) -f Makefile.$$i ocamldoc; \
|
||||
done
|
||||
|
||||
.PHONY: all-backends clean-backends install-backends uninstall-backends ocamldoc
|
65
bindings/ocaml/backends/Makefile.common
Normal file
65
bindings/ocaml/backends/Makefile.common
Normal file
@ -0,0 +1,65 @@
|
||||
##===- bindings/ocaml/backends/Makefile.common -------------*- 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 slave makefile for backend-specific bindings. This makefile should
|
||||
# be included after defining TARGET. It will then substitute @TARGET@ for
|
||||
# the value of TARGET in various *.in files and build an OCaml library in
|
||||
# a regular way.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm_$(TARGET)
|
||||
UsedComponents := $(TARGET)
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
include $(LEVEL)/Makefile.config
|
||||
|
||||
SOURCES := $(TARGET)_ocaml.c
|
||||
OcamlHeaders1 := $(PROJ_SRC_DIR)/llvm_$(TARGET).mli
|
||||
OcamlSources1 := $(PROJ_SRC_DIR)/llvm_$(TARGET).ml
|
||||
|
||||
include ../Makefile.ocaml
|
||||
|
||||
$(ObjDir)/llvm_$(TARGET).ml: $(PROJ_SRC_DIR)/llvm_backend.ml.in $(ObjDir)/.dir
|
||||
$(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' $< > $@
|
||||
|
||||
$(ObjDir)/llvm_$(TARGET).mli: $(PROJ_SRC_DIR)/llvm_backend.mli.in $(ObjDir)/.dir
|
||||
$(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' $< > $@
|
||||
|
||||
$(ObjDir)/$(TARGET)_ocaml.o: $(PROJ_SRC_DIR)/backend_ocaml.c $(ObjDir)/.dir
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Verb) $(Compile.C) -DTARGET=$(TARGET) $< -o $@
|
||||
|
||||
|
||||
##===- OCamlFind Package --------------------------------------------------===##
|
||||
|
||||
all-local:: copy-meta
|
||||
install-local:: install-meta
|
||||
uninstall-local:: uninstall-meta
|
||||
|
||||
DestMETA := $(PROJ_libocamldir)/META.llvm_$(TARGET)
|
||||
|
||||
# Easy way of generating META in the objdir
|
||||
copy-meta: $(OcamlDir)/META.llvm_$(TARGET)
|
||||
|
||||
$(OcamlDir)/META.llvm_$(TARGET): META.llvm_backend.in
|
||||
$(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' \
|
||||
-e 's/@PACKAGE_VERSION@/$(LLVMVersion)/' $< > $@
|
||||
|
||||
install-meta:: $(OcamlDir)/META.llvm_$(TARGET)
|
||||
$(Echo) "Install $(BuildMode) $(DestMETA)"
|
||||
$(Verb) $(MKDIR) $(PROJ_libocamldir)
|
||||
$(Verb) $(DataInstall) $< "$(DestMETA)"
|
||||
|
||||
uninstall-meta::
|
||||
$(Echo) "Uninstalling $(DestMETA)"
|
||||
-$(Verb) $(RM) -f "$(DestMETA)"
|
||||
|
||||
.PHONY: copy-meta install-meta uninstall-meta
|
37
bindings/ocaml/backends/backend_ocaml.c
Normal file
37
bindings/ocaml/backends/backend_ocaml.c
Normal file
@ -0,0 +1,37 @@
|
||||
/*===-- backend_ocaml.c - LLVM OCaml Glue -----------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
|* macros, since most of the parameters are not GC heap objects. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c/Target.h"
|
||||
#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();
|
||||
|
||||
#define INITIALIZER1(target) \
|
||||
CAMLprim value llvm_initialize_ ## target(value Unit) { \
|
||||
LLVMInitialize ## target ## TargetInfo(); \
|
||||
LLVMInitialize ## target ## Target(); \
|
||||
LLVMInitialize ## target ## TargetMC(); \
|
||||
return Val_unit; \
|
||||
}
|
||||
|
||||
#define INITIALIZER(target) INITIALIZER1(target)
|
||||
|
||||
INITIALIZER(TARGET)
|
10
bindings/ocaml/backends/llvm_backend.ml.in
Normal file
10
bindings/ocaml/backends/llvm_backend.ml.in
Normal file
@ -0,0 +1,10 @@
|
||||
(*===-- llvm_backend.ml.in - 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 initialize : unit -> unit = "llvm_initialize_@TARGET@"
|
19
bindings/ocaml/backends/llvm_backend.mli.in
Normal file
19
bindings/ocaml/backends/llvm_backend.mli.in
Normal file
@ -0,0 +1,19 @@
|
||||
(*===-- llvm_backend.mli.in - 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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
(** @TARGET@ Initialization.
|
||||
|
||||
This interface provides an OCaml API for initialization of
|
||||
the @TARGET@ LLVM target. By referencing this module, you will cause
|
||||
OCaml to load or link in the LLVM libraries corresponding to the target.
|
||||
By calling [initialize], you will register components of this target
|
||||
in the target registry, which is necessary in order to emit assembly,
|
||||
object files, and so on. *)
|
||||
|
||||
external initialize : unit -> unit = "llvm_initialize_@TARGET@"
|
@ -1,4 +1,4 @@
|
||||
/*===-- bitwriter_ocaml.c - LLVM Ocaml Glue ---------------------*- C++ -*-===*\
|
||||
/*===-- bitwriter_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
@ -7,7 +7,7 @@
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_bitreader.ml - LLVM Ocaml Interface ----------------*- C++ -*-===*
|
||||
(*===-- llvm_bitreader.ml - LLVM OCaml Interface ----------------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_bitreader.mli - LLVM Ocaml Interface ---------------*- C++ -*-===*
|
||||
(*===-- llvm_bitreader.mli - LLVM OCaml Interface ---------------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
(** Bitcode reader.
|
||||
|
||||
This interface provides an ocaml API for the LLVM bitcode reader, the
|
||||
This interface provides an OCaml API for the LLVM bitcode reader, the
|
||||
classes in the Bitreader library. *)
|
||||
|
||||
exception Error of string
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*===-- bitwriter_ocaml.c - LLVM Ocaml Glue ---------------------*- C++ -*-===*\
|
||||
/*===-- bitwriter_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
@ -7,7 +7,7 @@
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_bitwriter.ml - LLVM Ocaml Interface ----------------*- C++ -*-===*
|
||||
(*===-- llvm_bitwriter.ml - LLVM OCaml Interface ----------------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
*
|
||||
*===----------------------------------------------------------------------===
|
||||
*
|
||||
* This interface provides an ocaml API for the LLVM intermediate
|
||||
* This interface provides an OCaml API for the LLVM intermediate
|
||||
* representation, the classes in the VMCore library.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_bitwriter.mli - LLVM Ocaml Interface ---------------*- C++ -*-===*
|
||||
(*===-- llvm_bitwriter.mli - LLVM OCaml Interface ---------------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
(** Bitcode writer.
|
||||
|
||||
This interface provides an ocaml API for the LLVM bitcode writer, the
|
||||
This interface provides an OCaml API for the LLVM bitcode writer, the
|
||||
classes in the Bitwriter library. *)
|
||||
|
||||
(** [write_bitcode_file m path] writes the bitcode for module [m] to the file at
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*===-- executionengine_ocaml.c - LLVM Ocaml Glue ---------------*- C++ -*-===*\
|
||||
/*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
@ -7,7 +7,7 @@
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
@ -324,3 +324,18 @@ CAMLprim value llvm_ee_free_machine_code(LLVMValueRef 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;
|
||||
TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
|
||||
DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
|
||||
LLVMDisposeMessage(TargetDataCStr);
|
||||
|
||||
return DataLayout;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_executionengine.ml - LLVM Ocaml Interface ----------*- C++ -*-===*
|
||||
(*===-- llvm_executionengine.ml - LLVM OCaml Interface ----------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -83,12 +83,11 @@ module ExecutionEngine = struct
|
||||
external free_machine_code: Llvm.llvalue -> t -> unit
|
||||
= "llvm_ee_free_machine_code"
|
||||
|
||||
external target_data: t -> Llvm_target.DataLayout.t
|
||||
= "LLVMGetExecutionEngineTargetData"
|
||||
external data_layout : t -> Llvm_target.DataLayout.t
|
||||
= "llvm_ee_get_data_layout"
|
||||
|
||||
(* The following are not bound. Patches are welcome.
|
||||
|
||||
get_target_data: t -> lltargetdata
|
||||
add_global_mapping: llvalue -> llgenericvalue -> t -> unit
|
||||
clear_all_global_mappings: t -> unit
|
||||
update_global_mapping: llvalue -> llgenericvalue -> t -> unit
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_executionengine.mli - LLVM Ocaml Interface ---------*- C++ -*-===*
|
||||
(*===-- llvm_executionengine.mli - LLVM OCaml Interface ---------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
(** JIT Interpreter.
|
||||
|
||||
This interface provides an ocaml API for LLVM execution engine (JIT/
|
||||
This interface provides an OCaml API for LLVM execution engine (JIT/
|
||||
interpreter), the classes in the ExecutionEngine library. *)
|
||||
|
||||
exception Error of string
|
||||
@ -43,7 +43,6 @@ module GenericValue: sig
|
||||
bitwidth [w]. See the field [llvm::GenericValue::IntVal]. *)
|
||||
val of_nativeint : Llvm.lltype -> nativeint -> t
|
||||
|
||||
|
||||
(** [of_int64 n w] boxes the int64 [i] in a generic value with the bitwidth
|
||||
[w]. See the field [llvm::GenericValue::IntVal]. *)
|
||||
val of_int64 : Llvm.lltype -> int64 -> t
|
||||
@ -110,7 +109,7 @@ module ExecutionEngine: sig
|
||||
(** [dispose ee] releases the memory used by the execution engine and must be
|
||||
invoked to avoid memory leaks. *)
|
||||
val dispose : t -> unit
|
||||
|
||||
|
||||
(** [add_module m ee] adds the module [m] to the execution engine [ee]. *)
|
||||
val add_module : Llvm.llmodule -> t -> unit
|
||||
|
||||
@ -119,19 +118,16 @@ module ExecutionEngine: sig
|
||||
[Error msg] if an error occurs. *)
|
||||
val remove_module : Llvm.llmodule -> t -> Llvm.llmodule
|
||||
|
||||
|
||||
(** [find_function n ee] finds the function named [n] defined in any of the
|
||||
modules owned by the execution engine [ee]. Returns [None] if the function
|
||||
is not found and [Some f] otherwise. *)
|
||||
val find_function : string -> t -> Llvm.llvalue option
|
||||
|
||||
|
||||
(** [run_function f args ee] synchronously executes the function [f] with the
|
||||
arguments [args], which must be compatible with the parameter types. *)
|
||||
val run_function : Llvm.llvalue -> GenericValue.t array -> t ->
|
||||
GenericValue.t
|
||||
|
||||
|
||||
(** [run_static_ctors ee] executes the static constructors of each module in
|
||||
the execution engine [ee]. *)
|
||||
val run_static_ctors : t -> unit
|
||||
@ -147,17 +143,12 @@ module ExecutionEngine: sig
|
||||
val run_function_as_main : Llvm.llvalue -> string array ->
|
||||
(string * string) array -> t -> int
|
||||
|
||||
|
||||
(** [free_machine_code f ee] releases the memory in the execution engine [ee]
|
||||
used to store the machine code for the function [f]. *)
|
||||
val free_machine_code : Llvm.llvalue -> t -> unit
|
||||
|
||||
|
||||
(** [target_data ee] is the target data owned by the execution engine
|
||||
[ee]. *)
|
||||
val target_data : t -> Llvm_target.DataLayout.t
|
||||
|
||||
(** [data_layout ee] is the data layout of the execution engine [ee]. *)
|
||||
val data_layout : t -> Llvm_target.DataLayout.t
|
||||
end
|
||||
|
||||
val initialize_native_target : unit -> bool
|
||||
|
||||
|
19
bindings/ocaml/irreader/Makefile
Normal file
19
bindings/ocaml/irreader/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
##===- bindings/ocaml/irreader/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_irreader interface.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm_irreader
|
||||
UsedComponents := irreader
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
include ../Makefile.ocaml
|
59
bindings/ocaml/irreader/irreader_ocaml.c
Normal file
59
bindings/ocaml/irreader/irreader_ocaml.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*===-- irreader_ocaml.c - LLVM OCaml Glue ----------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c/IRReader.h"
|
||||
#include "caml/alloc.h"
|
||||
#include "caml/fail.h"
|
||||
#include "caml/memory.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 -----------------------------------------------------------===*/
|
||||
|
||||
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
|
||||
CAMLprim value llvm_parse_ir(LLVMContextRef C,
|
||||
LLVMMemoryBufferRef MemBuf) {
|
||||
CAMLparam0();
|
||||
CAMLlocal2(Variant, MessageVal);
|
||||
LLVMModuleRef M;
|
||||
char *Message;
|
||||
|
||||
if (LLVMParseIRInContext(C, MemBuf, &M, &Message))
|
||||
llvm_raise(llvm_irreader_error_exn, Message);
|
||||
|
||||
CAMLreturn((value) M);
|
||||
}
|
17
bindings/ocaml/irreader/llvm_irreader.ml
Normal file
17
bindings/ocaml/irreader/llvm_irreader.ml
Normal file
@ -0,0 +1,17 @@
|
||||
(*===-- llvm_irreader.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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
|
||||
exception Error of string
|
||||
|
||||
external register_exns : exn -> unit = "llvm_register_irreader_exns"
|
||||
let _ = register_exns (Error "")
|
||||
|
||||
external parse_ir : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||
= "llvm_parse_ir"
|
21
bindings/ocaml/irreader/llvm_irreader.mli
Normal file
21
bindings/ocaml/irreader/llvm_irreader.mli
Normal file
@ -0,0 +1,21 @@
|
||||
(*===-- llvm_irreader.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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
(** IR reader.
|
||||
|
||||
This interface provides an OCaml API for the LLVM assembly reader, the
|
||||
classes in the IRReader library. *)
|
||||
|
||||
exception Error of string
|
||||
|
||||
(** [parse_ir context mb] parses the IR 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
|
||||
encountered. See the function [llvm::ParseIR]. *)
|
||||
val parse_ir : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
19
bindings/ocaml/linker/Makefile
Normal file
19
bindings/ocaml/linker/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
##===- bindings/ocaml/linker/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_target interface.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm_linker
|
||||
UsedComponents := linker
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
include ../Makefile.ocaml
|
54
bindings/ocaml/linker/linker_ocaml.c
Normal file
54
bindings/ocaml/linker/linker_ocaml.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*===-- linker_ocaml.c - LLVM Ocaml Glue ------------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
|* macros, since most of the parameters are not GC heap objects. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c/Linker.h"
|
||||
#include "caml/alloc.h"
|
||||
#include "caml/memory.h"
|
||||
#include "caml/fail.h"
|
||||
|
||||
static value llvm_linker_error_exn;
|
||||
|
||||
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) {
|
||||
char* Message;
|
||||
|
||||
if (LLVMLinkModules(Dst, Src, Int_val(Mode), &Message))
|
||||
llvm_raise(llvm_linker_error_exn, Message);
|
||||
|
||||
return Val_unit;
|
||||
}
|
22
bindings/ocaml/linker/llvm_linker.ml
Normal file
22
bindings/ocaml/linker/llvm_linker.ml
Normal file
@ -0,0 +1,22 @@
|
||||
(*===-- llvm_linker.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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
exception Error of string
|
||||
|
||||
external register_exns : exn -> unit = "llvm_register_linker_exns"
|
||||
let _ = register_exns (Error "")
|
||||
|
||||
module Mode = struct
|
||||
type t =
|
||||
| DestroySource
|
||||
| PreserveSource
|
||||
end
|
||||
|
||||
external link_modules : Llvm.llmodule -> Llvm.llmodule -> Mode.t -> unit
|
||||
= "llvm_link_modules"
|
26
bindings/ocaml/linker/llvm_linker.mli
Normal file
26
bindings/ocaml/linker/llvm_linker.mli
Normal file
@ -0,0 +1,26 @@
|
||||
(*===-- llvm_linker.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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
(** Linker.
|
||||
|
||||
This interface provides an OCaml API for LLVM bitcode linker,
|
||||
the classes in the Linker library. *)
|
||||
|
||||
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
|
@ -46,6 +46,14 @@ package "ipo" (
|
||||
archive(native) = "llvm_ipo.cmxa"
|
||||
)
|
||||
|
||||
package "irreader" (
|
||||
requires = "llvm"
|
||||
version = "@PACKAGE_VERSION@"
|
||||
description = "IR assembly reader for LLVM"
|
||||
archive(byte) = "llvm_irreader.cma"
|
||||
archive(native) = "llvm_irreader.cmxa"
|
||||
)
|
||||
|
||||
package "scalar_opts" (
|
||||
requires = "llvm"
|
||||
version = "@PACKAGE_VERSION@"
|
||||
@ -54,6 +62,22 @@ package "scalar_opts" (
|
||||
archive(native) = "llvm_scalar_opts.cmxa"
|
||||
)
|
||||
|
||||
package "vectorize" (
|
||||
requires = "llvm"
|
||||
version = "@PACKAGE_VERSION@"
|
||||
description = "Vector Transforms for LLVM"
|
||||
archive(byte) = "llvm_vectorize.cma"
|
||||
archive(native) = "llvm_vectorize.cmxa"
|
||||
)
|
||||
|
||||
package "passmgr_builder" (
|
||||
requires = "llvm"
|
||||
version = "@PACKAGE_VERSION@"
|
||||
description = "Pass Manager Builder for LLVM"
|
||||
archive(byte) = "llvm_passmgr_builder.cma"
|
||||
archive(native) = "llvm_passmgr_builder.cmxa"
|
||||
)
|
||||
|
||||
package "target" (
|
||||
requires = "llvm"
|
||||
version = "@PACKAGE_VERSION@"
|
||||
@ -61,3 +85,11 @@ package "target" (
|
||||
archive(byte) = "llvm_target.cma"
|
||||
archive(native) = "llvm_target.cmxa"
|
||||
)
|
||||
|
||||
package "linker" (
|
||||
requires = "llvm"
|
||||
version = "@PACKAGE_VERSION@"
|
||||
description = "Intermediate Representation Linker for LLVM"
|
||||
archive(byte) = "llvm_linker.cma"
|
||||
archive(native) = "llvm_linker.cmxa"
|
||||
)
|
||||
|
@ -14,7 +14,7 @@
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm
|
||||
UsedComponents := core
|
||||
UsedOcamLibs := llvm
|
||||
UsedOcamlLibs := llvm
|
||||
|
||||
include ../Makefile.ocaml
|
||||
|
||||
|
@ -34,6 +34,7 @@ module TypeKind = struct
|
||||
| Pointer
|
||||
| Vector
|
||||
| Metadata
|
||||
| X86_mmx
|
||||
end
|
||||
|
||||
module Linkage = struct
|
||||
@ -42,6 +43,7 @@ module Linkage = struct
|
||||
| Available_externally
|
||||
| Link_once
|
||||
| Link_once_odr
|
||||
| Link_once_odr_auto_hide
|
||||
| Weak
|
||||
| Weak_odr
|
||||
| Appending
|
||||
@ -53,6 +55,7 @@ module Linkage = struct
|
||||
| Ghost
|
||||
| Common
|
||||
| Linker_private
|
||||
| Linker_private_weak
|
||||
end
|
||||
|
||||
module Visibility = struct
|
||||
@ -202,7 +205,48 @@ module Opcode = struct
|
||||
| AtomicRMW
|
||||
| Resume
|
||||
| LandingPad
|
||||
| Unwind
|
||||
end
|
||||
|
||||
module LandingPadClauseTy = struct
|
||||
type t =
|
||||
| Catch
|
||||
| Filter
|
||||
end
|
||||
|
||||
module ThreadLocalMode = struct
|
||||
type t =
|
||||
| None
|
||||
| GeneralDynamic
|
||||
| LocalDynamic
|
||||
| InitialExec
|
||||
| LocalExec
|
||||
end
|
||||
|
||||
module AtomicOrdering = struct
|
||||
type t =
|
||||
| NotAtomic
|
||||
| Unordered
|
||||
| Monotonic
|
||||
| Invalid
|
||||
| Acquire
|
||||
| Release
|
||||
| AcqiureRelease
|
||||
| SequentiallyConsistent
|
||||
end
|
||||
|
||||
module AtomicRMWBinOp = struct
|
||||
type t =
|
||||
| Xchg
|
||||
| Add
|
||||
| Sub
|
||||
| And
|
||||
| Nand
|
||||
| Or
|
||||
| Xor
|
||||
| Max
|
||||
| Min
|
||||
| UMax
|
||||
| UMin
|
||||
end
|
||||
|
||||
module ValueKind = struct
|
||||
@ -216,6 +260,8 @@ module ValueKind = struct
|
||||
| BlockAddress
|
||||
| ConstantAggregateZero
|
||||
| ConstantArray
|
||||
| ConstantDataArray
|
||||
| ConstantDataVector
|
||||
| ConstantExpr
|
||||
| ConstantFP
|
||||
| ConstantInt
|
||||
@ -234,6 +280,13 @@ exception IoError of string
|
||||
external register_exns : exn -> unit = "llvm_register_core_exns"
|
||||
let _ = register_exns (IoError "")
|
||||
|
||||
external install_fatal_error_handler : (string -> unit) -> unit
|
||||
= "llvm_install_fatal_error_handler"
|
||||
external reset_fatal_error_handler : unit -> unit
|
||||
= "llvm_reset_fatal_error_handler"
|
||||
external enable_pretty_stacktrace : unit -> unit
|
||||
= "llvm_enable_pretty_stacktrace"
|
||||
|
||||
type ('a, 'b) llpos =
|
||||
| At_end of 'a
|
||||
| Before of 'b
|
||||
@ -260,6 +313,8 @@ external data_layout: llmodule -> string
|
||||
external set_data_layout: string -> llmodule -> unit
|
||||
= "llvm_set_data_layout"
|
||||
external dump_module : llmodule -> unit = "llvm_dump_module"
|
||||
external print_module : string -> llmodule -> unit = "llvm_print_module"
|
||||
external string_of_llmodule : llmodule -> string = "llvm_string_of_llmodule"
|
||||
external set_module_inline_asm : llmodule -> string -> unit
|
||||
= "llvm_set_module_inline_asm"
|
||||
external module_context : llmodule -> llcontext = "LLVMGetModuleContext"
|
||||
@ -268,6 +323,8 @@ external module_context : llmodule -> llcontext = "LLVMGetModuleContext"
|
||||
external classify_type : lltype -> TypeKind.t = "llvm_classify_type"
|
||||
external type_context : lltype -> llcontext = "llvm_type_context"
|
||||
external type_is_sized : lltype -> bool = "llvm_type_is_sized"
|
||||
external dump_type : lltype -> unit = "llvm_dump_type"
|
||||
external string_of_lltype : lltype -> string = "llvm_string_of_lltype"
|
||||
|
||||
(*--... Operations on integer types ........................................--*)
|
||||
external i1_type : llcontext -> lltype = "llvm_i1_type"
|
||||
@ -323,6 +380,7 @@ external vector_size : lltype -> int = "llvm_vector_size"
|
||||
(*--... Operations on other types ..........................................--*)
|
||||
external void_type : llcontext -> lltype = "llvm_void_type"
|
||||
external label_type : llcontext -> lltype = "llvm_label_type"
|
||||
external x86_mmx_type : llcontext -> lltype = "llvm_x86_mmx_type"
|
||||
external type_by_name : llmodule -> string -> lltype option = "llvm_type_by_name"
|
||||
|
||||
external classify_value : llvalue -> ValueKind.t = "llvm_classify_value"
|
||||
@ -331,8 +389,9 @@ external type_of : llvalue -> lltype = "llvm_type_of"
|
||||
external value_name : llvalue -> string = "llvm_value_name"
|
||||
external set_value_name : string -> llvalue -> unit = "llvm_set_value_name"
|
||||
external dump_value : llvalue -> unit = "llvm_dump_value"
|
||||
external string_of_llvalue : llvalue -> string = "llvm_string_of_llvalue"
|
||||
external replace_all_uses_with : llvalue -> llvalue -> unit
|
||||
= "LLVMReplaceAllUsesWith"
|
||||
= "llvm_replace_all_uses_with"
|
||||
|
||||
(*--... Operations on uses .................................................--*)
|
||||
external use_begin : llvalue -> lluse option = "llvm_use_begin"
|
||||
@ -391,7 +450,10 @@ external clear_metadata : llvalue -> int -> unit = "llvm_clear_metadata"
|
||||
external mdstring : llcontext -> string -> llvalue = "llvm_mdstring"
|
||||
external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode"
|
||||
external get_mdstring : llvalue -> string option = "llvm_get_mdstring"
|
||||
external get_named_metadata : llmodule -> string -> llvalue array = "llvm_get_namedmd"
|
||||
external get_named_metadata : llmodule -> string -> llvalue array
|
||||
= "llvm_get_namedmd"
|
||||
external add_named_metadata_operand : llmodule -> string -> llvalue -> unit
|
||||
= "llvm_append_namedmd"
|
||||
|
||||
(*--... Operations on scalar constants .....................................--*)
|
||||
external const_int : lltype -> int -> llvalue = "llvm_const_int"
|
||||
@ -477,7 +539,8 @@ external const_trunc_or_bitcast : llvalue -> lltype -> llvalue
|
||||
= "LLVMConstTruncOrBitCast"
|
||||
external const_pointercast : llvalue -> lltype -> llvalue
|
||||
= "LLVMConstPointerCast"
|
||||
external const_intcast : llvalue -> lltype -> llvalue = "LLVMConstIntCast"
|
||||
external const_intcast : llvalue -> lltype -> is_signed:bool -> llvalue
|
||||
= "llvm_const_intcast"
|
||||
external const_fpcast : llvalue -> lltype -> llvalue = "LLVMConstFPCast"
|
||||
external const_select : llvalue -> llvalue -> llvalue -> llvalue
|
||||
= "LLVMConstSelect"
|
||||
@ -530,6 +593,14 @@ external set_initializer : llvalue -> llvalue -> unit = "llvm_set_initializer"
|
||||
external remove_initializer : llvalue -> unit = "llvm_remove_initializer"
|
||||
external is_thread_local : llvalue -> bool = "llvm_is_thread_local"
|
||||
external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local"
|
||||
external thread_local_mode : llvalue -> ThreadLocalMode.t
|
||||
= "llvm_thread_local_mode"
|
||||
external set_thread_local_mode : ThreadLocalMode.t -> llvalue -> unit
|
||||
= "llvm_set_thread_local_mode"
|
||||
external is_externally_initialized : llvalue -> bool
|
||||
= "llvm_is_externally_initialized"
|
||||
external set_externally_initialized : bool -> llvalue -> unit
|
||||
= "llvm_set_externally_initialized"
|
||||
external global_begin : llmodule -> (llmodule, llvalue) llpos
|
||||
= "llvm_global_begin"
|
||||
external global_succ : llvalue -> (llmodule, llvalue) llpos
|
||||
@ -725,6 +796,10 @@ let unpack_attr (a : int32) : Attribute.t list =
|
||||
let add_function_attr llval attr =
|
||||
llvm_add_function_attr llval (pack_attr attr)
|
||||
|
||||
external add_target_dependent_function_attr
|
||||
: llvalue -> string -> string -> unit
|
||||
= "llvm_add_target_dependent_function_attr"
|
||||
|
||||
let remove_function_attr llval attr =
|
||||
llvm_remove_function_attr llval (pack_attr attr)
|
||||
|
||||
@ -803,6 +878,11 @@ external block_parent : llbasicblock -> llvalue = "LLVMGetBasicBlockParent"
|
||||
external basic_blocks : llvalue -> llbasicblock array = "llvm_basic_blocks"
|
||||
external entry_block : llvalue -> llbasicblock = "LLVMGetEntryBasicBlock"
|
||||
external delete_block : llbasicblock -> unit = "llvm_delete_block"
|
||||
external remove_block : llbasicblock -> unit = "llvm_remove_block"
|
||||
external move_block_before : llbasicblock -> llbasicblock -> unit
|
||||
= "llvm_move_block_before"
|
||||
external move_block_after : llbasicblock -> llbasicblock -> unit
|
||||
= "llvm_move_block_after"
|
||||
external append_block : llcontext -> string -> llvalue -> llbasicblock
|
||||
= "llvm_append_block"
|
||||
external insert_block : llcontext -> string -> llbasicblock -> llbasicblock
|
||||
@ -872,8 +952,6 @@ 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 icmp_predicate : llvalue -> Icmp.t option = "llvm_instr_icmp_predicate"
|
||||
|
||||
let rec iter_instrs_range f i e =
|
||||
if i = e then () else
|
||||
match i with
|
||||
@ -936,6 +1014,10 @@ let remove_instruction_param_attr llval i attr =
|
||||
external is_tail_call : llvalue -> bool = "llvm_is_tail_call"
|
||||
external set_tail_call : bool -> llvalue -> unit = "llvm_set_tail_call"
|
||||
|
||||
(*--... Operations on load/store instructions (only) .......................--*)
|
||||
external is_volatile : llvalue -> bool = "llvm_is_volatile"
|
||||
external set_volatile : bool -> llvalue -> unit = "llvm_set_volatile"
|
||||
|
||||
(*--... Operations on phi nodes ............................................--*)
|
||||
external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit
|
||||
= "llvm_add_incoming"
|
||||
@ -1078,6 +1160,11 @@ external build_load : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_load"
|
||||
external build_store : llvalue -> llvalue -> llbuilder -> llvalue
|
||||
= "llvm_build_store"
|
||||
external build_atomicrmw : AtomicRMWBinOp.t -> llvalue -> llvalue ->
|
||||
AtomicOrdering.t -> bool -> string -> llbuilder ->
|
||||
llvalue
|
||||
= "llvm_build_atomicrmw_bytecode"
|
||||
"llvm_build_atomicrmw_native"
|
||||
external build_gep : llvalue -> llvalue array -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_gep"
|
||||
external build_in_bounds_gep : llvalue -> llvalue array -> string ->
|
||||
@ -1167,6 +1254,9 @@ external build_ptrdiff : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
module MemoryBuffer = struct
|
||||
external of_file : string -> llmemorybuffer = "llvm_memorybuffer_of_file"
|
||||
external of_stdin : unit -> llmemorybuffer = "llvm_memorybuffer_of_stdin"
|
||||
external of_string : ?name:string -> string -> llmemorybuffer
|
||||
= "llvm_memorybuffer_of_string"
|
||||
external as_string : llmemorybuffer -> string = "llvm_memorybuffer_as_string"
|
||||
external dispose : llmemorybuffer -> unit = "llvm_memorybuffer_dispose"
|
||||
end
|
||||
|
||||
@ -1187,54 +1277,3 @@ module PassManager = struct
|
||||
external finalize : [ `Function ] t -> bool = "llvm_passmanager_finalize"
|
||||
external dispose : [< any ] t -> unit = "llvm_passmanager_dispose"
|
||||
end
|
||||
|
||||
|
||||
(*===-- Non-Externs -------------------------------------------------------===*)
|
||||
(* These functions are built using the externals, so must be declared late. *)
|
||||
|
||||
let concat2 sep arr =
|
||||
let s = ref "" in
|
||||
if 0 < Array.length arr then begin
|
||||
s := !s ^ arr.(0);
|
||||
for i = 1 to (Array.length arr) - 1 do
|
||||
s := !s ^ sep ^ arr.(i)
|
||||
done
|
||||
end;
|
||||
!s
|
||||
|
||||
let rec string_of_lltype ty =
|
||||
(* FIXME: stop infinite recursion! :) *)
|
||||
match classify_type ty with
|
||||
TypeKind.Integer -> "i" ^ string_of_int (integer_bitwidth ty)
|
||||
| TypeKind.Pointer ->
|
||||
(let ety = element_type ty in
|
||||
match classify_type ety with
|
||||
| TypeKind.Struct ->
|
||||
(match struct_name ety with
|
||||
| None -> (string_of_lltype ety)
|
||||
| Some s -> s) ^ "*"
|
||||
| _ -> (string_of_lltype (element_type ty)) ^ "*")
|
||||
| TypeKind.Struct ->
|
||||
let s = "{ " ^ (concat2 ", " (
|
||||
Array.map string_of_lltype (struct_element_types ty)
|
||||
)) ^ " }" in
|
||||
if is_packed ty
|
||||
then "<" ^ s ^ ">"
|
||||
else s
|
||||
| TypeKind.Array -> "[" ^ (string_of_int (array_length ty)) ^
|
||||
" x " ^ (string_of_lltype (element_type ty)) ^ "]"
|
||||
| TypeKind.Vector -> "<" ^ (string_of_int (vector_size ty)) ^
|
||||
" x " ^ (string_of_lltype (element_type ty)) ^ ">"
|
||||
| TypeKind.Function -> string_of_lltype (return_type ty) ^
|
||||
" (" ^ (concat2 ", " (
|
||||
Array.map string_of_lltype (param_types ty)
|
||||
)) ^ ")"
|
||||
| TypeKind.Label -> "label"
|
||||
| TypeKind.Ppc_fp128 -> "ppc_fp128"
|
||||
| TypeKind.Fp128 -> "fp128"
|
||||
| TypeKind.X86fp80 -> "x86_fp80"
|
||||
| TypeKind.Double -> "double"
|
||||
| TypeKind.Float -> "float"
|
||||
| TypeKind.Half -> "half"
|
||||
| TypeKind.Void -> "void"
|
||||
| TypeKind.Metadata -> "metadata"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/*===-- llvm_ocaml.c - LLVM Ocaml Glue --------------------------*- C++ -*-===*\
|
||||
/*===-- llvm_ocaml.c - LLVM OCaml Glue --------------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
@ -7,7 +7,7 @@
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
@ -33,6 +33,7 @@ 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;
|
||||
}
|
||||
|
||||
@ -50,6 +51,30 @@ static void llvm_raise(value Prototype, char *Message) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static value llvm_fatal_error_handler;
|
||||
|
||||
static void llvm_fatal_error_trampoline(const char *Reason) {
|
||||
callback(llvm_fatal_error_handler, copy_string(Reason));
|
||||
}
|
||||
|
||||
CAMLprim value llvm_install_fatal_error_handler(value Handler) {
|
||||
LLVMInstallFatalErrorHandler(llvm_fatal_error_trampoline);
|
||||
llvm_fatal_error_handler = Handler;
|
||||
caml_register_global_root(&llvm_fatal_error_handler);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
CAMLprim value llvm_reset_fatal_error_handler(value Unit) {
|
||||
caml_remove_global_root(&llvm_fatal_error_handler);
|
||||
LLVMResetFatalErrorHandler();
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
CAMLprim value llvm_enable_pretty_stacktrace(value Unit) {
|
||||
LLVMEnablePrettyStackTrace();
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
static value alloc_variant(int tag, void *Value) {
|
||||
value Iter = alloc_small(1, tag);
|
||||
Field(Iter, 0) = Val_op(Value);
|
||||
@ -158,6 +183,27 @@ CAMLprim value llvm_dump_module(LLVMModuleRef M) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llmodule -> string */
|
||||
CAMLprim value llvm_string_of_llmodule(LLVMModuleRef M) {
|
||||
char* ModuleCStr;
|
||||
ModuleCStr = LLVMPrintModuleToString(M);
|
||||
|
||||
value ModuleStr = caml_copy_string(ModuleCStr);
|
||||
LLVMDisposeMessage(ModuleCStr);
|
||||
|
||||
return ModuleStr;
|
||||
}
|
||||
|
||||
/* llmodule -> string -> unit */
|
||||
CAMLprim value llvm_set_module_inline_asm(LLVMModuleRef M, value Asm) {
|
||||
LLVMSetModuleInlineAsm(M, String_val(Asm));
|
||||
@ -180,6 +226,23 @@ CAMLprim LLVMContextRef llvm_type_context(LLVMTypeRef Ty) {
|
||||
return LLVMGetTypeContext(Ty);
|
||||
}
|
||||
|
||||
/* lltype -> unit */
|
||||
CAMLprim value llvm_dump_type(LLVMTypeRef Val) {
|
||||
LLVMDumpType(Val);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* lltype -> string */
|
||||
CAMLprim value llvm_string_of_lltype(LLVMTypeRef M) {
|
||||
char* TypeCStr;
|
||||
TypeCStr = LLVMPrintTypeToString(M);
|
||||
|
||||
value TypeStr = caml_copy_string(TypeCStr);
|
||||
LLVMDisposeMessage(TypeCStr);
|
||||
|
||||
return TypeStr;
|
||||
}
|
||||
|
||||
/*--... Operations on integer types ........................................--*/
|
||||
|
||||
/* llcontext -> lltype */
|
||||
@ -244,11 +307,6 @@ CAMLprim LLVMTypeRef llvm_ppc_fp128_type(LLVMContextRef Context) {
|
||||
return LLVMPPCFP128TypeInContext(Context);
|
||||
}
|
||||
|
||||
/* llcontext -> lltype */
|
||||
CAMLprim LLVMTypeRef llvm_x86mmx_type(LLVMContextRef Context) {
|
||||
return LLVMX86MMXTypeInContext(Context);
|
||||
}
|
||||
|
||||
/*--... Operations on function types .......................................--*/
|
||||
|
||||
/* lltype -> lltype array -> lltype */
|
||||
@ -386,6 +444,11 @@ CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) {
|
||||
return LLVMLabelTypeInContext(Context);
|
||||
}
|
||||
|
||||
/* llcontext -> lltype */
|
||||
CAMLprim LLVMTypeRef llvm_x86_mmx_type(LLVMContextRef Context) {
|
||||
return LLVMX86MMXTypeInContext(Context);
|
||||
}
|
||||
|
||||
CAMLprim value llvm_type_by_name(LLVMModuleRef M, value Name)
|
||||
{
|
||||
CAMLparam1(Name);
|
||||
@ -416,6 +479,8 @@ enum ValueKind {
|
||||
BlockAddress,
|
||||
ConstantAggregateZero,
|
||||
ConstantArray,
|
||||
ConstantDataArray,
|
||||
ConstantDataVector,
|
||||
ConstantExpr,
|
||||
ConstantFP,
|
||||
ConstantInt,
|
||||
@ -441,6 +506,8 @@ CAMLprim value llvm_classify_value(LLVMValueRef Val) {
|
||||
DEFINE_CASE(Val, BlockAddress);
|
||||
DEFINE_CASE(Val, ConstantAggregateZero);
|
||||
DEFINE_CASE(Val, ConstantArray);
|
||||
DEFINE_CASE(Val, ConstantDataArray);
|
||||
DEFINE_CASE(Val, ConstantDataVector);
|
||||
DEFINE_CASE(Val, ConstantExpr);
|
||||
DEFINE_CASE(Val, ConstantFP);
|
||||
DEFINE_CASE(Val, ConstantInt);
|
||||
@ -485,6 +552,24 @@ CAMLprim value llvm_dump_value(LLVMValueRef Val) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> string */
|
||||
CAMLprim value llvm_string_of_llvalue(LLVMValueRef M) {
|
||||
char* ValueCStr;
|
||||
ValueCStr = LLVMPrintValueToString(M);
|
||||
|
||||
value ValueStr = caml_copy_string(ValueCStr);
|
||||
LLVMDisposeMessage(ValueCStr);
|
||||
|
||||
return ValueStr;
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> unit */
|
||||
CAMLprim value llvm_replace_all_uses_with(LLVMValueRef OldVal,
|
||||
LLVMValueRef NewVal) {
|
||||
LLVMReplaceAllUsesWith(OldVal, NewVal);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*--... Operations on users ................................................--*/
|
||||
|
||||
/* llvalue -> int -> llvalue */
|
||||
@ -590,14 +675,22 @@ CAMLprim value llvm_get_mdstring(LLVMValueRef V) {
|
||||
CAMLreturn(Val_int(0));
|
||||
}
|
||||
|
||||
CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value name)
|
||||
/* llmodule -> string -> llvalue array */
|
||||
CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value Name)
|
||||
{
|
||||
CAMLparam1(name);
|
||||
CAMLparam1(Name);
|
||||
CAMLlocal1(Nodes);
|
||||
Nodes = alloc(LLVMGetNamedMetadataNumOperands(M, String_val(name)), 0);
|
||||
LLVMGetNamedMetadataOperands(M, String_val(name), (LLVMValueRef *) Nodes);
|
||||
Nodes = alloc(LLVMGetNamedMetadataNumOperands(M, String_val(Name)), 0);
|
||||
LLVMGetNamedMetadataOperands(M, String_val(Name), (LLVMValueRef *) Nodes);
|
||||
CAMLreturn(Nodes);
|
||||
}
|
||||
|
||||
/* llmodule -> string -> llvalue -> unit */
|
||||
CAMLprim value llvm_append_namedmd(LLVMModuleRef M, value Name, LLVMValueRef Val) {
|
||||
LLVMAddNamedMetadataOperand(M, String_val(Name), Val);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*--... Operations on scalar constants .....................................--*/
|
||||
|
||||
/* lltype -> int -> llvalue */
|
||||
@ -718,6 +811,12 @@ CAMLprim LLVMValueRef llvm_const_in_bounds_gep(LLVMValueRef ConstantVal,
|
||||
Wosize_val(Indices));
|
||||
}
|
||||
|
||||
/* llvalue -> lltype -> is_signed:bool -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_const_intcast(LLVMValueRef CV, LLVMTypeRef T,
|
||||
value IsSigned) {
|
||||
return LLVMConstIntCast(CV, T, Bool_val(IsSigned));
|
||||
}
|
||||
|
||||
/* llvalue -> int array -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_const_extractvalue(LLVMValueRef Aggregate,
|
||||
value Indices) {
|
||||
@ -877,7 +976,8 @@ CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name,
|
||||
LLVMPointerType(Ty, Int_val(AddressSpace)));
|
||||
return GlobalVar;
|
||||
}
|
||||
return LLVMAddGlobal(M, Ty, String_val(Name));
|
||||
return LLVMAddGlobalInAddressSpace(M, Ty, String_val(Name),
|
||||
Int_val(AddressSpace));
|
||||
}
|
||||
|
||||
/* string -> llmodule -> llvalue option */
|
||||
@ -945,6 +1045,30 @@ CAMLprim value llvm_set_thread_local(value IsThreadLocal,
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> ThreadLocalMode.t */
|
||||
CAMLprim value llvm_thread_local_mode(LLVMValueRef GlobalVar) {
|
||||
return Val_int(LLVMGetThreadLocalMode(GlobalVar));
|
||||
}
|
||||
|
||||
/* ThreadLocalMode.t -> llvalue -> unit */
|
||||
CAMLprim value llvm_set_thread_local_mode(value ThreadLocalMode,
|
||||
LLVMValueRef GlobalVar) {
|
||||
LLVMSetThreadLocalMode(GlobalVar, Int_val(ThreadLocalMode));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> bool */
|
||||
CAMLprim value llvm_is_externally_initialized(LLVMValueRef GlobalVar) {
|
||||
return Val_bool(LLVMIsExternallyInitialized(GlobalVar));
|
||||
}
|
||||
|
||||
/* bool -> llvalue -> unit */
|
||||
CAMLprim value llvm_set_externally_initialized(value IsExternallyInitialized,
|
||||
LLVMValueRef GlobalVar) {
|
||||
LLVMSetExternallyInitialized(GlobalVar, Bool_val(IsExternallyInitialized));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> bool */
|
||||
CAMLprim value llvm_is_global_constant(LLVMValueRef GlobalVar) {
|
||||
return Val_bool(LLVMIsGlobalConstant(GlobalVar));
|
||||
@ -1051,6 +1175,13 @@ CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> string -> string -> unit */
|
||||
CAMLprim value llvm_add_target_dependent_function_attr(
|
||||
LLVMValueRef Arg, value A, value V) {
|
||||
LLVMAddTargetDependentFunctionAttr(Arg, String_val(A), String_val(V));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> int32 */
|
||||
CAMLprim value llvm_function_attr(LLVMValueRef Fn)
|
||||
{
|
||||
@ -1135,6 +1266,24 @@ CAMLprim value llvm_delete_block(LLVMBasicBlockRef BB) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llbasicblock -> unit */
|
||||
CAMLprim value llvm_remove_block(LLVMBasicBlockRef BB) {
|
||||
LLVMRemoveBasicBlockFromParent(BB);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llbasicblock -> llbasicblock -> unit */
|
||||
CAMLprim value llvm_move_block_before(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
|
||||
LLVMMoveBasicBlockBefore(BB, Pos);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llbasicblock -> llbasicblock -> unit */
|
||||
CAMLprim value llvm_move_block_after(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
|
||||
LLVMMoveBasicBlockAfter(BB, Pos);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* string -> llvalue -> llbasicblock */
|
||||
CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name,
|
||||
LLVMValueRef Fn) {
|
||||
@ -1167,7 +1316,7 @@ CAMLprim value llvm_instr_get_opcode(LLVMValueRef Inst) {
|
||||
return Val_int(o);
|
||||
}
|
||||
|
||||
/* llvalue -> ICmp.t */
|
||||
/* llvalue -> ICmp.t option */
|
||||
CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) {
|
||||
CAMLparam0();
|
||||
int x = LLVMGetICmpPredicate(Val);
|
||||
@ -1223,6 +1372,20 @@ CAMLprim value llvm_set_tail_call(value IsTailCall,
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*--... Operations on load/store instructions (only)........................--*/
|
||||
|
||||
/* llvalue -> bool */
|
||||
CAMLprim value llvm_is_volatile(LLVMValueRef MemoryInst) {
|
||||
return Val_bool(LLVMGetVolatile(MemoryInst));
|
||||
}
|
||||
|
||||
/* bool -> llvalue -> unit */
|
||||
CAMLprim value llvm_set_volatile(value IsVolatile,
|
||||
LLVMValueRef MemoryInst) {
|
||||
LLVMSetVolatile(MemoryInst, Bool_val(IsVolatile));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*--... Operations on phi nodes ............................................--*/
|
||||
|
||||
/* (llvalue * llbasicblock) -> llvalue -> unit */
|
||||
@ -1271,7 +1434,7 @@ static void llvm_finalize_builder(value B) {
|
||||
}
|
||||
|
||||
static struct custom_operations builder_ops = {
|
||||
(char *) "IRBuilder",
|
||||
(char *) "LLVMIRBuilder",
|
||||
llvm_finalize_builder,
|
||||
custom_compare_default,
|
||||
custom_hash_default,
|
||||
@ -1694,6 +1857,24 @@ CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer,
|
||||
return LLVMBuildStore(Builder_val(B), Value, Pointer);
|
||||
}
|
||||
|
||||
/* AtomicRMWBinOp.t -> llvalue -> llvalue -> AtomicOrdering.t ->
|
||||
bool -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_atomicrmw_native(value BinOp, LLVMValueRef Ptr,
|
||||
LLVMValueRef Val, value Ord,
|
||||
value ST, value Name, value B) {
|
||||
LLVMValueRef Instr;
|
||||
Instr = LLVMBuildAtomicRMW(Builder_val(B), Int_val(BinOp),
|
||||
Ptr, Val, Int_val(Ord), Bool_val(ST));
|
||||
LLVMSetValueName(Instr, String_val(Name));
|
||||
return Instr;
|
||||
}
|
||||
|
||||
CAMLprim LLVMValueRef llvm_build_atomicrmw_bytecode(value *argv, int argn) {
|
||||
return llvm_build_atomicrmw_native(argv[0], (LLVMValueRef) argv[1],
|
||||
(LLVMValueRef) argv[2], argv[3],
|
||||
argv[4], argv[5], argv[6]);
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices,
|
||||
value Name, value B) {
|
||||
@ -1960,7 +2141,6 @@ CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
|
||||
/*===-- Memory buffers ----------------------------------------------------===*/
|
||||
|
||||
/* string -> llmemorybuffer
|
||||
@ -1989,6 +2169,30 @@ CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
|
||||
return MemBuf;
|
||||
}
|
||||
|
||||
/* ?name:string -> string -> llmemorybuffer */
|
||||
CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_string(value Name, value String) {
|
||||
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);
|
||||
|
||||
return MemBuf;
|
||||
}
|
||||
|
||||
/* llmemorybuffer -> string */
|
||||
CAMLprim value llvm_memorybuffer_as_string(LLVMMemoryBufferRef MemBuf) {
|
||||
value String = caml_alloc_string(LLVMGetBufferSize(MemBuf));
|
||||
memcpy(String_val(String), LLVMGetBufferStart(MemBuf),
|
||||
LLVMGetBufferSize(MemBuf));
|
||||
|
||||
return String;
|
||||
}
|
||||
|
||||
/* llmemorybuffer -> unit */
|
||||
CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
|
||||
LLVMDisposeMemoryBuffer(MemBuf);
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_target.ml - LLVM Ocaml Interface ------------------*- OCaml -*-===*
|
||||
(*===-- llvm_target.ml - LLVM OCaml Interface ------------------*- OCaml -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -13,30 +13,126 @@ module Endian = struct
|
||||
| Little
|
||||
end
|
||||
|
||||
module CodeGenOptLevel = struct
|
||||
type t =
|
||||
| None
|
||||
| Less
|
||||
| Default
|
||||
| Aggressive
|
||||
end
|
||||
|
||||
module RelocMode = struct
|
||||
type t =
|
||||
| Default
|
||||
| Static
|
||||
| PIC
|
||||
| DynamicNoPIC
|
||||
end
|
||||
|
||||
module CodeModel = struct
|
||||
type t =
|
||||
| Default
|
||||
| JITDefault
|
||||
| Small
|
||||
| Kernel
|
||||
| Medium
|
||||
| Large
|
||||
end
|
||||
|
||||
module CodeGenFileType = struct
|
||||
type t =
|
||||
| AssemblyFile
|
||||
| ObjectFile
|
||||
end
|
||||
|
||||
exception Error of string
|
||||
|
||||
external register_exns : exn -> unit = "llvm_register_target_exns"
|
||||
let _ = register_exns (Error "")
|
||||
|
||||
module DataLayout = struct
|
||||
type t
|
||||
|
||||
external create : string -> t = "llvm_targetdata_create"
|
||||
external add : t -> [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||
= "llvm_targetdata_add"
|
||||
external as_string : t -> string = "llvm_targetdata_as_string"
|
||||
external dispose : t -> unit = "llvm_targetdata_dispose"
|
||||
external of_string : string -> t = "llvm_datalayout_of_string"
|
||||
external as_string : t -> string = "llvm_datalayout_as_string"
|
||||
external add_to_pass_manager : [<Llvm.PassManager.any]
|
||||
Llvm.PassManager.t -> t -> unit
|
||||
= "llvm_datalayout_add_to_pass_manager"
|
||||
external byte_order : t -> Endian.t = "llvm_datalayout_byte_order"
|
||||
external pointer_size : t -> int = "llvm_datalayout_pointer_size"
|
||||
external intptr_type : Llvm.llcontext -> t -> Llvm.lltype
|
||||
= "llvm_datalayout_intptr_type"
|
||||
external qualified_pointer_size : int -> t -> int
|
||||
= "llvm_datalayout_qualified_pointer_size"
|
||||
external qualified_intptr_type : Llvm.llcontext -> int -> t -> Llvm.lltype
|
||||
= "llvm_datalayout_qualified_intptr_type"
|
||||
external size_in_bits : Llvm.lltype -> t -> Int64.t
|
||||
= "llvm_datalayout_size_in_bits"
|
||||
external store_size : Llvm.lltype -> t -> Int64.t
|
||||
= "llvm_datalayout_store_size"
|
||||
external abi_size : Llvm.lltype -> t -> Int64.t
|
||||
= "llvm_datalayout_abi_size"
|
||||
external abi_align : Llvm.lltype -> t -> int
|
||||
= "llvm_datalayout_abi_align"
|
||||
external stack_align : Llvm.lltype -> t -> int
|
||||
= "llvm_datalayout_stack_align"
|
||||
external preferred_align : Llvm.lltype -> t -> int
|
||||
= "llvm_datalayout_preferred_align"
|
||||
external preferred_align_of_global : Llvm.llvalue -> t -> int
|
||||
= "llvm_datalayout_preferred_align_of_global"
|
||||
external element_at_offset : Llvm.lltype -> Int64.t -> t -> int
|
||||
= "llvm_datalayout_element_at_offset"
|
||||
external offset_of_element : Llvm.lltype -> int -> t -> Int64.t
|
||||
= "llvm_datalayout_offset_of_element"
|
||||
end
|
||||
|
||||
external byte_order : DataLayout.t -> Endian.t = "llvm_byte_order"
|
||||
external pointer_size : DataLayout.t -> int = "llvm_pointer_size"
|
||||
external intptr_type : DataLayout.t -> Llvm.lltype = "LLVMIntPtrType"
|
||||
external size_in_bits : DataLayout.t -> Llvm.lltype -> Int64.t
|
||||
= "llvm_size_in_bits"
|
||||
external store_size : DataLayout.t -> Llvm.lltype -> Int64.t = "llvm_store_size"
|
||||
external abi_size : DataLayout.t -> Llvm.lltype -> Int64.t = "llvm_abi_size"
|
||||
external abi_align : DataLayout.t -> Llvm.lltype -> int = "llvm_abi_align"
|
||||
external stack_align : DataLayout.t -> Llvm.lltype -> int = "llvm_stack_align"
|
||||
external preferred_align : DataLayout.t -> Llvm.lltype -> int
|
||||
= "llvm_preferred_align"
|
||||
external preferred_align_of_global : DataLayout.t -> Llvm.llvalue -> int
|
||||
= "llvm_preferred_align_of_global"
|
||||
external element_at_offset : DataLayout.t -> Llvm.lltype -> Int64.t -> int
|
||||
= "llvm_element_at_offset"
|
||||
external offset_of_element : DataLayout.t -> Llvm.lltype -> int -> Int64.t
|
||||
= "llvm_offset_of_element"
|
||||
module Target = struct
|
||||
type t
|
||||
|
||||
external default_triple : unit -> string = "llvm_target_default_triple"
|
||||
external first : unit -> t option = "llvm_target_first"
|
||||
external succ : t -> t option = "llvm_target_succ"
|
||||
external by_name : string -> t option = "llvm_target_by_name"
|
||||
external by_triple : string -> t = "llvm_target_by_triple"
|
||||
external name : t -> string = "llvm_target_name"
|
||||
external description : t -> string = "llvm_target_description"
|
||||
external has_jit : t -> bool = "llvm_target_has_jit"
|
||||
external has_target_machine : t -> bool = "llvm_target_has_target_machine"
|
||||
external has_asm_backend : t -> bool = "llvm_target_has_asm_backend"
|
||||
|
||||
let all () =
|
||||
let rec step elem lst =
|
||||
match elem with
|
||||
| Some target -> step (succ target) (target :: lst)
|
||||
| None -> lst
|
||||
in
|
||||
step (first ()) []
|
||||
end
|
||||
|
||||
module TargetMachine = struct
|
||||
type t
|
||||
|
||||
external create : triple:string -> ?cpu:string -> ?features:string ->
|
||||
?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t ->
|
||||
?code_model:CodeModel.t -> Target.t -> t
|
||||
= "llvm_create_targetmachine_bytecode"
|
||||
"llvm_create_targetmachine_native"
|
||||
external target : t -> Target.t
|
||||
= "llvm_targetmachine_target"
|
||||
external triple : t -> string
|
||||
= "llvm_targetmachine_triple"
|
||||
external cpu : t -> string
|
||||
= "llvm_targetmachine_cpu"
|
||||
external features : t -> string
|
||||
= "llvm_targetmachine_features"
|
||||
external data_layout : t -> DataLayout.t
|
||||
= "llvm_targetmachine_data_layout"
|
||||
external set_verbose_asm : bool -> t -> unit
|
||||
= "llvm_targetmachine_set_verbose_asm"
|
||||
external emit_to_file : Llvm.llmodule -> CodeGenFileType.t -> string ->
|
||||
t -> unit
|
||||
= "llvm_targetmachine_emit_to_file"
|
||||
external emit_to_memory_buffer : Llvm.llmodule -> CodeGenFileType.t ->
|
||||
t -> Llvm.llmemorybuffer
|
||||
= "llvm_targetmachine_emit_to_memory_buffer"
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_target.mli - LLVM Ocaml Interface -----------------*- OCaml -*-===*
|
||||
(*===-- llvm_target.mli - LLVM OCaml Interface -----------------*- OCaml -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
(** Target Information.
|
||||
|
||||
This interface provides an ocaml API for LLVM target information,
|
||||
This interface provides an OCaml API for LLVM target information,
|
||||
the classes in the Target library. *)
|
||||
|
||||
module Endian : sig
|
||||
@ -18,78 +18,205 @@ module Endian : sig
|
||||
| Little
|
||||
end
|
||||
|
||||
module CodeGenOptLevel : sig
|
||||
type t =
|
||||
| None
|
||||
| Less
|
||||
| Default
|
||||
| Aggressive
|
||||
end
|
||||
|
||||
module RelocMode : sig
|
||||
type t =
|
||||
| Default
|
||||
| Static
|
||||
| PIC
|
||||
| DynamicNoPIC
|
||||
end
|
||||
|
||||
module CodeModel : sig
|
||||
type t =
|
||||
| Default
|
||||
| JITDefault
|
||||
| Small
|
||||
| Kernel
|
||||
| Medium
|
||||
| Large
|
||||
end
|
||||
|
||||
module CodeGenFileType : sig
|
||||
type t =
|
||||
| AssemblyFile
|
||||
| ObjectFile
|
||||
end
|
||||
|
||||
(** {6 Exceptions} *)
|
||||
|
||||
exception Error of string
|
||||
|
||||
(** {6 Data Layout} *)
|
||||
|
||||
module DataLayout : sig
|
||||
type t
|
||||
|
||||
(** [DataLayout.create rep] parses the target data string representation [rep].
|
||||
See the constructor llvm::DataLayout::DataLayout. *)
|
||||
external create : string -> t = "llvm_targetdata_create"
|
||||
(** [of_string rep] parses the data layout string representation [rep].
|
||||
See the constructor [llvm::DataLayout::DataLayout]. *)
|
||||
val of_string : string -> t
|
||||
|
||||
(** [add_target_data td pm] adds the target data [td] to the pass manager [pm].
|
||||
Does not take ownership of the target data.
|
||||
See the method llvm::PassManagerBase::add. *)
|
||||
external add : t -> [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||
= "llvm_targetdata_add"
|
||||
(** [as_string dl] is the string representation of the data layout [dl].
|
||||
See the method [llvm::DataLayout::getStringRepresentation]. *)
|
||||
val as_string : t -> string
|
||||
|
||||
(** [as_string td] is the string representation of the target data [td].
|
||||
See the constructor llvm::DataLayout::DataLayout. *)
|
||||
external as_string : t -> string = "llvm_targetdata_as_string"
|
||||
(** [add_to_pass_manager dl pm] adds the target data [dl] to
|
||||
the pass manager [pm].
|
||||
See the method [llvm::PassManagerBase::add]. *)
|
||||
val add_to_pass_manager : [<Llvm.PassManager.any] Llvm.PassManager.t ->
|
||||
t -> unit
|
||||
|
||||
(** Deallocates a DataLayout.
|
||||
See the destructor llvm::DataLayout::~DataLayout. *)
|
||||
external dispose : t -> unit = "llvm_targetdata_dispose"
|
||||
(** Returns the byte order of a target, either [Endian.Big] or
|
||||
[Endian.Little].
|
||||
See the method [llvm::DataLayout::isLittleEndian]. *)
|
||||
val byte_order : t -> Endian.t
|
||||
|
||||
(** Returns the pointer size in bytes for a target.
|
||||
See the method [llvm::DataLayout::getPointerSize]. *)
|
||||
val pointer_size : t -> int
|
||||
|
||||
(** Returns the integer type that is the same size as a pointer on a target.
|
||||
See the method [llvm::DataLayout::getIntPtrType]. *)
|
||||
val intptr_type : Llvm.llcontext -> t -> Llvm.lltype
|
||||
|
||||
(** Returns the pointer size in bytes for a target in a given address space.
|
||||
See the method [llvm::DataLayout::getPointerSize]. *)
|
||||
val qualified_pointer_size : int -> t -> int
|
||||
|
||||
(** Returns the integer type that is the same size as a pointer on a target
|
||||
in a given address space.
|
||||
See the method [llvm::DataLayout::getIntPtrType]. *)
|
||||
val qualified_intptr_type : Llvm.llcontext -> int -> t -> Llvm.lltype
|
||||
|
||||
(** Computes the size of a type in bits for a target.
|
||||
See the method [llvm::DataLayout::getTypeSizeInBits]. *)
|
||||
val size_in_bits : Llvm.lltype -> t -> Int64.t
|
||||
|
||||
(** Computes the storage size of a type in bytes for a target.
|
||||
See the method [llvm::DataLayout::getTypeStoreSize]. *)
|
||||
val store_size : Llvm.lltype -> t -> Int64.t
|
||||
|
||||
(** Computes the ABI size of a type in bytes for a target.
|
||||
See the method [llvm::DataLayout::getTypeAllocSize]. *)
|
||||
val abi_size : Llvm.lltype -> t -> Int64.t
|
||||
|
||||
(** Computes the ABI alignment of a type in bytes for a target.
|
||||
See the method [llvm::DataLayout::getTypeABISize]. *)
|
||||
val abi_align : Llvm.lltype -> t -> int
|
||||
|
||||
(** Computes the call frame alignment of a type in bytes for a target.
|
||||
See the method [llvm::DataLayout::getTypeABISize]. *)
|
||||
val stack_align : Llvm.lltype -> t -> int
|
||||
|
||||
(** Computes the preferred alignment of a type in bytes for a target.
|
||||
See the method [llvm::DataLayout::getTypeABISize]. *)
|
||||
val preferred_align : Llvm.lltype -> t -> int
|
||||
|
||||
(** Computes the preferred alignment of a global variable in bytes for
|
||||
a target. See the method [llvm::DataLayout::getPreferredAlignment]. *)
|
||||
val preferred_align_of_global : Llvm.llvalue -> t -> int
|
||||
|
||||
(** Computes the structure element that contains the byte offset for a target.
|
||||
See the method [llvm::StructLayout::getElementContainingOffset]. *)
|
||||
val element_at_offset : Llvm.lltype -> Int64.t -> t -> int
|
||||
|
||||
(** Computes the byte offset of the indexed struct element for a target.
|
||||
See the method [llvm::StructLayout::getElementContainingOffset]. *)
|
||||
val offset_of_element : Llvm.lltype -> int -> t -> Int64.t
|
||||
end
|
||||
|
||||
(** Returns the byte order of a target, either LLVMBigEndian or
|
||||
LLVMLittleEndian.
|
||||
See the method llvm::DataLayout::isLittleEndian. *)
|
||||
external byte_order : DataLayout.t -> Endian.t = "llvm_byte_order"
|
||||
(** {6 Target} *)
|
||||
|
||||
(** Returns the pointer size in bytes for a target.
|
||||
See the method llvm::DataLayout::getPointerSize. *)
|
||||
external pointer_size : DataLayout.t -> int = "llvm_pointer_size"
|
||||
module Target : sig
|
||||
type t
|
||||
|
||||
(** Returns the integer type that is the same size as a pointer on a target.
|
||||
See the method llvm::DataLayout::getIntPtrType. *)
|
||||
external intptr_type : DataLayout.t -> Llvm.lltype = "LLVMIntPtrType"
|
||||
(** [default_triple ()] returns the default target triple for current
|
||||
platform. *)
|
||||
val default_triple : unit -> string
|
||||
|
||||
(** Computes the size of a type in bytes for a target.
|
||||
See the method llvm::DataLayout::getTypeSizeInBits. *)
|
||||
external size_in_bits : DataLayout.t -> Llvm.lltype -> Int64.t
|
||||
= "llvm_size_in_bits"
|
||||
(** [first ()] returns the first target in the registered targets
|
||||
list, or [None]. *)
|
||||
val first : unit -> t option
|
||||
|
||||
(** Computes the storage size of a type in bytes for a target.
|
||||
See the method llvm::DataLayout::getTypeStoreSize. *)
|
||||
external store_size : DataLayout.t -> Llvm.lltype -> Int64.t = "llvm_store_size"
|
||||
(** [succ t] returns the next target after [t], or [None]
|
||||
if [t] was the last target. *)
|
||||
val succ : t -> t option
|
||||
|
||||
(** Computes the ABI size of a type in bytes for a target.
|
||||
See the method llvm::DataLayout::getTypeAllocSize. *)
|
||||
external abi_size : DataLayout.t -> Llvm.lltype -> Int64.t = "llvm_abi_size"
|
||||
(** [all ()] returns a list of known targets. *)
|
||||
val all : unit -> t list
|
||||
|
||||
(** Computes the ABI alignment of a type in bytes for a target.
|
||||
See the method llvm::DataLayout::getTypeABISize. *)
|
||||
external abi_align : DataLayout.t -> Llvm.lltype -> int = "llvm_abi_align"
|
||||
(** [by_name name] returns [Some t] if a target [t] named [name] is
|
||||
registered, or [None] otherwise. *)
|
||||
val by_name : string -> t option
|
||||
|
||||
(** Computes the call frame alignment of a type in bytes for a target.
|
||||
See the method llvm::DataLayout::getTypeABISize. *)
|
||||
external stack_align : DataLayout.t -> Llvm.lltype -> int = "llvm_stack_align"
|
||||
(** [by_triple triple] returns a target for a triple [triple], or raises
|
||||
[Error] if [triple] does not correspond to a registered target. *)
|
||||
val by_triple : string -> t
|
||||
|
||||
(** Computes the preferred alignment of a type in bytes for a target.
|
||||
See the method llvm::DataLayout::getTypeABISize. *)
|
||||
external preferred_align : DataLayout.t -> Llvm.lltype -> int
|
||||
= "llvm_preferred_align"
|
||||
(** Returns the name of a target. See [llvm::Target::getName]. *)
|
||||
val name : t -> string
|
||||
|
||||
(** Computes the preferred alignment of a global variable in bytes for a target.
|
||||
See the method llvm::DataLayout::getPreferredAlignment. *)
|
||||
external preferred_align_of_global : DataLayout.t -> Llvm.llvalue -> int
|
||||
= "llvm_preferred_align_of_global"
|
||||
(** Returns the description of a target.
|
||||
See [llvm::Target::getDescription]. *)
|
||||
val description : t -> string
|
||||
|
||||
(** Computes the structure element that contains the byte offset for a target.
|
||||
See the method llvm::StructLayout::getElementContainingOffset. *)
|
||||
external element_at_offset : DataLayout.t -> Llvm.lltype -> Int64.t -> int
|
||||
= "llvm_element_at_offset"
|
||||
(** Returns [true] if the target has a JIT. *)
|
||||
val has_jit : t -> bool
|
||||
|
||||
(** Computes the byte offset of the indexed struct element for a target.
|
||||
See the method llvm::StructLayout::getElementContainingOffset. *)
|
||||
external offset_of_element : DataLayout.t -> Llvm.lltype -> int -> Int64.t
|
||||
= "llvm_offset_of_element"
|
||||
(** Returns [true] if the target has a target machine associated. *)
|
||||
val has_target_machine : t -> bool
|
||||
|
||||
(** Returns [true] if the target has an ASM backend (required for
|
||||
emitting output). *)
|
||||
val has_asm_backend : t -> bool
|
||||
end
|
||||
|
||||
(** {6 Target Machine} *)
|
||||
|
||||
module TargetMachine : sig
|
||||
type t
|
||||
|
||||
(** Creates a new target machine.
|
||||
See [llvm::Target::createTargetMachine]. *)
|
||||
val create : triple:string -> ?cpu:string -> ?features:string ->
|
||||
?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t ->
|
||||
?code_model:CodeModel.t -> Target.t -> t
|
||||
|
||||
(** Returns the Target used in a TargetMachine *)
|
||||
val target : t -> Target.t
|
||||
|
||||
(** Returns the triple used while creating this target machine. See
|
||||
[llvm::TargetMachine::getTriple]. *)
|
||||
val triple : t -> string
|
||||
|
||||
(** Returns the CPU used while creating this target machine. See
|
||||
[llvm::TargetMachine::getCPU]. *)
|
||||
val cpu : t -> string
|
||||
|
||||
(** Returns the feature string used while creating this target machine. See
|
||||
[llvm::TargetMachine::getFeatureString]. *)
|
||||
val features : t -> string
|
||||
|
||||
(** Returns the data layout of this target machine. *)
|
||||
val data_layout : t -> DataLayout.t
|
||||
|
||||
(** Sets the assembly verbosity of this target machine.
|
||||
See [llvm::TargetMachine::setAsmVerbosity]. *)
|
||||
val set_verbose_asm : bool -> t -> unit
|
||||
|
||||
(** Emits assembly or object data for the given module to the given
|
||||
file or raise [Error]. *)
|
||||
val emit_to_file : Llvm.llmodule -> CodeGenFileType.t -> string -> t -> unit
|
||||
|
||||
(** Emits assembly or object data for the given module to a fresh memory
|
||||
buffer or raise [Error]. *)
|
||||
val emit_to_memory_buffer : Llvm.llmodule -> CodeGenFileType.t -> t ->
|
||||
Llvm.llmemorybuffer
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*===-- target_ocaml.c - LLVM Ocaml Glue ------------------------*- C++ -*-===*\
|
||||
/*===-- target_ocaml.c - LLVM OCaml Glue ------------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
@ -7,7 +7,7 @@
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
@ -16,87 +16,375 @@
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c/Target.h"
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
#include "caml/alloc.h"
|
||||
#include "caml/fail.h"
|
||||
#include "caml/memory.h"
|
||||
#include "caml/custom.h"
|
||||
|
||||
/* string -> DataLayout.t */
|
||||
CAMLprim LLVMTargetDataRef llvm_targetdata_create(value StringRep) {
|
||||
return LLVMCreateTargetData(String_val(StringRep));
|
||||
}
|
||||
/*===---- Exceptions ------------------------------------------------------===*/
|
||||
|
||||
/* DataLayout.t -> [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||
CAMLprim value llvm_targetdata_add(LLVMTargetDataRef TD, LLVMPassManagerRef PM){
|
||||
LLVMAddTargetData(TD, PM);
|
||||
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;
|
||||
}
|
||||
|
||||
/*===---- Data Layout -----------------------------------------------------===*/
|
||||
|
||||
#define DataLayout_val(v) (*(LLVMTargetDataRef *)(Data_custom_val(v)))
|
||||
|
||||
static void llvm_finalize_data_layout(value DataLayout) {
|
||||
LLVMDisposeTargetData(DataLayout_val(DataLayout));
|
||||
}
|
||||
|
||||
static struct custom_operations llvm_data_layout_ops = {
|
||||
(char *) "LLVMDataLayout",
|
||||
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
|
||||
};
|
||||
|
||||
value llvm_alloc_data_layout(LLVMTargetDataRef DataLayout) {
|
||||
value V = alloc_custom(&llvm_data_layout_ops, sizeof(LLVMTargetDataRef),
|
||||
0, 1);
|
||||
DataLayout_val(V) = DataLayout;
|
||||
return V;
|
||||
}
|
||||
|
||||
/* string -> DataLayout.t */
|
||||
CAMLprim value llvm_datalayout_of_string(value StringRep) {
|
||||
return llvm_alloc_data_layout(LLVMCreateTargetData(String_val(StringRep)));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> string */
|
||||
CAMLprim value llvm_targetdata_as_string(LLVMTargetDataRef TD) {
|
||||
char *StringRep = LLVMCopyStringRepOfTargetData(TD);
|
||||
CAMLprim value llvm_datalayout_as_string(value TD) {
|
||||
char *StringRep = LLVMCopyStringRepOfTargetData(DataLayout_val(TD));
|
||||
value Copy = copy_string(StringRep);
|
||||
LLVMDisposeMessage(StringRep);
|
||||
return Copy;
|
||||
}
|
||||
|
||||
/* DataLayout.t -> unit */
|
||||
CAMLprim value llvm_targetdata_dispose(LLVMTargetDataRef TD) {
|
||||
LLVMDisposeTargetData(TD);
|
||||
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> DataLayout.t -> unit */
|
||||
CAMLprim value llvm_datalayout_add_to_pass_manager(LLVMPassManagerRef PM,
|
||||
value DL) {
|
||||
LLVMAddTargetData(DataLayout_val(DL), PM);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Endian.t */
|
||||
CAMLprim value llvm_byte_order(LLVMTargetDataRef TD) {
|
||||
return Val_int(LLVMByteOrder(TD));
|
||||
CAMLprim value llvm_datalayout_byte_order(value DL) {
|
||||
return Val_int(LLVMByteOrder(DataLayout_val(DL)));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> int */
|
||||
CAMLprim value llvm_pointer_size(LLVMTargetDataRef TD) {
|
||||
return Val_int(LLVMPointerSize(TD));
|
||||
CAMLprim value llvm_datalayout_pointer_size(value DL) {
|
||||
return Val_int(LLVMPointerSize(DataLayout_val(DL)));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.lltype -> Int64.t */
|
||||
CAMLprim value llvm_size_in_bits(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
|
||||
return caml_copy_int64(LLVMSizeOfTypeInBits(TD, Ty));
|
||||
/* Llvm.llcontext -> DataLayout.t -> Llvm.lltype */
|
||||
CAMLprim LLVMTypeRef llvm_datalayout_intptr_type(LLVMContextRef C, value DL) {
|
||||
return LLVMIntPtrTypeInContext(C, DataLayout_val(DL));;
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.lltype -> Int64.t */
|
||||
CAMLprim value llvm_store_size(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
|
||||
return caml_copy_int64(LLVMStoreSizeOfType(TD, Ty));
|
||||
/* int -> DataLayout.t -> int */
|
||||
CAMLprim value llvm_datalayout_qualified_pointer_size(value AS, value DL) {
|
||||
return Val_int(LLVMPointerSizeForAS(DataLayout_val(DL), Int_val(AS)));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.lltype -> Int64.t */
|
||||
CAMLprim value llvm_abi_size(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
|
||||
return caml_copy_int64(LLVMABISizeOfType(TD, Ty));
|
||||
/* Llvm.llcontext -> int -> DataLayout.t -> Llvm.lltype */
|
||||
CAMLprim LLVMTypeRef llvm_datalayout_qualified_intptr_type(LLVMContextRef C,
|
||||
value AS,
|
||||
value DL) {
|
||||
return LLVMIntPtrTypeForASInContext(C, DataLayout_val(DL), Int_val(AS));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.lltype -> int */
|
||||
CAMLprim value llvm_abi_align(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
|
||||
return Val_int(LLVMABIAlignmentOfType(TD, Ty));
|
||||
/* Llvm.lltype -> DataLayout.t -> Int64.t */
|
||||
CAMLprim value llvm_datalayout_size_in_bits(LLVMTypeRef Ty, value DL) {
|
||||
return caml_copy_int64(LLVMSizeOfTypeInBits(DataLayout_val(DL), Ty));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.lltype -> int */
|
||||
CAMLprim value llvm_stack_align(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
|
||||
return Val_int(LLVMCallFrameAlignmentOfType(TD, Ty));
|
||||
/* Llvm.lltype -> DataLayout.t -> Int64.t */
|
||||
CAMLprim value llvm_datalayout_store_size(LLVMTypeRef Ty, value DL) {
|
||||
return caml_copy_int64(LLVMStoreSizeOfType(DataLayout_val(DL), Ty));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.lltype -> int */
|
||||
CAMLprim value llvm_preferred_align(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
|
||||
return Val_int(LLVMPreferredAlignmentOfType(TD, Ty));
|
||||
/* Llvm.lltype -> DataLayout.t -> Int64.t */
|
||||
CAMLprim value llvm_datalayout_abi_size(LLVMTypeRef Ty, value DL) {
|
||||
return caml_copy_int64(LLVMABISizeOfType(DataLayout_val(DL), Ty));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.llvalue -> int */
|
||||
CAMLprim value llvm_preferred_align_of_global(LLVMTargetDataRef TD,
|
||||
LLVMValueRef GlobalVar) {
|
||||
return Val_int(LLVMPreferredAlignmentOfGlobal(TD, GlobalVar));
|
||||
/* Llvm.lltype -> DataLayout.t -> int */
|
||||
CAMLprim value llvm_datalayout_abi_align(LLVMTypeRef Ty, value DL) {
|
||||
return Val_int(LLVMABIAlignmentOfType(DataLayout_val(DL), Ty));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.lltype -> Int64.t -> int */
|
||||
CAMLprim value llvm_element_at_offset(LLVMTargetDataRef TD, LLVMTypeRef Ty,
|
||||
value Offset) {
|
||||
return Val_int(LLVMElementAtOffset(TD, Ty, Int_val(Offset)));
|
||||
/* Llvm.lltype -> DataLayout.t -> int */
|
||||
CAMLprim value llvm_datalayout_stack_align(LLVMTypeRef Ty, value DL) {
|
||||
return Val_int(LLVMCallFrameAlignmentOfType(DataLayout_val(DL), Ty));
|
||||
}
|
||||
|
||||
/* DataLayout.t -> Llvm.lltype -> int -> Int64.t */
|
||||
CAMLprim value llvm_offset_of_element(LLVMTargetDataRef TD, LLVMTypeRef Ty,
|
||||
value Index) {
|
||||
return caml_copy_int64(LLVMOffsetOfElement(TD, Ty, Int_val(Index)));
|
||||
/* Llvm.lltype -> DataLayout.t -> int */
|
||||
CAMLprim value llvm_datalayout_preferred_align(LLVMTypeRef Ty, value DL) {
|
||||
return Val_int(LLVMPreferredAlignmentOfType(DataLayout_val(DL), Ty));
|
||||
}
|
||||
|
||||
/* Llvm.llvalue -> DataLayout.t -> int */
|
||||
CAMLprim value llvm_datalayout_preferred_align_of_global(LLVMValueRef GlobalVar,
|
||||
value DL) {
|
||||
return Val_int(LLVMPreferredAlignmentOfGlobal(DataLayout_val(DL), GlobalVar));
|
||||
}
|
||||
|
||||
/* Llvm.lltype -> Int64.t -> DataLayout.t -> int */
|
||||
CAMLprim value llvm_datalayout_element_at_offset(LLVMTypeRef Ty, value Offset,
|
||||
value DL) {
|
||||
return Val_int(LLVMElementAtOffset(DataLayout_val(DL), Ty,
|
||||
Int64_val(Offset)));
|
||||
}
|
||||
|
||||
/* Llvm.lltype -> int -> DataLayout.t -> Int64.t */
|
||||
CAMLprim value llvm_datalayout_offset_of_element(LLVMTypeRef Ty, value Index,
|
||||
value DL) {
|
||||
return caml_copy_int64(LLVMOffsetOfElement(DataLayout_val(DL), Ty,
|
||||
Int_val(Index)));
|
||||
}
|
||||
|
||||
/*===---- Target ----------------------------------------------------------===*/
|
||||
|
||||
static value llvm_target_option(LLVMTargetRef Target) {
|
||||
if(Target != NULL) {
|
||||
value Result = caml_alloc_small(1, 0);
|
||||
Store_field(Result, 0, (value) Target);
|
||||
return Result;
|
||||
}
|
||||
|
||||
return Val_int(0);
|
||||
}
|
||||
|
||||
/* unit -> string */
|
||||
CAMLprim value llvm_target_default_triple(value Unit) {
|
||||
char *TripleCStr = LLVMGetDefaultTargetTriple();
|
||||
value TripleStr = caml_copy_string(TripleCStr);
|
||||
LLVMDisposeMessage(TripleCStr);
|
||||
|
||||
return TripleStr;
|
||||
}
|
||||
|
||||
/* unit -> Target.t option */
|
||||
CAMLprim value llvm_target_first(value Unit) {
|
||||
return llvm_target_option(LLVMGetFirstTarget());
|
||||
}
|
||||
|
||||
/* Target.t -> Target.t option */
|
||||
CAMLprim value llvm_target_succ(LLVMTargetRef Target) {
|
||||
return llvm_target_option(LLVMGetNextTarget(Target));
|
||||
}
|
||||
|
||||
/* string -> Target.t option */
|
||||
CAMLprim value llvm_target_by_name(value Name) {
|
||||
return llvm_target_option(LLVMGetTargetFromName(String_val(Name)));
|
||||
}
|
||||
|
||||
/* string -> Target.t */
|
||||
CAMLprim LLVMTargetRef llvm_target_by_triple(value Triple) {
|
||||
LLVMTargetRef T;
|
||||
char *Error;
|
||||
|
||||
if(LLVMGetTargetFromTriple(String_val(Triple), &T, &Error))
|
||||
llvm_raise(llvm_target_error_exn, Error);
|
||||
|
||||
return T;
|
||||
}
|
||||
|
||||
/* Target.t -> string */
|
||||
CAMLprim value llvm_target_name(LLVMTargetRef Target) {
|
||||
return caml_copy_string(LLVMGetTargetName(Target));
|
||||
}
|
||||
|
||||
/* Target.t -> string */
|
||||
CAMLprim value llvm_target_description(LLVMTargetRef Target) {
|
||||
return caml_copy_string(LLVMGetTargetDescription(Target));
|
||||
}
|
||||
|
||||
/* Target.t -> bool */
|
||||
CAMLprim value llvm_target_has_jit(LLVMTargetRef Target) {
|
||||
return Val_bool(LLVMTargetHasJIT(Target));
|
||||
}
|
||||
|
||||
/* Target.t -> bool */
|
||||
CAMLprim value llvm_target_has_target_machine(LLVMTargetRef Target) {
|
||||
return Val_bool(LLVMTargetHasTargetMachine(Target));
|
||||
}
|
||||
|
||||
/* Target.t -> bool */
|
||||
CAMLprim value llvm_target_has_asm_backend(LLVMTargetRef Target) {
|
||||
return Val_bool(LLVMTargetHasAsmBackend(Target));
|
||||
}
|
||||
|
||||
/*===---- Target Machine --------------------------------------------------===*/
|
||||
|
||||
#define TargetMachine_val(v) (*(LLVMTargetMachineRef *)(Data_custom_val(v)))
|
||||
|
||||
static void llvm_finalize_target_machine(value Machine) {
|
||||
LLVMDisposeTargetMachine(TargetMachine_val(Machine));
|
||||
}
|
||||
|
||||
static struct custom_operations llvm_target_machine_ops = {
|
||||
(char *) "LLVMTargetMachine",
|
||||
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
|
||||
};
|
||||
|
||||
static value llvm_alloc_targetmachine(LLVMTargetMachineRef Machine) {
|
||||
value V = alloc_custom(&llvm_target_machine_ops, sizeof(LLVMTargetMachineRef),
|
||||
0, 1);
|
||||
TargetMachine_val(V) = Machine;
|
||||
return V;
|
||||
}
|
||||
|
||||
/* triple:string -> ?cpu:string -> ?features:string
|
||||
?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t
|
||||
?code_model:CodeModel.t -> Target.t -> TargetMachine.t */
|
||||
CAMLprim value llvm_create_targetmachine_native(value Triple, value CPU,
|
||||
value Features, value OptLevel, value RelocMode,
|
||||
value CodeModel, LLVMTargetRef Target) {
|
||||
LLVMTargetMachineRef Machine;
|
||||
const char *CPUStr = "", *FeaturesStr = "";
|
||||
LLVMCodeGenOptLevel OptLevelEnum = LLVMCodeGenLevelDefault;
|
||||
LLVMRelocMode RelocModeEnum = LLVMRelocDefault;
|
||||
LLVMCodeModel CodeModelEnum = LLVMCodeModelDefault;
|
||||
|
||||
if(CPU != Val_int(0))
|
||||
CPUStr = String_val(Field(CPU, 0));
|
||||
if(Features != Val_int(0))
|
||||
FeaturesStr = String_val(Field(Features, 0));
|
||||
if(OptLevel != Val_int(0))
|
||||
OptLevelEnum = Int_val(Field(OptLevel, 0));
|
||||
if(RelocMode != Val_int(0))
|
||||
RelocModeEnum = Int_val(Field(RelocMode, 0));
|
||||
if(CodeModel != Val_int(0))
|
||||
CodeModelEnum = Int_val(Field(CodeModel, 0));
|
||||
|
||||
Machine = LLVMCreateTargetMachine(Target, String_val(Triple), CPUStr,
|
||||
FeaturesStr, OptLevelEnum, RelocModeEnum, CodeModelEnum);
|
||||
|
||||
return llvm_alloc_targetmachine(Machine);
|
||||
}
|
||||
|
||||
CAMLprim value llvm_create_targetmachine_bytecode(value *argv, int argn) {
|
||||
return llvm_create_targetmachine_native(argv[0], argv[1], argv[2], argv[3],
|
||||
argv[4], argv[5], (LLVMTargetRef) argv[6]);
|
||||
}
|
||||
|
||||
/* TargetMachine.t -> Target.t */
|
||||
CAMLprim LLVMTargetRef llvm_targetmachine_target(value Machine) {
|
||||
return LLVMGetTargetMachineTarget(TargetMachine_val(Machine));
|
||||
}
|
||||
|
||||
/* TargetMachine.t -> string */
|
||||
CAMLprim value llvm_targetmachine_triple(value Machine) {
|
||||
return llvm_string_of_message(LLVMGetTargetMachineTriple(
|
||||
TargetMachine_val(Machine)));
|
||||
}
|
||||
|
||||
/* TargetMachine.t -> string */
|
||||
CAMLprim value llvm_targetmachine_cpu(value Machine) {
|
||||
return llvm_string_of_message(LLVMGetTargetMachineCPU(
|
||||
TargetMachine_val(Machine)));
|
||||
}
|
||||
|
||||
/* TargetMachine.t -> string */
|
||||
CAMLprim value llvm_targetmachine_features(value Machine) {
|
||||
return llvm_string_of_message(LLVMGetTargetMachineFeatureString(
|
||||
TargetMachine_val(Machine)));
|
||||
}
|
||||
|
||||
/* TargetMachine.t -> DataLayout.t */
|
||||
CAMLprim value llvm_targetmachine_data_layout(value Machine) {
|
||||
CAMLparam1(Machine);
|
||||
CAMLlocal1(DataLayout);
|
||||
|
||||
/* LLVMGetTargetMachineData returns a pointer owned by the TargetMachine,
|
||||
so it is impossible to wrap it with llvm_alloc_target_data, which assumes
|
||||
that OCaml owns the pointer. */
|
||||
LLVMTargetDataRef OrigDataLayout;
|
||||
OrigDataLayout = LLVMGetTargetMachineData(TargetMachine_val(Machine));
|
||||
|
||||
char* TargetDataCStr;
|
||||
TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
|
||||
DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
|
||||
LLVMDisposeMessage(TargetDataCStr);
|
||||
|
||||
CAMLreturn(DataLayout);
|
||||
}
|
||||
|
||||
/* TargetMachine.t -> bool -> unit */
|
||||
CAMLprim value llvm_targetmachine_set_verbose_asm(value Machine, value Verb) {
|
||||
LLVMSetTargetMachineAsmVerbosity(TargetMachine_val(Machine), Bool_val(Verb));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
if(LLVMTargetMachineEmitToFile(TargetMachine_val(Machine), Module,
|
||||
String_val(FileName), Int_val(FileType),
|
||||
&ErrorMessage)) {
|
||||
llvm_raise(llvm_target_error_exn, ErrorMessage);
|
||||
}
|
||||
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* Llvm.llmodule -> CodeGenFileType.t -> TargetMachine.t ->
|
||||
Llvm.llmemorybuffer */
|
||||
CAMLprim LLVMMemoryBufferRef llvm_targetmachine_emit_to_memory_buffer(
|
||||
LLVMModuleRef Module, value FileType,
|
||||
value Machine) {
|
||||
char* ErrorMessage;
|
||||
LLVMMemoryBufferRef Buffer;
|
||||
|
||||
if(LLVMTargetMachineEmitToMemoryBuffer(TargetMachine_val(Machine), Module,
|
||||
Int_val(FileType), &ErrorMessage,
|
||||
&Buffer)) {
|
||||
llvm_raise(llvm_target_error_exn, ErrorMessage);
|
||||
}
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../../..
|
||||
DIRS = scalar ipo
|
||||
DIRS = scalar ipo vectorize passmgr_builder
|
||||
|
||||
ocamldoc:
|
||||
$(Verb) for i in $(DIRS) ; do \
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
LEVEL := ../../../..
|
||||
LIBRARYNAME := llvm_ipo
|
||||
DONT_BUILD_RELINKED := 1
|
||||
UsedComponents := ipo
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*===-- ipo_ocaml.c - LLVM Ocaml Glue -------------------*- C++ -*-===*\
|
||||
/*===-- ipo_ocaml.c - LLVM OCaml Glue ---------------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
@ -7,7 +7,7 @@
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
@ -49,6 +49,12 @@ CAMLprim value llvm_add_function_inlining(LLVMPassManagerRef PM) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* [`Module] Llvm.PassManager.t -> unit */
|
||||
CAMLprim value llvm_add_always_inliner(LLVMPassManagerRef PM) {
|
||||
LLVMAddAlwaysInlinerPass(PM);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* [`Module] Llvm.PassManager.t -> unit */
|
||||
CAMLprim value llvm_add_always_inliner_pass(LLVMPassManagerRef PM) {
|
||||
LLVMAddAlwaysInlinerPass(PM);
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_ipo.mli - LLVM Ocaml Interface ------------*- OCaml -*-===*
|
||||
(*===-- llvm_ipo.ml - LLVM OCaml Interface --------------------*- OCaml -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -7,59 +7,31 @@
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
(** IPO Transforms.
|
||||
|
||||
This interface provides an ocaml API for LLVM interprocedural optimizations, the
|
||||
classes in the [LLVMIPO] library. *)
|
||||
|
||||
(** See llvm::createAddArgumentPromotionPass *)
|
||||
external add_argument_promotion : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_argument_promotion"
|
||||
|
||||
(** See llvm::createConstantMergePass function. *)
|
||||
external add_constant_merge : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_constant_merge"
|
||||
|
||||
(** See llvm::createDeadArgEliminationPass function. *)
|
||||
external add_dead_arg_elimination :
|
||||
[ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_dead_arg_elimination"
|
||||
|
||||
(** See llvm::createFunctionAttrsPass function. *)
|
||||
external add_function_attrs : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_function_attrs"
|
||||
|
||||
(** See llvm::createFunctionInliningPass function. *)
|
||||
external add_function_inlining : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_function_inlining"
|
||||
|
||||
(** See llvm::createGlobalDCEPass function. *)
|
||||
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"
|
||||
|
||||
(** See llvm::createGlobalOptimizerPass function. *)
|
||||
external add_global_optimizer : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_global_optimizer"
|
||||
|
||||
(** See llvm::createIPConstantPropagationPass function. *)
|
||||
external add_ipc_propagation : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_ipc_propagation"
|
||||
|
||||
(** See llvm::createPruneEHPass function. *)
|
||||
external add_prune_eh : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_prune_eh"
|
||||
|
||||
(** See llvm::createIPSCCPPass function. *)
|
||||
external add_ipsccp : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_ipsccp"
|
||||
|
||||
(** See llvm::createInternalizePass function. *)
|
||||
external add_internalize : [ | `Module ] Llvm.PassManager.t -> bool -> unit =
|
||||
"llvm_add_internalize"
|
||||
|
||||
(** See llvm::createStripDeadPrototypesPass function. *)
|
||||
external add_strip_dead_prototypes :
|
||||
[ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_strip_dead_prototypes"
|
||||
|
||||
(** See llvm::createStripSymbolsPass function. *)
|
||||
external add_strip_symbols : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_strip_symbols"
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_ipo.mli - LLVM Ocaml Interface ------------*- OCaml -*-===*
|
||||
(*===-- llvm_ipo.mli - LLVM OCaml Interface -------------------*- OCaml -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -9,13 +9,13 @@
|
||||
|
||||
(** IPO Transforms.
|
||||
|
||||
This interface provides an ocaml API for LLVM interprocedural optimizations, the
|
||||
This interface provides an OCaml API for LLVM interprocedural optimizations, the
|
||||
classes in the [LLVMIPO] library. *)
|
||||
|
||||
(** See llvm::createAddArgumentPromotionPass *)
|
||||
external add_argument_promotion : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
|
||||
"llvm_add_argument_promotion"
|
||||
|
||||
(** See llvm::createConstantMergePass function. *)
|
||||
external add_constant_merge : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_constant_merge"
|
||||
@ -32,6 +32,10 @@ external add_function_attrs : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
external add_function_inlining : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_function_inlining"
|
||||
|
||||
(** See llvm::createAlwaysInlinerPass function. *)
|
||||
external add_always_inliner : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_always_inliner"
|
||||
|
||||
(** See llvm::createGlobalDCEPass function. *)
|
||||
external add_global_dce : [ | `Module ] Llvm.PassManager.t -> unit =
|
||||
"llvm_add_global_dce"
|
||||
|
19
bindings/ocaml/transforms/passmgr_builder/Makefile
Normal file
19
bindings/ocaml/transforms/passmgr_builder/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
##===- bindings/ocaml/transforms/passmgr_builder/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_passmgr_builder interface.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../../../..
|
||||
LIBRARYNAME := llvm_passmgr_builder
|
||||
UsedComponents := ipo
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
include ../../Makefile.ocaml
|
@ -0,0 +1,32 @@
|
||||
(*===-- llvm_passmgr_builder.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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
type t
|
||||
|
||||
external create : unit -> t
|
||||
= "llvm_pmbuilder_create"
|
||||
external set_opt_level : int -> t -> unit
|
||||
= "llvm_pmbuilder_set_opt_level"
|
||||
external set_size_level : int -> t -> unit
|
||||
= "llvm_pmbuilder_set_size_level"
|
||||
external set_disable_unit_at_a_time : bool -> t -> unit
|
||||
= "llvm_pmbuilder_set_disable_unit_at_a_time"
|
||||
external set_disable_unroll_loops : bool -> t -> unit
|
||||
= "llvm_pmbuilder_set_disable_unroll_loops"
|
||||
external use_inliner_with_threshold : int -> t -> unit
|
||||
= "llvm_pmbuilder_use_inliner_with_threshold"
|
||||
external populate_function_pass_manager
|
||||
: [ `Function ] Llvm.PassManager.t -> t -> unit
|
||||
= "llvm_pmbuilder_populate_function_pass_manager"
|
||||
external populate_module_pass_manager
|
||||
: [ `Module ] Llvm.PassManager.t -> t -> unit
|
||||
= "llvm_pmbuilder_populate_module_pass_manager"
|
||||
external populate_lto_pass_manager
|
||||
: [ `Module ] Llvm.PassManager.t -> internalize:bool -> run_inliner:bool -> t -> unit
|
||||
= "llvm_pmbuilder_populate_lto_pass_manager"
|
@ -0,0 +1,54 @@
|
||||
(*===-- llvm_passmgr_builder.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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
(** Pass Manager Builder.
|
||||
|
||||
This interface provides an OCaml API for LLVM pass manager builder
|
||||
from the [LLVMCore] library. *)
|
||||
|
||||
type t
|
||||
|
||||
(** See [llvm::PassManagerBuilder]. *)
|
||||
external create : unit -> t
|
||||
= "llvm_pmbuilder_create"
|
||||
|
||||
(** See [llvm::PassManagerBuilder::OptLevel]. *)
|
||||
external set_opt_level : int -> t -> unit
|
||||
= "llvm_pmbuilder_set_opt_level"
|
||||
|
||||
(** See [llvm::PassManagerBuilder::SizeLevel]. *)
|
||||
external set_size_level : int -> t -> unit
|
||||
= "llvm_pmbuilder_set_size_level"
|
||||
|
||||
(** See [llvm::PassManagerBuilder::DisableUnitAtATime]. *)
|
||||
external set_disable_unit_at_a_time : bool -> t -> unit
|
||||
= "llvm_pmbuilder_set_disable_unit_at_a_time"
|
||||
|
||||
(** See [llvm::PassManagerBuilder::DisableUnrollLoops]. *)
|
||||
external set_disable_unroll_loops : bool -> t -> unit
|
||||
= "llvm_pmbuilder_set_disable_unroll_loops"
|
||||
|
||||
(** See [llvm::PassManagerBuilder::Inliner]. *)
|
||||
external use_inliner_with_threshold : int -> t -> unit
|
||||
= "llvm_pmbuilder_use_inliner_with_threshold"
|
||||
|
||||
(** See [llvm::PassManagerBuilder::populateFunctionPassManager]. *)
|
||||
external populate_function_pass_manager
|
||||
: [ `Function ] Llvm.PassManager.t -> t -> unit
|
||||
= "llvm_pmbuilder_populate_function_pass_manager"
|
||||
|
||||
(** See [llvm::PassManagerBuilder::populateModulePassManager]. *)
|
||||
external populate_module_pass_manager
|
||||
: [ `Module ] Llvm.PassManager.t -> t -> unit
|
||||
= "llvm_pmbuilder_populate_module_pass_manager"
|
||||
|
||||
(** See [llvm::PassManagerBuilder::populateLTOPassManager]. *)
|
||||
external populate_lto_pass_manager
|
||||
: [ `Module ] Llvm.PassManager.t -> internalize:bool -> run_inliner:bool -> t -> unit
|
||||
= "llvm_pmbuilder_populate_lto_pass_manager"
|
@ -0,0 +1,113 @@
|
||||
/*===-- passmgr_builder_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
|* macros, since most of the parameters are not GC heap objects. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c/Transforms/PassManagerBuilder.h"
|
||||
#include "caml/mlvalues.h"
|
||||
#include "caml/custom.h"
|
||||
#include "caml/misc.h"
|
||||
|
||||
#define PMBuilder_val(v) (*(LLVMPassManagerBuilderRef *)(Data_custom_val(v)))
|
||||
|
||||
static void llvm_finalize_pmbuilder(value PMB) {
|
||||
LLVMPassManagerBuilderDispose(PMBuilder_val(PMB));
|
||||
}
|
||||
|
||||
static struct custom_operations pmbuilder_ops = {
|
||||
(char *) "LLVMPassManagerBuilder",
|
||||
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
|
||||
};
|
||||
|
||||
static value alloc_pmbuilder(LLVMPassManagerBuilderRef Ref) {
|
||||
value Val = alloc_custom(&pmbuilder_ops,
|
||||
sizeof(LLVMPassManagerBuilderRef), 0, 1);
|
||||
PMBuilder_val(Val) = Ref;
|
||||
return Val;
|
||||
}
|
||||
|
||||
/* t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_create(value Unit) {
|
||||
return alloc_pmbuilder(LLVMPassManagerBuilderCreate());
|
||||
}
|
||||
|
||||
/* int -> t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_set_opt_level(value OptLevel, value PMB) {
|
||||
LLVMPassManagerBuilderSetOptLevel(PMBuilder_val(PMB), Int_val(OptLevel));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* int -> t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_set_size_level(value SizeLevel, value PMB) {
|
||||
LLVMPassManagerBuilderSetSizeLevel(PMBuilder_val(PMB), Int_val(SizeLevel));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* int -> t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_use_inliner_with_threshold(
|
||||
value Threshold, value PMB) {
|
||||
LLVMPassManagerBuilderSetOptLevel(PMBuilder_val(PMB), Int_val(Threshold));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* bool -> t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_set_disable_unit_at_a_time(
|
||||
value DisableUnitAtATime, value PMB) {
|
||||
LLVMPassManagerBuilderSetDisableUnitAtATime(
|
||||
PMBuilder_val(PMB), Bool_val(DisableUnitAtATime));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* bool -> t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_set_disable_unroll_loops(
|
||||
value DisableUnroll, value PMB) {
|
||||
LLVMPassManagerBuilderSetDisableUnrollLoops(
|
||||
PMBuilder_val(PMB), Bool_val(DisableUnroll));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* [ `Function ] Llvm.PassManager.t -> t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_populate_function_pass_manager(
|
||||
LLVMPassManagerRef PM, value PMB) {
|
||||
LLVMPassManagerBuilderPopulateFunctionPassManager(
|
||||
PMBuilder_val(PMB), PM);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* [ `Module ] Llvm.PassManager.t -> t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_populate_module_pass_manager(
|
||||
LLVMPassManagerRef PM, value PMB) {
|
||||
LLVMPassManagerBuilderPopulateModulePassManager(
|
||||
PMBuilder_val(PMB), PM);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* [ `Module ] Llvm.PassManager.t ->
|
||||
internalize:bool -> run_inliner:bool -> t -> unit */
|
||||
CAMLprim value llvm_pmbuilder_populate_lto_pass_manager(
|
||||
LLVMPassManagerRef PM, value Internalize, value RunInliner,
|
||||
value PMB) {
|
||||
LLVMPassManagerBuilderPopulateLTOPassManager(
|
||||
PMBuilder_val(PMB), PM,
|
||||
Bool_val(Internalize), Bool_val(RunInliner));
|
||||
return Val_unit;
|
||||
}
|
@ -13,7 +13,6 @@
|
||||
|
||||
LEVEL := ../../../..
|
||||
LIBRARYNAME := llvm_scalar_opts
|
||||
DONT_BUILD_RELINKED := 1
|
||||
UsedComponents := scalaropts
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
(*===-- llvm_scalar_opts.ml - LLVM Ocaml Interface -------------*- OCaml -*-===*
|
||||
(*===-- llvm_scalar_opts.ml - LLVM OCaml Interface -------------*- OCaml -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -109,3 +109,6 @@ 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,4 +1,4 @@
|
||||
(*===-- llvm_scalar_opts.mli - LLVM Ocaml Interface ------------*- OCaml -*-===*
|
||||
(*===-- llvm_scalar_opts.mli - LLVM OCaml Interface ------------*- OCaml -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
(** Scalar Transforms.
|
||||
|
||||
This interface provides an ocaml API for LLVM scalar transforms, the
|
||||
This interface provides an OCaml API for LLVM scalar transforms, the
|
||||
classes in the [LLVMScalarOpts] library. *)
|
||||
|
||||
(** See the [llvm::createConstantPropogationPass] function. *)
|
||||
@ -162,3 +162,7 @@ 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"
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*===-- scalar_opts_ocaml.c - LLVM Ocaml Glue -------------------*- C++ -*-===*\
|
||||
/*===-- scalar_opts_ocaml.c - LLVM OCaml Glue -------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
@ -7,7 +7,7 @@
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
@ -199,3 +199,9 @@ CAMLprim value llvm_add_basic_alias_analysis(LLVMPassManagerRef PM) {
|
||||
LLVMAddBasicAliasAnalysisPass(PM);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||
CAMLprim value llvm_add_partially_inline_lib_calls(LLVMPassManagerRef PM) {
|
||||
LLVMAddPartiallyInlineLibCallsPass(PM);
|
||||
return Val_unit;
|
||||
}
|
||||
|
19
bindings/ocaml/transforms/vectorize/Makefile
Normal file
19
bindings/ocaml/transforms/vectorize/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
##===- bindings/ocaml/transforms/vectorize/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_vectorize_opts interface.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../../../..
|
||||
LIBRARYNAME := llvm_vectorize
|
||||
UsedComponents := vectorize
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
include ../../Makefile.ocaml
|
15
bindings/ocaml/transforms/vectorize/llvm_vectorize.ml
Normal file
15
bindings/ocaml/transforms/vectorize/llvm_vectorize.ml
Normal file
@ -0,0 +1,15 @@
|
||||
(*===-- llvm_vectorize.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_bb_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||
= "llvm_add_bb_vectorize"
|
||||
external add_loop_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||
= "llvm_add_loop_vectorize"
|
||||
external add_slp_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||
= "llvm_add_slp_vectorize"
|
25
bindings/ocaml/transforms/vectorize/llvm_vectorize.mli
Normal file
25
bindings/ocaml/transforms/vectorize/llvm_vectorize.mli
Normal file
@ -0,0 +1,25 @@
|
||||
(*===-- llvm_vectorize.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.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*)
|
||||
|
||||
(** Vectorize Transforms.
|
||||
|
||||
This interface provides an OCaml API for LLVM vectorize transforms, the
|
||||
classes in the [LLVMVectorize] library. *)
|
||||
|
||||
(** See the [llvm::createBBVectorizePass] function. *)
|
||||
external add_bb_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||
= "llvm_add_bb_vectorize"
|
||||
|
||||
(** See the [llvm::createLoopVectorizePass] function. *)
|
||||
external add_loop_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||
= "llvm_add_loop_vectorize"
|
||||
|
||||
(** See [llvm::createSLPVectorizerPass] function. *)
|
||||
external add_slp_vectorize : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||
= "llvm_add_slp_vectorize"
|
38
bindings/ocaml/transforms/vectorize/vectorize_ocaml.c
Normal file
38
bindings/ocaml/transforms/vectorize/vectorize_ocaml.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*===-- vectorize_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||
|* *|
|
||||
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|
||||
|* macros, since most of the parameters are not GC heap objects. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c/Transforms/Vectorize.h"
|
||||
#include "caml/mlvalues.h"
|
||||
#include "caml/misc.h"
|
||||
|
||||
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||
CAMLprim value llvm_add_bb_vectorize(LLVMPassManagerRef PM) {
|
||||
LLVMAddBBVectorizePass(PM);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||
CAMLprim value llvm_add_loop_vectorize(LLVMPassManagerRef PM) {
|
||||
LLVMAddLoopVectorizePass(PM);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||
CAMLprim value llvm_add_slp_vectorize(LLVMPassManagerRef PM) {
|
||||
LLVMAddSLPVectorizePass(PM);
|
||||
return Val_unit;
|
||||
}
|
31
bindings/python/llvm/bit_reader.py
Normal file
31
bindings/python/llvm/bit_reader.py
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
from .common import LLVMObject
|
||||
from .common import c_object_p
|
||||
from .common import get_library
|
||||
from . import enumerations
|
||||
from .core import MemoryBuffer
|
||||
from .core import Module
|
||||
from .core import OpCode
|
||||
from ctypes import POINTER
|
||||
from ctypes import byref
|
||||
from ctypes import c_char_p
|
||||
from ctypes import cast
|
||||
__all__ = ['parse_bitcode']
|
||||
lib = get_library()
|
||||
|
||||
def parse_bitcode(mem_buffer):
|
||||
"""Input is .core.MemoryBuffer"""
|
||||
module = c_object_p()
|
||||
out = c_char_p(None)
|
||||
result = lib.LLVMParseBitcode(mem_buffer, byref(module), byref(out))
|
||||
if result:
|
||||
raise RuntimeError('LLVM Error: %s' % out.value)
|
||||
m = Module(module)
|
||||
m.take_ownership(mem_buffer)
|
||||
return m
|
||||
|
||||
def register_library(library):
|
||||
library.LLVMParseBitcode.argtypes = [MemoryBuffer, POINTER(c_object_p), POINTER(c_char_p)]
|
||||
library.LLVMParseBitcode.restype = bool
|
||||
|
||||
register_library(lib)
|
@ -16,7 +16,7 @@
|
||||
|
||||
# LLVM_VERSION: sync with PACKAGE_VERSION in autoconf/configure.ac and CMakeLists.txt
|
||||
# but leave out the 'svn' suffix.
|
||||
LLVM_VERSION = '3.3'
|
||||
LLVM_VERSION = '3.4'
|
||||
|
||||
__all__ = [
|
||||
'c_object_p',
|
||||
|
@ -16,10 +16,19 @@
|
||||
from ctypes import POINTER
|
||||
from ctypes import byref
|
||||
from ctypes import c_char_p
|
||||
from ctypes import c_uint
|
||||
|
||||
__all__ = [
|
||||
"lib",
|
||||
"OpCode",
|
||||
"MemoryBuffer",
|
||||
"Module",
|
||||
"Value",
|
||||
"Function",
|
||||
"BasicBlock",
|
||||
"Instruction",
|
||||
"Context",
|
||||
"PassRegistry"
|
||||
]
|
||||
|
||||
lib = get_library()
|
||||
@ -83,16 +92,449 @@ def __init__(self, filename=None):
|
||||
|
||||
LLVMObject.__init__(self, memory, disposer=lib.LLVMDisposeMemoryBuffer)
|
||||
|
||||
def __len__(self):
|
||||
return lib.LLVMGetBufferSize(self)
|
||||
|
||||
class Value(LLVMObject):
|
||||
|
||||
def __init__(self, value):
|
||||
LLVMObject.__init__(self, value)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return lib.LLVMGetValueName(self)
|
||||
|
||||
def dump(self):
|
||||
lib.LLVMDumpValue(self)
|
||||
|
||||
def get_operand(self, i):
|
||||
return Value(lib.LLVMGetOperand(self, i))
|
||||
|
||||
def set_operand(self, i, v):
|
||||
return lib.LLVMSetOperand(self, i, v)
|
||||
|
||||
def __len__(self):
|
||||
return lib.LLVMGetNumOperands(self)
|
||||
|
||||
class Module(LLVMObject):
|
||||
"""Represents the top-level structure of an llvm program in an opaque object."""
|
||||
|
||||
def __init__(self, module, name=None, context=None):
|
||||
LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule)
|
||||
|
||||
@classmethod
|
||||
def CreateWithName(cls, module_id):
|
||||
m = Module(lib.LLVMModuleCreateWithName(module_id))
|
||||
c = Context.GetGlobalContext().take_ownership(m)
|
||||
return m
|
||||
|
||||
@property
|
||||
def datalayout(self):
|
||||
return lib.LLVMGetDataLayout(self)
|
||||
|
||||
@datalayout.setter
|
||||
def datalayout(self, new_data_layout):
|
||||
"""new_data_layout is a string."""
|
||||
lib.LLVMSetDataLayout(self, new_data_layout)
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
return lib.LLVMGetTarget(self)
|
||||
|
||||
@target.setter
|
||||
def target(self, new_target):
|
||||
"""new_target is a string."""
|
||||
lib.LLVMSetTarget(self, new_target)
|
||||
|
||||
def dump(self):
|
||||
lib.LLVMDumpModule(self)
|
||||
|
||||
class __function_iterator(object):
|
||||
def __init__(self, module, reverse=False):
|
||||
self.module = module
|
||||
self.reverse = reverse
|
||||
if self.reverse:
|
||||
self.function = self.module.last
|
||||
else:
|
||||
self.function = self.module.first
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if not isinstance(self.function, Function):
|
||||
raise StopIteration("")
|
||||
result = self.function
|
||||
if self.reverse:
|
||||
self.function = self.function.prev
|
||||
else:
|
||||
self.function = self.function.next
|
||||
return result
|
||||
|
||||
def __iter__(self):
|
||||
return Module.__function_iterator(self)
|
||||
|
||||
def __reversed__(self):
|
||||
return Module.__function_iterator(self, reverse=True)
|
||||
|
||||
@property
|
||||
def first(self):
|
||||
return Function(lib.LLVMGetFirstFunction(self))
|
||||
|
||||
@property
|
||||
def last(self):
|
||||
return Function(lib.LLVMGetLastFunction(self))
|
||||
|
||||
def print_module_to_file(self, filename):
|
||||
out = c_char_p(None)
|
||||
# Result is inverted so 0 means everything was ok.
|
||||
result = lib.LLVMPrintModuleToFile(self, filename, byref(out))
|
||||
if result:
|
||||
raise RuntimeError("LLVM Error: %s" % out.value)
|
||||
|
||||
class Function(Value):
|
||||
|
||||
def __init__(self, value):
|
||||
Value.__init__(self, value)
|
||||
|
||||
@property
|
||||
def next(self):
|
||||
f = lib.LLVMGetNextFunction(self)
|
||||
return f and Function(f)
|
||||
|
||||
@property
|
||||
def prev(self):
|
||||
f = lib.LLVMGetPreviousFunction(self)
|
||||
return f and Function(f)
|
||||
|
||||
@property
|
||||
def first(self):
|
||||
b = lib.LLVMGetFirstBasicBlock(self)
|
||||
return b and BasicBlock(b)
|
||||
|
||||
@property
|
||||
def last(self):
|
||||
b = lib.LLVMGetLastBasicBlock(self)
|
||||
return b and BasicBlock(b)
|
||||
|
||||
class __bb_iterator(object):
|
||||
def __init__(self, function, reverse=False):
|
||||
self.function = function
|
||||
self.reverse = reverse
|
||||
if self.reverse:
|
||||
self.bb = function.last
|
||||
else:
|
||||
self.bb = function.first
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if not isinstance(self.bb, BasicBlock):
|
||||
raise StopIteration("")
|
||||
result = self.bb
|
||||
if self.reverse:
|
||||
self.bb = self.bb.prev
|
||||
else:
|
||||
self.bb = self.bb.next
|
||||
return result
|
||||
|
||||
def __iter__(self):
|
||||
return Function.__bb_iterator(self)
|
||||
|
||||
def __reversed__(self):
|
||||
return Function.__bb_iterator(self, reverse=True)
|
||||
|
||||
def __len__(self):
|
||||
return lib.LLVMCountBasicBlocks(self)
|
||||
|
||||
class BasicBlock(LLVMObject):
|
||||
|
||||
def __init__(self, value):
|
||||
LLVMObject.__init__(self, value)
|
||||
|
||||
@property
|
||||
def next(self):
|
||||
b = lib.LLVMGetNextBasicBlock(self)
|
||||
return b and BasicBlock(b)
|
||||
|
||||
@property
|
||||
def prev(self):
|
||||
b = lib.LLVMGetPreviousBasicBlock(self)
|
||||
return b and BasicBlock(b)
|
||||
|
||||
@property
|
||||
def first(self):
|
||||
i = lib.LLVMGetFirstInstruction(self)
|
||||
return i and Instruction(i)
|
||||
|
||||
@property
|
||||
def last(self):
|
||||
i = lib.LLVMGetLastInstruction(self)
|
||||
return i and Instruction(i)
|
||||
|
||||
def __as_value(self):
|
||||
return Value(lib.LLVMBasicBlockAsValue(self))
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return lib.LLVMGetValueName(self.__as_value())
|
||||
|
||||
def dump(self):
|
||||
lib.LLVMDumpValue(self.__as_value())
|
||||
|
||||
def get_operand(self, i):
|
||||
return Value(lib.LLVMGetOperand(self.__as_value(),
|
||||
i))
|
||||
|
||||
def set_operand(self, i, v):
|
||||
return lib.LLVMSetOperand(self.__as_value(),
|
||||
i, v)
|
||||
|
||||
def __len__(self):
|
||||
return lib.LLVMGetNumOperands(self.__as_value())
|
||||
|
||||
class __inst_iterator(object):
|
||||
def __init__(self, bb, reverse=False):
|
||||
self.bb = bb
|
||||
self.reverse = reverse
|
||||
if self.reverse:
|
||||
self.inst = self.bb.last
|
||||
else:
|
||||
self.inst = self.bb.first
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if not isinstance(self.inst, Instruction):
|
||||
raise StopIteration("")
|
||||
result = self.inst
|
||||
if self.reverse:
|
||||
self.inst = self.inst.prev
|
||||
else:
|
||||
self.inst = self.inst.next
|
||||
return result
|
||||
|
||||
def __iter__(self):
|
||||
return BasicBlock.__inst_iterator(self)
|
||||
|
||||
def __reversed__(self):
|
||||
return BasicBlock.__inst_iterator(self, reverse=True)
|
||||
|
||||
|
||||
class Instruction(Value):
|
||||
|
||||
def __init__(self, value):
|
||||
Value.__init__(self, value)
|
||||
|
||||
@property
|
||||
def next(self):
|
||||
i = lib.LLVMGetNextInstruction(self)
|
||||
return i and Instruction(i)
|
||||
|
||||
@property
|
||||
def prev(self):
|
||||
i = lib.LLVMGetPreviousInstruction(self)
|
||||
return i and Instruction(i)
|
||||
|
||||
@property
|
||||
def opcode(self):
|
||||
return OpCode.from_value(lib.LLVMGetInstructionOpcode(self))
|
||||
|
||||
class Context(LLVMObject):
|
||||
|
||||
def __init__(self, context=None):
|
||||
if context is None:
|
||||
context = lib.LLVMContextCreate()
|
||||
LLVMObject.__init__(self, context, disposer=lib.LLVMContextDispose)
|
||||
else:
|
||||
LLVMObject.__init__(self, context)
|
||||
|
||||
@classmethod
|
||||
def GetGlobalContext(cls):
|
||||
return Context(lib.LLVMGetGlobalContext())
|
||||
|
||||
class PassRegistry(LLVMObject):
|
||||
"""Represents an opaque pass registry object."""
|
||||
|
||||
def __init__(self):
|
||||
LLVMObject.__init__(self,
|
||||
lib.LLVMGetGlobalPassRegistry())
|
||||
|
||||
def register_library(library):
|
||||
# Initialization/Shutdown declarations.
|
||||
library.LLVMInitializeCore.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeCore.restype = None
|
||||
|
||||
library.LLVMInitializeTransformUtils.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeTransformUtils.restype = None
|
||||
|
||||
library.LLVMInitializeScalarOpts.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeScalarOpts.restype = None
|
||||
|
||||
library.LLVMInitializeObjCARCOpts.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeObjCARCOpts.restype = None
|
||||
|
||||
library.LLVMInitializeVectorization.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeVectorization.restype = None
|
||||
|
||||
library.LLVMInitializeInstCombine.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeInstCombine.restype = None
|
||||
|
||||
library.LLVMInitializeIPO.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeIPO.restype = None
|
||||
|
||||
library.LLVMInitializeInstrumentation.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeInstrumentation.restype = None
|
||||
|
||||
library.LLVMInitializeAnalysis.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeAnalysis.restype = None
|
||||
|
||||
library.LLVMInitializeIPA.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeIPA.restype = None
|
||||
|
||||
library.LLVMInitializeCodeGen.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeCodeGen.restype = None
|
||||
|
||||
library.LLVMInitializeTarget.argtypes = [PassRegistry]
|
||||
library.LLVMInitializeTarget.restype = None
|
||||
|
||||
library.LLVMShutdown.argtypes = []
|
||||
library.LLVMShutdown.restype = None
|
||||
|
||||
# Pass Registry declarations.
|
||||
library.LLVMGetGlobalPassRegistry.argtypes = []
|
||||
library.LLVMGetGlobalPassRegistry.restype = c_object_p
|
||||
|
||||
# Context declarations.
|
||||
library.LLVMContextCreate.argtypes = []
|
||||
library.LLVMContextCreate.restype = c_object_p
|
||||
|
||||
library.LLVMContextDispose.argtypes = [Context]
|
||||
library.LLVMContextDispose.restype = None
|
||||
|
||||
library.LLVMGetGlobalContext.argtypes = []
|
||||
library.LLVMGetGlobalContext.restype = c_object_p
|
||||
|
||||
# Memory buffer declarations
|
||||
library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p,
|
||||
POINTER(c_object_p), POINTER(c_char_p)]
|
||||
library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool
|
||||
|
||||
library.LLVMGetBufferSize.argtypes = [MemoryBuffer]
|
||||
|
||||
library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer]
|
||||
|
||||
# Module declarations
|
||||
library.LLVMModuleCreateWithName.argtypes = [c_char_p]
|
||||
library.LLVMModuleCreateWithName.restype = c_object_p
|
||||
|
||||
library.LLVMDisposeModule.argtypes = [Module]
|
||||
library.LLVMDisposeModule.restype = None
|
||||
|
||||
library.LLVMGetDataLayout.argtypes = [Module]
|
||||
library.LLVMGetDataLayout.restype = c_char_p
|
||||
|
||||
library.LLVMSetDataLayout.argtypes = [Module, c_char_p]
|
||||
library.LLVMSetDataLayout.restype = None
|
||||
|
||||
library.LLVMGetTarget.argtypes = [Module]
|
||||
library.LLVMGetTarget.restype = c_char_p
|
||||
|
||||
library.LLVMSetTarget.argtypes = [Module, c_char_p]
|
||||
library.LLVMSetTarget.restype = None
|
||||
|
||||
library.LLVMDumpModule.argtypes = [Module]
|
||||
library.LLVMDumpModule.restype = None
|
||||
|
||||
library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p,
|
||||
POINTER(c_char_p)]
|
||||
library.LLVMPrintModuleToFile.restype = bool
|
||||
|
||||
library.LLVMGetFirstFunction.argtypes = [Module]
|
||||
library.LLVMGetFirstFunction.restype = c_object_p
|
||||
|
||||
library.LLVMGetLastFunction.argtypes = [Module]
|
||||
library.LLVMGetLastFunction.restype = c_object_p
|
||||
|
||||
library.LLVMGetNextFunction.argtypes = [Function]
|
||||
library.LLVMGetNextFunction.restype = c_object_p
|
||||
|
||||
library.LLVMGetPreviousFunction.argtypes = [Function]
|
||||
library.LLVMGetPreviousFunction.restype = c_object_p
|
||||
|
||||
# Value declarations.
|
||||
library.LLVMGetValueName.argtypes = [Value]
|
||||
library.LLVMGetValueName.restype = c_char_p
|
||||
|
||||
library.LLVMDumpValue.argtypes = [Value]
|
||||
library.LLVMDumpValue.restype = None
|
||||
|
||||
library.LLVMGetOperand.argtypes = [Value, c_uint]
|
||||
library.LLVMGetOperand.restype = c_object_p
|
||||
|
||||
library.LLVMSetOperand.argtypes = [Value, Value, c_uint]
|
||||
library.LLVMSetOperand.restype = None
|
||||
|
||||
library.LLVMGetNumOperands.argtypes = [Value]
|
||||
library.LLVMGetNumOperands.restype = c_uint
|
||||
|
||||
# Basic Block Declarations.
|
||||
library.LLVMGetFirstBasicBlock.argtypes = [Function]
|
||||
library.LLVMGetFirstBasicBlock.restype = c_object_p
|
||||
|
||||
library.LLVMGetLastBasicBlock.argtypes = [Function]
|
||||
library.LLVMGetLastBasicBlock.restype = c_object_p
|
||||
|
||||
library.LLVMGetNextBasicBlock.argtypes = [BasicBlock]
|
||||
library.LLVMGetNextBasicBlock.restype = c_object_p
|
||||
|
||||
library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock]
|
||||
library.LLVMGetPreviousBasicBlock.restype = c_object_p
|
||||
|
||||
library.LLVMGetFirstInstruction.argtypes = [BasicBlock]
|
||||
library.LLVMGetFirstInstruction.restype = c_object_p
|
||||
|
||||
library.LLVMGetLastInstruction.argtypes = [BasicBlock]
|
||||
library.LLVMGetLastInstruction.restype = c_object_p
|
||||
|
||||
library.LLVMBasicBlockAsValue.argtypes = [BasicBlock]
|
||||
library.LLVMBasicBlockAsValue.restype = c_object_p
|
||||
|
||||
library.LLVMCountBasicBlocks.argtypes = [Function]
|
||||
library.LLVMCountBasicBlocks.restype = c_uint
|
||||
|
||||
# Instruction Declarations.
|
||||
library.LLVMGetNextInstruction.argtypes = [Instruction]
|
||||
library.LLVMGetNextInstruction.restype = c_object_p
|
||||
|
||||
library.LLVMGetPreviousInstruction.argtypes = [Instruction]
|
||||
library.LLVMGetPreviousInstruction.restype = c_object_p
|
||||
|
||||
library.LLVMGetInstructionOpcode.argtypes = [Instruction]
|
||||
library.LLVMGetInstructionOpcode.restype = c_uint
|
||||
|
||||
def register_enumerations():
|
||||
for name, value in enumerations.OpCodes:
|
||||
OpCode.register(name, value)
|
||||
|
||||
def initialize_llvm():
|
||||
c = Context.GetGlobalContext()
|
||||
p = PassRegistry()
|
||||
lib.LLVMInitializeCore(p)
|
||||
lib.LLVMInitializeTransformUtils(p)
|
||||
lib.LLVMInitializeScalarOpts(p)
|
||||
lib.LLVMInitializeObjCARCOpts(p)
|
||||
lib.LLVMInitializeVectorization(p)
|
||||
lib.LLVMInitializeInstCombine(p)
|
||||
lib.LLVMInitializeIPO(p)
|
||||
lib.LLVMInitializeInstrumentation(p)
|
||||
lib.LLVMInitializeAnalysis(p)
|
||||
lib.LLVMInitializeIPA(p)
|
||||
lib.LLVMInitializeCodeGen(p)
|
||||
lib.LLVMInitializeTarget(p)
|
||||
|
||||
register_library(lib)
|
||||
register_enumerations()
|
||||
initialize_llvm()
|
||||
|
@ -10,7 +10,6 @@
|
||||
from ctypes import CFUNCTYPE
|
||||
from ctypes import POINTER
|
||||
from ctypes import addressof
|
||||
from ctypes import byref
|
||||
from ctypes import c_byte
|
||||
from ctypes import c_char_p
|
||||
from ctypes import c_int
|
||||
@ -34,6 +33,29 @@
|
||||
# Constants for set_options
|
||||
Option_UseMarkup = 1
|
||||
|
||||
|
||||
|
||||
_initialized = False
|
||||
_targets = ['AArch64', 'ARM', 'Hexagon', 'MSP430', 'Mips', 'NVPTX', 'PowerPC', 'R600', 'Sparc', 'SystemZ', 'X86', 'XCore']
|
||||
def _ensure_initialized():
|
||||
global _initialized
|
||||
if not _initialized:
|
||||
# Here one would want to call the functions
|
||||
# LLVMInitializeAll{TargetInfo,TargetMC,Disassembler}s, but
|
||||
# unfortunately they are only defined as static inline
|
||||
# functions in the header files of llvm-c, so they don't exist
|
||||
# as symbols in the shared library.
|
||||
# So until that is fixed use this hack to initialize them all
|
||||
for tgt in _targets:
|
||||
for initializer in ("TargetInfo", "TargetMC", "Disassembler"):
|
||||
try:
|
||||
f = getattr(lib, "LLVMInitialize" + tgt + initializer)
|
||||
except AttributeError:
|
||||
continue
|
||||
f()
|
||||
_initialized = True
|
||||
|
||||
|
||||
class Disassembler(LLVMObject):
|
||||
"""Represents a disassembler instance.
|
||||
|
||||
@ -48,9 +70,12 @@ def __init__(self, triple):
|
||||
The triple argument is the triple to create the disassembler for. This
|
||||
is something like 'i386-apple-darwin9'.
|
||||
"""
|
||||
|
||||
_ensure_initialized()
|
||||
|
||||
ptr = lib.LLVMCreateDisasm(c_char_p(triple), c_void_p(None), c_int(0),
|
||||
callbacks['op_info'](0), callbacks['symbol_lookup'](0))
|
||||
if not ptr.contents:
|
||||
if not ptr:
|
||||
raise Exception('Could not obtain disassembler for triple: %s' %
|
||||
triple)
|
||||
|
||||
|
@ -30,3 +30,9 @@ def get_test_binary(self):
|
||||
|
||||
raise Exception('No suitable test binaries available!')
|
||||
get_test_binary.__test__ = False
|
||||
|
||||
def get_test_file(self):
|
||||
return os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_file")
|
||||
|
||||
def get_test_bc(self):
|
||||
return os.path.join(os.path.dirname(os.path.abspath(__file__)), "test.bc")
|
||||
|
BIN
bindings/python/llvm/tests/test.bc
Normal file
BIN
bindings/python/llvm/tests/test.bc
Normal file
Binary file not shown.
15
bindings/python/llvm/tests/test_bitreader.py
Normal file
15
bindings/python/llvm/tests/test_bitreader.py
Normal file
@ -0,0 +1,15 @@
|
||||
from .base import TestBase
|
||||
from ..core import OpCode
|
||||
from ..core import MemoryBuffer
|
||||
from ..core import PassRegistry
|
||||
from ..core import Context
|
||||
from ..core import Module
|
||||
from ..bit_reader import parse_bitcode
|
||||
|
||||
class TestBitReader(TestBase):
|
||||
|
||||
def test_parse_bitcode(self):
|
||||
source = self.get_test_bc()
|
||||
m = parse_bitcode(MemoryBuffer(filename=source))
|
||||
print m.target
|
||||
print m.datalayout
|
@ -1,6 +1,10 @@
|
||||
from .base import TestBase
|
||||
from ..core import OpCode
|
||||
from ..core import MemoryBuffer
|
||||
from ..core import PassRegistry
|
||||
from ..core import Context
|
||||
from ..core import Module
|
||||
from ..bit_reader import parse_bitcode
|
||||
|
||||
class TestCore(TestBase):
|
||||
def test_opcode(self):
|
||||
@ -13,7 +17,7 @@ def test_opcode(self):
|
||||
self.assertEqual(op, OpCode.Ret)
|
||||
|
||||
def test_memory_buffer_create_from_file(self):
|
||||
source = self.get_test_binary()
|
||||
source = self.get_test_file()
|
||||
|
||||
MemoryBuffer(filename=source)
|
||||
|
||||
@ -21,3 +25,106 @@ def test_memory_buffer_failing(self):
|
||||
with self.assertRaises(Exception):
|
||||
MemoryBuffer(filename="/hopefully/this/path/doesnt/exist")
|
||||
|
||||
def test_memory_buffer_len(self):
|
||||
source = self.get_test_file()
|
||||
m = MemoryBuffer(filename=source)
|
||||
self.assertEqual(len(m), 50)
|
||||
|
||||
def test_create_passregistry(self):
|
||||
PassRegistry()
|
||||
|
||||
def test_create_context(self):
|
||||
Context.GetGlobalContext()
|
||||
|
||||
def test_create_module_with_name(self):
|
||||
# Make sure we can not create a module without a LLVMModuleRef.
|
||||
with self.assertRaises(TypeError):
|
||||
m = Module()
|
||||
m = Module.CreateWithName("test-module")
|
||||
|
||||
def test_module_getset_datalayout(self):
|
||||
m = Module.CreateWithName("test-module")
|
||||
dl = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
|
||||
m.datalayout = dl
|
||||
self.assertEqual(m.datalayout, dl)
|
||||
|
||||
def test_module_getset_target(self):
|
||||
m = Module.CreateWithName("test-module")
|
||||
target = "thumbv7-apple-ios5.0.0"
|
||||
m.target = target
|
||||
self.assertEqual(m.target, target)
|
||||
|
||||
def test_module_print_module_to_file(self):
|
||||
m = Module.CreateWithName("test")
|
||||
dl = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
|
||||
m.datalayout = dl
|
||||
target = "thumbv7-apple-ios5.0.0"
|
||||
m.target = target
|
||||
m.print_module_to_file("test2.ll")
|
||||
|
||||
def test_module_function_iteration(self):
|
||||
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
|
||||
i = 0
|
||||
functions = ["f", "f2", "f3", "f4", "f5", "f6", "g1", "g2", "h1", "h2",
|
||||
"h3"]
|
||||
# Forward
|
||||
for f in m:
|
||||
self.assertEqual(f.name, functions[i])
|
||||
f.dump()
|
||||
i += 1
|
||||
# Backwards
|
||||
for f in reversed(m):
|
||||
i -= 1
|
||||
self.assertEqual(f.name, functions[i])
|
||||
f.dump()
|
||||
|
||||
def test_function_basicblock_iteration(self):
|
||||
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
|
||||
i = 0
|
||||
|
||||
bb_list = ['b1', 'b2', 'end']
|
||||
|
||||
f = m.first
|
||||
while f.name != "f6":
|
||||
f = f.next
|
||||
|
||||
# Forward
|
||||
for bb in f:
|
||||
self.assertEqual(bb.name, bb_list[i])
|
||||
bb.dump()
|
||||
i += 1
|
||||
|
||||
# Backwards
|
||||
for bb in reversed(f):
|
||||
i -= 1
|
||||
self.assertEqual(bb.name, bb_list[i])
|
||||
bb.dump()
|
||||
|
||||
def test_basicblock_instruction_iteration(self):
|
||||
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
|
||||
i = 0
|
||||
|
||||
inst_list = [('arg1', OpCode.ExtractValue),
|
||||
('arg2', OpCode.ExtractValue),
|
||||
('', OpCode.Call),
|
||||
('', OpCode.Ret)]
|
||||
|
||||
bb = m.first.first
|
||||
|
||||
# Forward
|
||||
for inst in bb:
|
||||
self.assertEqual(inst.name, inst_list[i][0])
|
||||
self.assertEqual(inst.opcode, inst_list[i][1])
|
||||
for op in range(len(inst)):
|
||||
o = inst.get_operand(op)
|
||||
print o.name
|
||||
o.dump()
|
||||
inst.dump()
|
||||
i += 1
|
||||
|
||||
# Backwards
|
||||
for inst in reversed(bb):
|
||||
i -= 1
|
||||
self.assertEqual(inst.name, inst_list[i][0])
|
||||
self.assertEqual(inst.opcode, inst_list[i][1])
|
||||
inst.dump()
|
||||
|
@ -16,6 +16,10 @@ def test_basic(self):
|
||||
self.assertEqual(count, 3)
|
||||
self.assertEqual(s, '\tjcxz\t-127')
|
||||
|
||||
def test_nonexistant_triple(self):
|
||||
with self.assertRaisesRegexp(Exception, "Could not obtain disassembler for triple"):
|
||||
Disassembler("nonexistant-triple-raises")
|
||||
|
||||
def test_get_instructions(self):
|
||||
sequence = '\x67\xe3\x81\x01\xc7' # jcxz -127; addl %eax, %edi
|
||||
|
||||
|
1
bindings/python/llvm/tests/test_file
Normal file
1
bindings/python/llvm/tests/test_file
Normal file
@ -0,0 +1 @@
|
||||
I,"ìcAGðxq‘ÑÔ<C391>¹d«±ùà§vl¥À\»L>šg>`ö©ÿ©`<60>‡wÉ©
|
@ -35,37 +35,24 @@ function(check_type_exists type files variable)
|
||||
endfunction()
|
||||
|
||||
# include checks
|
||||
check_include_file(argz.h HAVE_ARGZ_H)
|
||||
check_include_file(assert.h HAVE_ASSERT_H)
|
||||
check_include_file(ctype.h HAVE_CTYPE_H)
|
||||
check_include_file_cxx(cxxabi.h HAVE_CXXABI_H)
|
||||
check_include_file(dirent.h HAVE_DIRENT_H)
|
||||
check_include_file(dl.h HAVE_DL_H)
|
||||
check_include_file(dld.h HAVE_DLD_H)
|
||||
check_include_file(dlfcn.h HAVE_DLFCN_H)
|
||||
check_include_file(errno.h HAVE_ERRNO_H)
|
||||
check_include_file(execinfo.h HAVE_EXECINFO_H)
|
||||
check_include_file(fcntl.h HAVE_FCNTL_H)
|
||||
check_include_file(inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_file(limits.h HAVE_LIMITS_H)
|
||||
check_include_file(link.h HAVE_LINK_H)
|
||||
check_include_file(malloc.h HAVE_MALLOC_H)
|
||||
check_include_file(malloc/malloc.h HAVE_MALLOC_MALLOC_H)
|
||||
check_include_file(memory.h HAVE_MEMORY_H)
|
||||
check_include_file(ndir.h HAVE_NDIR_H)
|
||||
if( NOT PURE_WINDOWS )
|
||||
check_include_file(pthread.h HAVE_PTHREAD_H)
|
||||
endif()
|
||||
check_include_file(sanitizer/msan_interface.h HAVE_SANITIZER_MSAN_INTERFACE_H)
|
||||
check_include_file(setjmp.h HAVE_SETJMP_H)
|
||||
check_include_file(signal.h HAVE_SIGNAL_H)
|
||||
check_include_file(stdint.h HAVE_STDINT_H)
|
||||
check_include_file(stdio.h HAVE_STDIO_H)
|
||||
check_include_file(stdlib.h HAVE_STDLIB_H)
|
||||
check_include_file(string.h HAVE_STRING_H)
|
||||
check_include_file(strings.h HAVE_STRINGS_H)
|
||||
check_include_file(sys/dir.h HAVE_SYS_DIR_H)
|
||||
check_include_file(sys/dl.h HAVE_SYS_DL_H)
|
||||
check_include_file(sys/ioctl.h HAVE_SYS_IOCTL_H)
|
||||
check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
|
||||
check_include_file(sys/ndir.h HAVE_SYS_NDIR_H)
|
||||
@ -73,14 +60,12 @@ check_include_file(sys/param.h HAVE_SYS_PARAM_H)
|
||||
check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H)
|
||||
check_include_file(sys/stat.h HAVE_SYS_STAT_H)
|
||||
check_include_file(sys/time.h HAVE_SYS_TIME_H)
|
||||
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
|
||||
check_include_file(sys/uio.h HAVE_SYS_UIO_H)
|
||||
check_include_file(sys/wait.h HAVE_SYS_WAIT_H)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||
check_include_file(utime.h HAVE_UTIME_H)
|
||||
check_include_file(valgrind/valgrind.h HAVE_VALGRIND_VALGRIND_H)
|
||||
check_include_file(windows.h HAVE_WINDOWS_H)
|
||||
check_include_file(zlib.h HAVE_ZLIB_H)
|
||||
check_include_file(fenv.h HAVE_FENV_H)
|
||||
check_symbol_exists(FE_ALL_EXCEPT "fenv.h" HAVE_DECL_FE_ALL_EXCEPT)
|
||||
@ -112,6 +97,20 @@ if( NOT PURE_WINDOWS )
|
||||
else()
|
||||
set(HAVE_LIBZ 0)
|
||||
endif()
|
||||
if(LLVM_ENABLE_TERMINFO)
|
||||
set(HAVE_TERMINFO 0)
|
||||
foreach(library tinfo terminfo curses ncurses ncursesw)
|
||||
string(TOUPPER ${library} library_suffix)
|
||||
check_library_exists(${library} setupterm "" HAVE_TERMINFO_${library_suffix})
|
||||
if(HAVE_TERMINFO_${library_suffix})
|
||||
set(HAVE_TERMINFO 1)
|
||||
set(TERMINFO_LIBS "${library}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(HAVE_TERMINFO 0)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# function checks
|
||||
@ -121,7 +120,6 @@ check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE)
|
||||
check_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE)
|
||||
check_symbol_exists(setrlimit sys/resource.h HAVE_SETRLIMIT)
|
||||
check_symbol_exists(isatty unistd.h HAVE_ISATTY)
|
||||
check_symbol_exists(index strings.h HAVE_INDEX)
|
||||
check_symbol_exists(isinf cmath HAVE_ISINF_IN_CMATH)
|
||||
check_symbol_exists(isinf math.h HAVE_ISINF_IN_MATH_H)
|
||||
check_symbol_exists(finite ieeefp.h HAVE_FINITE_IN_IEEEFP_H)
|
||||
@ -136,6 +134,8 @@ check_symbol_exists(log10 math.h HAVE_LOG10)
|
||||
check_symbol_exists(exp math.h HAVE_EXP)
|
||||
check_symbol_exists(exp2 math.h HAVE_EXP2)
|
||||
check_symbol_exists(exp10 math.h HAVE_EXP10)
|
||||
check_symbol_exists(futimens sys/stat.h HAVE_FUTIMENS)
|
||||
check_symbol_exists(futimes sys/time.h HAVE_FUTIMES)
|
||||
if( HAVE_SETJMP_H )
|
||||
check_symbol_exists(longjmp setjmp.h HAVE_LONGJMP)
|
||||
check_symbol_exists(setjmp setjmp.h HAVE_SETJMP)
|
||||
@ -160,11 +160,7 @@ check_symbol_exists(gettimeofday sys/time.h HAVE_GETTIMEOFDAY)
|
||||
check_symbol_exists(getrlimit "sys/types.h;sys/time.h;sys/resource.h" HAVE_GETRLIMIT)
|
||||
check_symbol_exists(posix_spawn spawn.h HAVE_POSIX_SPAWN)
|
||||
check_symbol_exists(pread unistd.h HAVE_PREAD)
|
||||
check_symbol_exists(rindex strings.h HAVE_RINDEX)
|
||||
check_symbol_exists(strchr string.h HAVE_STRCHR)
|
||||
check_symbol_exists(strcmp string.h HAVE_STRCMP)
|
||||
check_symbol_exists(strdup string.h HAVE_STRDUP)
|
||||
check_symbol_exists(strrchr string.h HAVE_STRRCHR)
|
||||
check_symbol_exists(realpath stdlib.h HAVE_REALPATH)
|
||||
check_symbol_exists(sbrk unistd.h HAVE_SBRK)
|
||||
check_symbol_exists(srand48 stdlib.h HAVE_RAND48_SRAND48)
|
||||
if( HAVE_RAND48_SRAND48 )
|
||||
@ -181,8 +177,6 @@ check_symbol_exists(strtoq stdlib.h HAVE_STRTOQ)
|
||||
check_symbol_exists(strerror string.h HAVE_STRERROR)
|
||||
check_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
|
||||
check_symbol_exists(strerror_s string.h HAVE_DECL_STRERROR_S)
|
||||
check_symbol_exists(memcpy string.h HAVE_MEMCPY)
|
||||
check_symbol_exists(memmove string.h HAVE_MEMMOVE)
|
||||
check_symbol_exists(setenv stdlib.h HAVE_SETENV)
|
||||
if( PURE_WINDOWS )
|
||||
check_symbol_exists(_chsize_s io.h HAVE__CHSIZE_S)
|
||||
@ -206,13 +200,6 @@ if( PURE_WINDOWS )
|
||||
check_function_exists(__main HAVE___MAIN)
|
||||
check_function_exists(__cmpdi2 HAVE___CMPDI2)
|
||||
endif()
|
||||
if( HAVE_ARGZ_H )
|
||||
check_symbol_exists(argz_append argz.h HAVE_ARGZ_APPEND)
|
||||
check_symbol_exists(argz_create_sep argz.h HAVE_ARGZ_CREATE_SEP)
|
||||
check_symbol_exists(argz_insert argz.h HAVE_ARGZ_INSERT)
|
||||
check_symbol_exists(argz_next argz.h HAVE_ARGZ_NEXT)
|
||||
check_symbol_exists(argz_stringify argz.h HAVE_ARGZ_STRINGIFY)
|
||||
endif()
|
||||
if( HAVE_DLFCN_H )
|
||||
if( HAVE_LIBDL )
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES dl)
|
||||
@ -229,10 +216,7 @@ if( LLVM_USING_GLIBC )
|
||||
add_llvm_definitions( -D_GNU_SOURCE )
|
||||
endif()
|
||||
|
||||
set(headers "")
|
||||
if (HAVE_SYS_TYPES_H)
|
||||
set(headers ${headers} "sys/types.h")
|
||||
endif()
|
||||
set(headers "sys/types.h")
|
||||
|
||||
if (HAVE_INTTYPES_H)
|
||||
set(headers ${headers} "inttypes.h")
|
||||
@ -245,13 +229,13 @@ endif()
|
||||
check_type_exists(int64_t "${headers}" HAVE_INT64_T)
|
||||
check_type_exists(uint64_t "${headers}" HAVE_UINT64_T)
|
||||
check_type_exists(u_int64_t "${headers}" HAVE_U_INT64_T)
|
||||
check_type_exists(error_t errno.h HAVE_ERROR_T)
|
||||
|
||||
# available programs checks
|
||||
function(llvm_find_program name)
|
||||
string(TOUPPER ${name} NAME)
|
||||
string(REGEX REPLACE "\\." "_" NAME ${NAME})
|
||||
find_program(LLVM_PATH_${NAME} ${name})
|
||||
|
||||
find_program(LLVM_PATH_${NAME} NAMES ${ARGV})
|
||||
mark_as_advanced(LLVM_PATH_${NAME})
|
||||
if(LLVM_PATH_${NAME})
|
||||
set(HAVE_${NAME} 1 CACHE INTERNAL "Is ${name} available ?")
|
||||
@ -268,7 +252,7 @@ llvm_find_program(neato)
|
||||
llvm_find_program(fdp)
|
||||
llvm_find_program(dot)
|
||||
llvm_find_program(dotty)
|
||||
llvm_find_program(xdot.py)
|
||||
llvm_find_program(xdot xdot.py)
|
||||
llvm_find_program(Graphviz)
|
||||
|
||||
if( LLVM_ENABLE_FFI )
|
||||
@ -316,6 +300,20 @@ endif()
|
||||
find_package(LibXml2)
|
||||
if (LIBXML2_FOUND)
|
||||
set(CLANG_HAVE_LIBXML 1)
|
||||
# When cross-compiling, liblzma is not detected as a dependency for libxml2,
|
||||
# which makes linking c-index-test fail. But for native builds, all libraries
|
||||
# are installed and checked by CMake before Makefiles are generated and everything
|
||||
# works according to the plan. However, if a -llzma is added to native builds,
|
||||
# an additional requirement on the static liblzma.a is required, but will not
|
||||
# be checked by CMake, breaking native compilation.
|
||||
# Since this is only pertinent to cross-compilations, and there's no way CMake
|
||||
# can check for every foreign library on every OS, we add the dep and warn the dev.
|
||||
if ( CMAKE_CROSSCOMPILING )
|
||||
if (NOT PC_LIBXML_VERSION VERSION_LESS "2.8.0")
|
||||
message(STATUS "Adding LZMA as a dep to XML2 for cross-compilation, make sure liblzma.a is available.")
|
||||
set(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} "-llzma")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
@ -384,6 +382,14 @@ else ()
|
||||
message(FATAL_ERROR "Unknown architecture ${LLVM_NATIVE_ARCH}")
|
||||
endif ()
|
||||
|
||||
# If build targets includes "host", then replace with native architecture.
|
||||
list(FIND LLVM_TARGETS_TO_BUILD "host" idx)
|
||||
if( NOT idx LESS 0 )
|
||||
list(REMOVE_AT LLVM_TARGETS_TO_BUILD ${idx})
|
||||
list(APPEND LLVM_TARGETS_TO_BUILD ${LLVM_NATIVE_ARCH})
|
||||
list(REMOVE_DUPLICATES LLVM_TARGETS_TO_BUILD)
|
||||
endif()
|
||||
|
||||
list(FIND LLVM_TARGETS_TO_BUILD ${LLVM_NATIVE_ARCH} NATIVE_ARCH_IDX)
|
||||
if (NATIVE_ARCH_IDX EQUAL -1)
|
||||
message(STATUS
|
||||
@ -409,27 +415,26 @@ endif ()
|
||||
if( MINGW )
|
||||
set(HAVE_LIBIMAGEHLP 1)
|
||||
set(HAVE_LIBPSAPI 1)
|
||||
set(HAVE_LIBSHELL32 1)
|
||||
# TODO: Check existence of libraries.
|
||||
# include(CheckLibraryExists)
|
||||
# CHECK_LIBRARY_EXISTS(imagehlp ??? . HAVE_LIBIMAGEHLP)
|
||||
endif( MINGW )
|
||||
|
||||
if (NOT HAVE_STRTOLL)
|
||||
# Use _strtoi64 if strtoll is not available.
|
||||
check_symbol_exists(_strtoi64 stdlib.h have_strtoi64)
|
||||
if (have_strtoi64)
|
||||
set(HAVE_STRTOLL 1)
|
||||
set(strtoll "_strtoi64")
|
||||
set(strtoull "_strtoui64")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if( MSVC )
|
||||
set(error_t int)
|
||||
set(LTDL_SHLIBPATH_VAR "PATH")
|
||||
set(LTDL_SYSSEARCHPATH "")
|
||||
set(LTDL_DLOPEN_DEPLIBS 1)
|
||||
set(SHLIBEXT ".lib")
|
||||
set(LTDL_OBJDIR "_libs")
|
||||
set(HAVE_STRTOLL 1)
|
||||
set(strtoll "_strtoi64")
|
||||
set(strtoull "_strtoui64")
|
||||
set(stricmp "_stricmp")
|
||||
set(strdup "_strdup")
|
||||
else( MSVC )
|
||||
set(LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH")
|
||||
set(LTDL_SYSSEARCHPATH "") # TODO
|
||||
set(LTDL_DLOPEN_DEPLIBS 0) # TODO
|
||||
endif( MSVC )
|
||||
|
||||
if( PURE_WINDOWS )
|
||||
@ -471,3 +476,25 @@ if (LLVM_ENABLE_ZLIB )
|
||||
endif()
|
||||
|
||||
set(LLVM_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
if (LLVM_ENABLE_DOXYGEN)
|
||||
message(STATUS "Doxygen enabled.")
|
||||
find_package(Doxygen)
|
||||
|
||||
if (DOXYGEN_FOUND)
|
||||
# If we find doxygen and we want to enable doxygen by default create a
|
||||
# global aggregate doxygen target for generating llvm and any/all
|
||||
# subprojects doxygen documentation.
|
||||
if (LLVM_BUILD_DOCS)
|
||||
add_custom_target(doxygen ALL)
|
||||
endif()
|
||||
|
||||
option(LLVM_DOXYGEN_EXTERNAL_SEARCH "Enable doxygen external search." OFF)
|
||||
if (LLVM_DOXYGEN_EXTERNAL_SEARCH)
|
||||
set(LLVM_DOXYGEN_SEARCHENGINE_URL "" CACHE STRING "URL to use for external searhc.")
|
||||
set(LLVM_DOXYGEN_SEARCH_MAPPINGS "" CACHE STRING "Doxygen Search Mappings")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Doxygen disabled.")
|
||||
endif()
|
||||
|
@ -12,6 +12,11 @@ macro(add_llvm_library name)
|
||||
|
||||
if( BUILD_SHARED_LIBS )
|
||||
llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
|
||||
if (MSVC)
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
IMPORT_SUFFIX ".imp")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
# Ensure that the system libraries always comes last on the
|
||||
@ -21,9 +26,11 @@ macro(add_llvm_library name)
|
||||
if( EXCLUDE_FROM_ALL )
|
||||
set_target_properties( ${name} PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
else()
|
||||
install(TARGETS ${name}
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "LTO")
|
||||
install(TARGETS ${name}
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
|
||||
endif()
|
||||
endif()
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Libraries")
|
||||
|
||||
@ -65,9 +72,11 @@ ${name} ignored.")
|
||||
if( EXCLUDE_FROM_ALL )
|
||||
set_target_properties( ${name} PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
else()
|
||||
install(TARGETS ${name}
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
install(TARGETS ${name}
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -91,14 +100,23 @@ macro(add_llvm_executable name)
|
||||
endmacro(add_llvm_executable name)
|
||||
|
||||
|
||||
set (LLVM_TOOLCHAIN_TOOLS
|
||||
llvm-ar
|
||||
llvm-objdump
|
||||
)
|
||||
|
||||
macro(add_llvm_tool name)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR})
|
||||
if( NOT LLVM_BUILD_TOOLS )
|
||||
set(EXCLUDE_FROM_ALL ON)
|
||||
endif()
|
||||
add_llvm_executable(${name} ${ARGN})
|
||||
if( LLVM_BUILD_TOOLS )
|
||||
install(TARGETS ${name} RUNTIME DESTINATION bin)
|
||||
|
||||
list(FIND LLVM_TOOLCHAIN_TOOLS ${name} LLVM_IS_${name}_TOOLCHAIN_TOOL)
|
||||
if (LLVM_IS_${name}_TOOLCHAIN_TOOL GREATER -1 OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
if( LLVM_BUILD_TOOLS )
|
||||
install(TARGETS ${name} RUNTIME DESTINATION bin)
|
||||
endif()
|
||||
endif()
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Tools")
|
||||
endmacro(add_llvm_tool name)
|
||||
@ -141,6 +159,7 @@ macro(add_llvm_external_project name)
|
||||
if("${add_llvm_external_dir}" STREQUAL "")
|
||||
set(add_llvm_external_dir ${name})
|
||||
endif()
|
||||
list(APPEND LLVM_IMPLICIT_PROJECT_IGNORE "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}")
|
||||
string(REPLACE "-" "_" nameUNDERSCORE ${name})
|
||||
string(TOUPPER ${nameUNDERSCORE} nameUPPER)
|
||||
set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}"
|
||||
@ -155,6 +174,34 @@ macro(add_llvm_external_project name)
|
||||
endif()
|
||||
endmacro(add_llvm_external_project)
|
||||
|
||||
macro(add_llvm_tool_subdirectory name)
|
||||
list(APPEND LLVM_IMPLICIT_PROJECT_IGNORE "${CMAKE_CURRENT_SOURCE_DIR}/${name}")
|
||||
add_subdirectory(${name})
|
||||
endmacro(add_llvm_tool_subdirectory)
|
||||
|
||||
macro(ignore_llvm_tool_subdirectory name)
|
||||
list(APPEND LLVM_IMPLICIT_PROJECT_IGNORE "${CMAKE_CURRENT_SOURCE_DIR}/${name}")
|
||||
endmacro(ignore_llvm_tool_subdirectory)
|
||||
|
||||
function(add_llvm_implicit_external_projects)
|
||||
set(list_of_implicit_subdirs "")
|
||||
file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*")
|
||||
foreach(dir ${sub-dirs})
|
||||
if(IS_DIRECTORY "${dir}")
|
||||
list(FIND LLVM_IMPLICIT_PROJECT_IGNORE "${dir}" tool_subdir_ignore)
|
||||
if( tool_subdir_ignore EQUAL -1
|
||||
AND EXISTS "${dir}/CMakeLists.txt")
|
||||
get_filename_component(fn "${dir}" NAME)
|
||||
list(APPEND list_of_implicit_subdirs "${fn}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(external_proj ${list_of_implicit_subdirs})
|
||||
add_llvm_external_project("${external_proj}")
|
||||
endforeach()
|
||||
endfunction(add_llvm_implicit_external_projects)
|
||||
|
||||
# Generic support for adding a unittest.
|
||||
function(add_unittest test_suite test_name)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
@ -191,7 +238,7 @@ function(add_unittest test_suite test_name)
|
||||
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
|
||||
set(target_compile_flags "${target_compile_flags} -fno-rtti")
|
||||
elseif (MSVC)
|
||||
set(target_compile_flags "${target_compile_flags} /GR-")
|
||||
llvm_replace_compiler_option(target_compile_flags "/GR" "/GR-")
|
||||
endif ()
|
||||
|
||||
if (SUPPORTS_NO_VARIADIC_MACROS_FLAG)
|
||||
@ -249,6 +296,22 @@ function(configure_lit_site_cfg input output)
|
||||
set(HOST_OS ${CMAKE_SYSTEM_NAME})
|
||||
set(HOST_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
||||
|
||||
if (CLANG_ENABLE_ARCMT)
|
||||
set(ENABLE_CLANG_ARCMT "1")
|
||||
else()
|
||||
set(ENABLE_CLANG_ARCMT "0")
|
||||
endif()
|
||||
if (CLANG_ENABLE_REWRITER)
|
||||
set(ENABLE_CLANG_REWRITER "1")
|
||||
else()
|
||||
set(ENABLE_CLANG_REWRITER "0")
|
||||
endif()
|
||||
if (CLANG_ENABLE_STATIC_ANALYZER)
|
||||
set(ENABLE_CLANG_STATIC_ANALYZER "1")
|
||||
else()
|
||||
set(ENABLE_CLANG_STATIC_ANALYZER "0")
|
||||
endif()
|
||||
|
||||
configure_file(${input} ${output} @ONLY)
|
||||
endfunction()
|
||||
|
||||
|
@ -19,19 +19,21 @@ configure_file(
|
||||
${llvm_cmake_builddir}/LLVMConfigVersion.cmake
|
||||
@ONLY)
|
||||
|
||||
install(FILES
|
||||
${llvm_cmake_builddir}/LLVMConfig.cmake
|
||||
${llvm_cmake_builddir}/LLVMConfigVersion.cmake
|
||||
LLVM-Config.cmake
|
||||
DESTINATION share/llvm/cmake)
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
install(FILES
|
||||
${llvm_cmake_builddir}/LLVMConfig.cmake
|
||||
${llvm_cmake_builddir}/LLVMConfigVersion.cmake
|
||||
LLVM-Config.cmake
|
||||
DESTINATION share/llvm/cmake)
|
||||
|
||||
install(DIRECTORY .
|
||||
DESTINATION share/llvm/cmake
|
||||
FILES_MATCHING PATTERN *.cmake
|
||||
PATTERN .svn EXCLUDE
|
||||
PATTERN LLVMConfig.cmake EXCLUDE
|
||||
PATTERN LLVMConfigVersion.cmake EXCLUDE
|
||||
PATTERN LLVM-Config.cmake EXCLUDE
|
||||
PATTERN GetHostTriple.cmake EXCLUDE
|
||||
PATTERN VersionFromVCS.cmake EXCLUDE
|
||||
PATTERN CheckAtomic.cmake EXCLUDE)
|
||||
install(DIRECTORY .
|
||||
DESTINATION share/llvm/cmake
|
||||
FILES_MATCHING PATTERN *.cmake
|
||||
PATTERN .svn EXCLUDE
|
||||
PATTERN LLVMConfig.cmake EXCLUDE
|
||||
PATTERN LLVMConfigVersion.cmake EXCLUDE
|
||||
PATTERN LLVM-Config.cmake EXCLUDE
|
||||
PATTERN GetHostTriple.cmake EXCLUDE
|
||||
PATTERN VersionFromVCS.cmake EXCLUDE
|
||||
PATTERN CheckAtomic.cmake EXCLUDE)
|
||||
endif()
|
||||
|
@ -71,7 +71,7 @@ variables (LLVM_USE_CRT_DEBUG, etc) instead.")
|
||||
CACHE STRING "Specify VC++ CRT to use for ${build_type} configurations."
|
||||
FORCE)
|
||||
set_property(CACHE LLVM_USE_CRT_${build}
|
||||
PROPERTY STRINGS "";${${MSVC_CRT}})
|
||||
PROPERTY STRINGS ;${${MSVC_CRT}})
|
||||
endif(NOT LLVM_USE_CRT_${build})
|
||||
endforeach(build_type)
|
||||
|
||||
|
@ -8,6 +8,8 @@ include(CheckCXXCompilerFlag)
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||
set(LLVM_COMPILER_IS_GCC_COMPATIBLE ON)
|
||||
elseif( MSVC )
|
||||
set(LLVM_COMPILER_IS_GCC_COMPATIBLE OFF)
|
||||
elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
||||
set(LLVM_COMPILER_IS_GCC_COMPATIBLE ON)
|
||||
endif()
|
||||
@ -17,13 +19,18 @@ if( LLVM_ENABLE_ASSERTIONS )
|
||||
if( NOT MSVC )
|
||||
add_definitions( -D_DEBUG )
|
||||
endif()
|
||||
# On Release builds cmake automatically defines NDEBUG, so we
|
||||
# On non-Debug builds cmake automatically defines NDEBUG, so we
|
||||
# explicitly undefine it:
|
||||
if( uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE" )
|
||||
if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
|
||||
add_definitions( -UNDEBUG )
|
||||
# Also remove /D NDEBUG to avoid MSVC warnings about conflicting defines.
|
||||
string (REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " "
|
||||
CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(REGEXP_NDEBUG "(^| )[/-]D *NDEBUG($| )")
|
||||
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
|
||||
CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
|
||||
endif()
|
||||
else()
|
||||
if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE" )
|
||||
@ -151,10 +158,25 @@ endif()
|
||||
if( MSVC )
|
||||
include(ChooseMSVCCRT)
|
||||
|
||||
if( MSVC11 )
|
||||
add_llvm_definitions(-D_VARIADIC_MAX=10)
|
||||
if( NOT (${CMAKE_VERSION} VERSION_LESS 2.8.11) )
|
||||
# set stack reserved size to ~10MB
|
||||
# CMake previously automatically set this value for MSVC builds, but the
|
||||
# behavior was changed in CMake 2.8.11 (Issue 12437) to use the MSVC default
|
||||
# value (1 MB) which is not enough for us in tasks such as parsing recursive
|
||||
# C++ templates in Clang.
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:10000000")
|
||||
endif()
|
||||
|
||||
if( MSVC10 )
|
||||
# MSVC 10 will complain about headers in the STL not being exported, but
|
||||
# will not complain in MSVC 11.
|
||||
add_llvm_definitions(
|
||||
-wd4275 # Suppress 'An exported class was derived from a class that was not exported.'
|
||||
)
|
||||
elseif( MSVC11 )
|
||||
add_llvm_definitions(-D_VARIADIC_MAX=10)
|
||||
endif()
|
||||
|
||||
# Add definitions that make MSVC much less annoying.
|
||||
add_llvm_definitions(
|
||||
# For some reason MS wants to deprecate a bunch of standard functions...
|
||||
@ -166,25 +188,18 @@ if( MSVC )
|
||||
-D_SCL_SECURE_NO_WARNINGS
|
||||
|
||||
# Disabled warnings.
|
||||
-wd4065 # Suppress 'switch statement contains 'default' but no 'case' labels'
|
||||
-wd4146 # Suppress 'unary minus operator applied to unsigned type, result still unsigned'
|
||||
-wd4180 # Suppress 'qualifier applied to function type has no meaning; ignored'
|
||||
-wd4181 # Suppress 'qualifier applied to reference type; ignored'
|
||||
-wd4224 # Suppress 'nonstandard extension used : formal parameter 'identifier' was previously defined as a type'
|
||||
-wd4244 # Suppress ''argument' : conversion from 'type1' to 'type2', possible loss of data'
|
||||
-wd4267 # Suppress ''var' : conversion from 'size_t' to 'type', possible loss of data'
|
||||
-wd4275 # Suppress 'An exported class was derived from a class that was not exported.'
|
||||
-wd4291 # Suppress ''declaration' : no matching operator delete found; memory will not be freed if initialization throws an exception'
|
||||
-wd4345 # Suppress 'behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized'
|
||||
-wd4351 # Suppress 'new behavior: elements of array 'array' will be default initialized'
|
||||
-wd4355 # Suppress ''this' : used in base member initializer list'
|
||||
-wd4503 # Suppress ''identifier' : decorated name length exceeded, name was truncated'
|
||||
-wd4551 # Suppress 'function call missing argument list'
|
||||
-wd4624 # Suppress ''derived class' : destructor could not be generated because a base class destructor is inaccessible'
|
||||
-wd4715 # Suppress ''function' : not all control paths return a value'
|
||||
-wd4722 # Suppress ''function' : destructor never returns, potential memory leak'
|
||||
-wd4800 # Suppress ''type' : forcing value to bool 'true' or 'false' (performance warning)'
|
||||
|
||||
-wd4291 # Suppress ''declaration' : no matching operator delete found; memory will not be freed if initialization throws an exception'
|
||||
|
||||
# Promoted warnings.
|
||||
-w14062 # Promote 'enumerator in switch of enum is not handled' to level 1 warning.
|
||||
|
||||
@ -241,6 +256,10 @@ macro(append_common_sanitizer_flags)
|
||||
NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
|
||||
add_flag_if_supported("-gline-tables-only")
|
||||
endif()
|
||||
# Use -O1 even in debug mode, otherwise sanitizers slowdown is too large.
|
||||
if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
|
||||
add_flag_if_supported("-O1")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Turn on sanitizers if necessary.
|
||||
@ -263,6 +282,18 @@ if(LLVM_USE_SANITIZER)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Turn on -gsplit-dwarf if requested
|
||||
if(LLVM_USE_SPLIT_DWARF)
|
||||
add_llvm_definitions("-gsplit-dwarf")
|
||||
endif()
|
||||
|
||||
add_llvm_definitions( -D__STDC_CONSTANT_MACROS )
|
||||
add_llvm_definitions( -D__STDC_FORMAT_MACROS )
|
||||
add_llvm_definitions( -D__STDC_LIMIT_MACROS )
|
||||
|
||||
# clang doesn't print colored diagnostics when invoked from Ninja
|
||||
if (UNIX AND
|
||||
CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
|
||||
CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
append("-fcolor-diagnostics" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
endif()
|
||||
|
@ -2,7 +2,7 @@ function(get_system_libs return_var)
|
||||
# Returns in `return_var' a list of system libraries used by LLVM.
|
||||
if( NOT MSVC )
|
||||
if( MINGW )
|
||||
set(system_libs ${system_libs} imagehlp psapi)
|
||||
set(system_libs ${system_libs} imagehlp psapi shell32)
|
||||
elseif( CMAKE_HOST_UNIX )
|
||||
if( HAVE_LIBRT )
|
||||
set(system_libs ${system_libs} rt)
|
||||
@ -10,6 +10,11 @@ function(get_system_libs return_var)
|
||||
if( HAVE_LIBDL )
|
||||
set(system_libs ${system_libs} ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
if(LLVM_ENABLE_TERMINFO)
|
||||
if(HAVE_TERMINFO)
|
||||
set(system_libs ${system_libs} ${TERMINFO_LIBS})
|
||||
endif()
|
||||
endif()
|
||||
if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
|
||||
set(system_libs ${system_libs} pthread)
|
||||
endif()
|
||||
|
@ -20,6 +20,8 @@ set(TARGET_TRIPLE "@TARGET_TRIPLE@")
|
||||
|
||||
set(LLVM_TOOLS_BINARY_DIR @LLVM_TOOLS_BINARY_DIR@)
|
||||
|
||||
set(LLVM_ENABLE_TERMINFO @LLVM_ENABLE_TERMINFO@)
|
||||
|
||||
set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@)
|
||||
|
||||
set(LLVM_ENABLE_ZLIB @LLVM_ENABLE_ZLIB@)
|
||||
@ -28,6 +30,8 @@ set(LLVM_NATIVE_ARCH @LLVM_NATIVE_ARCH@)
|
||||
|
||||
set(LLVM_ENABLE_PIC @LLVM_ENABLE_PIC@)
|
||||
|
||||
set(HAVE_TERMINFO @HAVE_TERMINFO@)
|
||||
set(TERMINFO_LIBS @TERMINFO_LIBS@)
|
||||
set(HAVE_LIBDL @HAVE_LIBDL@)
|
||||
set(HAVE_LIBPTHREAD @HAVE_LIBPTHREAD@)
|
||||
set(HAVE_LIBZ @HAVE_LIBZ@)
|
||||
|
@ -66,7 +66,8 @@ if(CMAKE_CROSSCOMPILING)
|
||||
|
||||
add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR}/CMakeCache.txt
|
||||
COMMAND ${CMAKE_COMMAND} -UMAKE_TOOLCHAIN_FILE -DCMAKE_BUILD_TYPE=Release
|
||||
-DLLVM_BUILD_POLLY=OFF ${CMAKE_SOURCE_DIR}
|
||||
-DLLVM_BUILD_POLLY=OFF
|
||||
-G "${CMAKE_GENERATOR}" ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${CX_NATIVE_TG_DIR}
|
||||
DEPENDS ${CX_NATIVE_TG_DIR}
|
||||
COMMENT "Configuring native TableGen...")
|
||||
@ -84,6 +85,16 @@ macro(add_tablegen target project)
|
||||
add_llvm_utility(${target} ${ARGN})
|
||||
set(LLVM_LINK_COMPONENTS ${${target}_OLD_LLVM_LINK_COMPONENTS})
|
||||
|
||||
# For Xcode builds, symlink bin/<target> to bin/<Config>/<target> so that
|
||||
# a separately-configured Clang project can still find llvm-tblgen.
|
||||
if (XCODE)
|
||||
add_custom_target(${target}-top ALL
|
||||
${CMAKE_COMMAND} -E create_symlink
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}${CMAKE_EXECUTABLE_SUFFIX}
|
||||
DEPENDS ${target})
|
||||
endif ()
|
||||
|
||||
set(${project}_TABLEGEN "${target}" CACHE
|
||||
STRING "Native TableGen executable. Saves building one when cross-compiling.")
|
||||
|
||||
@ -117,7 +128,7 @@ macro(add_tablegen target project)
|
||||
endif()
|
||||
|
||||
if( MINGW )
|
||||
target_link_libraries(${target} imagehlp psapi)
|
||||
target_link_libraries(${target} imagehlp psapi shell32)
|
||||
if(CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS -Wl,--stack,16777216)
|
||||
endif(CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
@ -126,5 +137,7 @@ macro(add_tablegen target project)
|
||||
target_link_libraries(${target} pthread)
|
||||
endif()
|
||||
|
||||
install(TARGETS ${target} RUNTIME DESTINATION bin)
|
||||
if (${project} STREQUAL LLVM AND NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
install(TARGETS ${target} RUNTIME DESTINATION bin)
|
||||
endif()
|
||||
endmacro()
|
||||
|
BIN
cmake/nsis_logo.bmp
Normal file
BIN
cmake/nsis_logo.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
@ -11,8 +11,15 @@
|
||||
# make <target>
|
||||
|
||||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
SET(CMAKE_C_COMPILER ${CMAKE_BINARY_DIR}/../bin/clang)
|
||||
SET(CMAKE_CXX_COMPILER ${CMAKE_BINARY_DIR}/../bin/clang++)
|
||||
|
||||
IF(NOT CMAKE_C_COMPILER)
|
||||
SET(CMAKE_C_COMPILER ${CMAKE_BINARY_DIR}/../bin/clang)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT CMAKE_CXX_COMPILER)
|
||||
SET(CMAKE_CXX_COMPILER ${CMAKE_BINARY_DIR}/../bin/clang++)
|
||||
ENDIF()
|
||||
|
||||
SET(ANDROID "1" CACHE STRING "ANDROID" FORCE)
|
||||
|
||||
SET(ANDROID_COMMON_FLAGS "-target arm-linux-androideabi --sysroot=${LLVM_ANDROID_TOOLCHAIN_DIR}/sysroot -B${LLVM_ANDROID_TOOLCHAIN_DIR} -mllvm -arm-enable-ehabi")
|
||||
|
@ -211,7 +211,7 @@ Notes for code generation
|
||||
never stored. A normal load or store instruction is usually sufficient, but
|
||||
note that an unordered load or store cannot be split into multiple
|
||||
instructions (or an instruction which does multiple memory operations, like
|
||||
``LDRD`` on ARM).
|
||||
``LDRD`` on ARM without LPAE, or not naturally-aligned ``LDRD`` on LPAE ARM).
|
||||
|
||||
Monotonic
|
||||
---------
|
||||
|
@ -718,7 +718,7 @@ global variable. The operand fields are:
|
||||
MODULE_CODE_FUNCTION Record
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc]``
|
||||
``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prefix]``
|
||||
|
||||
The ``FUNCTION`` record (code 8) marks the declaration or definition of a
|
||||
function. The operand fields are:
|
||||
@ -757,6 +757,9 @@ function. The operand fields are:
|
||||
* *unnamed_addr*: If present and non-zero, indicates that the function has
|
||||
``unnamed_addr``
|
||||
|
||||
* *prefix*: If non-zero, the value index of the prefix data for this function,
|
||||
plus 1.
|
||||
|
||||
MODULE_CODE_ALIAS Record
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -87,7 +87,7 @@ names are case-sensitive. Example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cmake -G "Visual Studio 9 2008" path/to/llvm/source/root
|
||||
$ cmake -G "Visual Studio 10" path/to/llvm/source/root
|
||||
|
||||
For a given development platform there can be more than one adequate
|
||||
generator. If you use Visual Studio "NMake Makefiles" is a generator you can use
|
||||
@ -275,6 +275,11 @@ LLVM-specific variables
|
||||
Build with zlib to support compression/uncompression in LLVM tools.
|
||||
Defaults to ON.
|
||||
|
||||
**LLVM_USE_SANITIZER**:STRING
|
||||
Define the sanitizer used to build LLVM binaries and tests. Possible values
|
||||
are ``Address``, ``Memory`` and ``MemoryWithOrigins``. Defaults to empty
|
||||
string.
|
||||
|
||||
Executing the test suite
|
||||
========================
|
||||
|
||||
@ -417,6 +422,5 @@ Microsoft Visual C++
|
||||
|
||||
**LLVM_COMPILER_JOBS**:STRING
|
||||
Specifies the maximum number of parallell compiler jobs to use per project
|
||||
when building with msbuild or Visual Studio. Only supported for Visual Studio
|
||||
2008 and Visual Studio 2010 CMake generators. 0 means use all
|
||||
processors. Default is 0.
|
||||
when building with msbuild or Visual Studio. Only supported for the Visual
|
||||
Studio 2010 CMake generator. 0 means use all processors. Default is 0.
|
||||
|
51
docs/CMakeLists.txt
Normal file
51
docs/CMakeLists.txt
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
if (DOXYGEN_FOUND)
|
||||
if (LLVM_ENABLE_DOXYGEN)
|
||||
set(abs_top_srcdir ${LLVM_MAIN_SRC_DIR})
|
||||
set(abs_top_builddir ${LLVM_BINARY_DIR})
|
||||
|
||||
if (HAVE_DOT)
|
||||
set(DOT ${LLVM_PATH_DOT})
|
||||
endif()
|
||||
|
||||
if (LLVM_DOXYGEN_EXTERNAL_SEARCH)
|
||||
set(enable_searchengine "YES")
|
||||
set(searchengine_url "${LLVM_DOXYGEN_SEARCHENGINE_URL}")
|
||||
set(enable_server_based_search "YES")
|
||||
set(enable_external_search "YES")
|
||||
set(extra_search_mappings "${LLVM_DOXYGEN_SEARCH_MAPPINGS}")
|
||||
else()
|
||||
set(enable_searchengine "NO")
|
||||
set(searchengine_url "")
|
||||
set(enable_server_based_search "NO")
|
||||
set(enable_external_search "NO")
|
||||
set(extra_search_mappings "")
|
||||
endif()
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxygen.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg @ONLY)
|
||||
|
||||
set(abs_top_srcdir)
|
||||
set(abs_top_builddir)
|
||||
set(DOT)
|
||||
set(enable_searchengine)
|
||||
set(searchengine_url)
|
||||
set(enable_server_based_search)
|
||||
set(enable_external_search)
|
||||
set(extra_search_mappings)
|
||||
|
||||
add_custom_target(doxygen-llvm
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating llvm doxygen documentation." VERBATIM)
|
||||
|
||||
if (LLVM_BUILD_DOCS)
|
||||
add_dependencies(doxygen doxygen-llvm)
|
||||
endif()
|
||||
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html
|
||||
DESTINATION docs/html)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
@ -636,6 +636,18 @@ file (MCObjectStreamer). MCAsmStreamer is a straight-forward implementation
|
||||
that prints out a directive for each method (e.g. ``EmitValue -> .byte``), but
|
||||
MCObjectStreamer implements a full assembler.
|
||||
|
||||
For target specific directives, the MCStreamer has a MCTargetStreamer instance.
|
||||
Each target that needs it defines a class that inherits from it and is a lot
|
||||
like MCStreamer itself: It has one method per directive and two classes that
|
||||
inherit from it, a target object streamer and a target asm streamer. The target
|
||||
asm streamer just prints it (``emitFnStart -> .fnstrart``), and the object
|
||||
streamer implement the assembler logic for it.
|
||||
|
||||
To make llvm use these classes, the target initialization must call
|
||||
TargetRegistry::RegisterAsmStreamer and TargetRegistry::RegisterMCObjectStreamer
|
||||
passing callbacks that allocate the corresponding target streamer and pass it
|
||||
to createAsmStreamer or to the appropriate object streamer constructor.
|
||||
|
||||
The ``MCContext`` class
|
||||
-----------------------
|
||||
|
||||
@ -1614,7 +1626,7 @@ Implementing a Native Assembler
|
||||
===============================
|
||||
|
||||
Though you're probably reading this because you want to write or maintain a
|
||||
compiler backend, LLVM also fully supports building a native assemblers too.
|
||||
compiler backend, LLVM also fully supports building a native assembler.
|
||||
We've tried hard to automate the generation of the assembler from the .td files
|
||||
(in particular the instruction syntax and encodings), which means that a large
|
||||
part of the manual and repetitive data entry can be factored and shared with the
|
||||
@ -1788,7 +1800,6 @@ Here is the table:
|
||||
:raw-html:`<th>Feature</th>`
|
||||
:raw-html:`<th>ARM</th>`
|
||||
:raw-html:`<th>Hexagon</th>`
|
||||
:raw-html:`<th>MBlaze</th>`
|
||||
:raw-html:`<th>MSP430</th>`
|
||||
:raw-html:`<th>Mips</th>`
|
||||
:raw-html:`<th>NVPTX</th>`
|
||||
@ -1803,7 +1814,6 @@ Here is the table:
|
||||
:raw-html:`<td><a href="#feat_reliable">is generally reliable</a></td>`
|
||||
:raw-html:`<td class="yes"></td> <!-- ARM -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
|
||||
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
|
||||
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- Mips -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- NVPTX -->`
|
||||
@ -1818,7 +1828,6 @@ Here is the table:
|
||||
:raw-html:`<td><a href="#feat_asmparser">assembly parser</a></td>`
|
||||
:raw-html:`<td class="no"></td> <!-- ARM -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
|
||||
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Mips -->`
|
||||
:raw-html:`<td class="no"></td> <!-- NVPTX -->`
|
||||
@ -1833,12 +1842,11 @@ Here is the table:
|
||||
:raw-html:`<td><a href="#feat_disassembler">disassembler</a></td>`
|
||||
:raw-html:`<td class="yes"></td> <!-- ARM -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
|
||||
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Mips -->`
|
||||
:raw-html:`<td class="na"></td> <!-- NVPTX -->`
|
||||
:raw-html:`<td class="no"></td> <!-- PowerPC -->`
|
||||
:raw-html:`<td class="no"></td> <!-- SystemZ -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- SystemZ -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Sparc -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- X86 -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- XCore -->`
|
||||
@ -1848,7 +1856,6 @@ Here is the table:
|
||||
:raw-html:`<td><a href="#feat_inlineasm">inline asm</a></td>`
|
||||
:raw-html:`<td class="yes"></td> <!-- ARM -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
|
||||
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Mips -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- NVPTX -->`
|
||||
@ -1863,7 +1870,6 @@ Here is the table:
|
||||
:raw-html:`<td><a href="#feat_jit">jit</a></td>`
|
||||
:raw-html:`<td class="partial"><a href="#feat_jit_arm">*</a></td> <!-- ARM -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
|
||||
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
|
||||
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- Mips -->`
|
||||
:raw-html:`<td class="na"></td> <!-- NVPTX -->`
|
||||
@ -1878,7 +1884,6 @@ Here is the table:
|
||||
:raw-html:`<td><a href="#feat_objectwrite">.o file writing</a></td>`
|
||||
:raw-html:`<td class="no"></td> <!-- ARM -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
|
||||
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Mips -->`
|
||||
:raw-html:`<td class="na"></td> <!-- NVPTX -->`
|
||||
@ -1893,7 +1898,6 @@ Here is the table:
|
||||
:raw-html:`<td><a hr:raw-html:`ef="#feat_tailcall">tail calls</a></td>`
|
||||
:raw-html:`<td class="yes"></td> <!-- ARM -->`
|
||||
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
|
||||
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
|
||||
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Mips -->`
|
||||
:raw-html:`<td class="no"></td> <!-- NVPTX -->`
|
||||
@ -1908,7 +1912,6 @@ Here is the table:
|
||||
:raw-html:`<td><a href="#feat_segstacks">segmented stacks</a></td>`
|
||||
:raw-html:`<td class="no"></td> <!-- ARM -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
|
||||
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
|
||||
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
|
||||
:raw-html:`<td class="no"></td> <!-- Mips -->`
|
||||
:raw-html:`<td class="no"></td> <!-- NVPTX -->`
|
||||
|
@ -796,7 +796,9 @@ In general, names should be in camel case (e.g. ``TextFileReader`` and
|
||||
|
||||
As an exception, classes that mimic STL classes can have member names in STL's
|
||||
style of lower-case words separated by underscores (e.g. ``begin()``,
|
||||
``push_back()``, and ``empty()``).
|
||||
``push_back()``, and ``empty()``). Classes that provide multiple
|
||||
iterators should add a singular prefix to ``begin()`` and ``end()``
|
||||
(e.g. ``global_begin()`` and ``use_begin()``).
|
||||
|
||||
Here are some examples of good and bad names:
|
||||
|
||||
|
@ -18,7 +18,8 @@ using :program:`grep`, but it is optimized for matching multiple different
|
||||
inputs in one file in a specific order.
|
||||
|
||||
The ``match-filename`` file specifies the file that contains the patterns to
|
||||
match. The file to verify is always read from standard input.
|
||||
match. The file to verify is read from standard input unless the
|
||||
:option:`--input-file` option is used.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
@ -29,11 +30,13 @@ OPTIONS
|
||||
|
||||
.. option:: --check-prefix prefix
|
||||
|
||||
FileCheck searches the contents of ``match-filename`` for patterns to match.
|
||||
By default, these patterns are prefixed with "``CHECK:``". If you'd like to
|
||||
use a different prefix (e.g. because the same input file is checking multiple
|
||||
different tool or options), the :option:`--check-prefix` argument allows you
|
||||
to specify a specific prefix to match.
|
||||
FileCheck searches the contents of ``match-filename`` for patterns to
|
||||
match. By default, these patterns are prefixed with "``CHECK:``".
|
||||
If you'd like to use a different prefix (e.g. because the same input
|
||||
file is checking multiple different tool or options), the
|
||||
:option:`--check-prefix` argument allows you to specify one or more
|
||||
prefixes to match. Multiple prefixes are useful for tests which might
|
||||
change for different run options, but most lines remain the same.
|
||||
|
||||
.. option:: --input-file filename
|
||||
|
||||
@ -44,7 +47,7 @@ OPTIONS
|
||||
By default, FileCheck canonicalizes input horizontal whitespace (spaces and
|
||||
tabs) which causes it to ignore these differences (a space will match a tab).
|
||||
The :option:`--strict-whitespace` argument disables this behavior. End-of-line
|
||||
sequences are canonicalized to UNIX-style '\n' in all modes.
|
||||
sequences are canonicalized to UNIX-style ``\n`` in all modes.
|
||||
|
||||
.. option:: -version
|
||||
|
||||
@ -194,6 +197,134 @@ can be used:
|
||||
; CHECK: ret i8
|
||||
}
|
||||
|
||||
The "CHECK-DAG:" directive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If it's necessary to match strings that don't occur in a strictly sequential
|
||||
order, "``CHECK-DAG:``" could be used to verify them between two matches (or
|
||||
before the first match, or after the last match). For example, clang emits
|
||||
vtable globals in reverse order. Using ``CHECK-DAG:``, we can keep the checks
|
||||
in the natural order:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
struct Foo { virtual void method(); };
|
||||
Foo f; // emit vtable
|
||||
// CHECK-DAG: @_ZTV3Foo =
|
||||
|
||||
struct Bar { virtual void method(); };
|
||||
Bar b;
|
||||
// CHECK-DAG: @_ZTV3Bar =
|
||||
|
||||
``CHECK-NOT:`` directives could be mixed with ``CHECK-DAG:`` directives to
|
||||
exclude strings between the surrounding ``CHECK-DAG:`` directives. As a result,
|
||||
the surrounding ``CHECK-DAG:`` directives cannot be reordered, i.e. all
|
||||
occurrences matching ``CHECK-DAG:`` before ``CHECK-NOT:`` must not fall behind
|
||||
occurrences matching ``CHECK-DAG:`` after ``CHECK-NOT:``. For example,
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
; CHECK-DAG: BEFORE
|
||||
; CHECK-NOT: NOT
|
||||
; CHECK-DAG: AFTER
|
||||
|
||||
This case will reject input strings where ``BEFORE`` occurs after ``AFTER``.
|
||||
|
||||
With captured variables, ``CHECK-DAG:`` is able to match valid topological
|
||||
orderings of a DAG with edges from the definition of a variable to its use.
|
||||
It's useful, e.g., when your test cases need to match different output
|
||||
sequences from the instruction scheduler. For example,
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
; CHECK-DAG: add [[REG1:r[0-9]+]], r1, r2
|
||||
; CHECK-DAG: add [[REG2:r[0-9]+]], r3, r4
|
||||
; CHECK: mul r5, [[REG1]], [[REG2]]
|
||||
|
||||
In this case, any order of that two ``add`` instructions will be allowed.
|
||||
|
||||
If you are defining `and` using variables in the same ``CHECK-DAG:`` block,
|
||||
be aware that the definition rule can match `after` its use.
|
||||
|
||||
So, for instance, the code below will pass:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
; CHECK-DAG: vmov.32 [[REG2:d[0-9]+]][0]
|
||||
; CHECK-DAG: vmov.32 [[REG2]][1]
|
||||
vmov.32 d0[1]
|
||||
vmov.32 d0[0]
|
||||
|
||||
While this other code, will not:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
; CHECK-DAG: vmov.32 [[REG2:d[0-9]+]][0]
|
||||
; CHECK-DAG: vmov.32 [[REG2]][1]
|
||||
vmov.32 d1[1]
|
||||
vmov.32 d0[0]
|
||||
|
||||
While this can be very useful, it's also dangerous, because in the case of
|
||||
register sequence, you must have a strong order (read before write, copy before
|
||||
use, etc). If the definition your test is looking for doesn't match (because
|
||||
of a bug in the compiler), it may match further away from the use, and mask
|
||||
real bugs away.
|
||||
|
||||
In those cases, to enforce the order, use a non-DAG directive between DAG-blocks.
|
||||
|
||||
The "CHECK-LABEL:" directive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes in a file containing multiple tests divided into logical blocks, one
|
||||
or more ``CHECK:`` directives may inadvertently succeed by matching lines in a
|
||||
later block. While an error will usually eventually be generated, the check
|
||||
flagged as causing the error may not actually bear any relationship to the
|
||||
actual source of the problem.
|
||||
|
||||
In order to produce better error messages in these cases, the "``CHECK-LABEL:``"
|
||||
directive can be used. It is treated identically to a normal ``CHECK``
|
||||
directive except that FileCheck makes an additional assumption that a line
|
||||
matched by the directive cannot also be matched by any other check present in
|
||||
``match-filename``; this is intended to be used for lines containing labels or
|
||||
other unique identifiers. Conceptually, the presence of ``CHECK-LABEL`` divides
|
||||
the input stream into separate blocks, each of which is processed independently,
|
||||
preventing a ``CHECK:`` directive in one block matching a line in another block.
|
||||
For example,
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define %struct.C* @C_ctor_base(%struct.C* %this, i32 %x) {
|
||||
entry:
|
||||
; CHECK-LABEL: C_ctor_base:
|
||||
; CHECK: mov [[SAVETHIS:r[0-9]+]], r0
|
||||
; CHECK: bl A_ctor_base
|
||||
; CHECK: mov r0, [[SAVETHIS]]
|
||||
%0 = bitcast %struct.C* %this to %struct.A*
|
||||
%call = tail call %struct.A* @A_ctor_base(%struct.A* %0)
|
||||
%1 = bitcast %struct.C* %this to %struct.B*
|
||||
%call2 = tail call %struct.B* @B_ctor_base(%struct.B* %1, i32 %x)
|
||||
ret %struct.C* %this
|
||||
}
|
||||
|
||||
define %struct.D* @D_ctor_base(%struct.D* %this, i32 %x) {
|
||||
entry:
|
||||
; CHECK-LABEL: D_ctor_base:
|
||||
|
||||
The use of ``CHECK-LABEL:`` directives in this case ensures that the three
|
||||
``CHECK:`` directives only accept lines corresponding to the body of the
|
||||
``@C_ctor_base`` function, even if the patterns match lines found later in
|
||||
the file. Furthermore, if one of these three ``CHECK:`` directives fail,
|
||||
FileCheck will recover by continuing to the next block, allowing multiple test
|
||||
failures to be detected in a single invocation.
|
||||
|
||||
There is no requirement that ``CHECK-LABEL:`` directives contain strings that
|
||||
correspond to actual syntactic labels in a source or output language: they must
|
||||
simply uniquely match a single line in the file being verified.
|
||||
|
||||
``CHECK-LABEL:`` directives cannot contain variable definitions or uses.
|
||||
|
||||
FileCheck Pattern Matching Syntax
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -21,7 +21,6 @@ Basic Commands
|
||||
lli
|
||||
llvm-link
|
||||
llvm-ar
|
||||
llvm-ranlib
|
||||
llvm-nm
|
||||
llvm-prof
|
||||
llvm-config
|
||||
|
@ -149,12 +149,11 @@ ADDITIONAL OPTIONS
|
||||
|
||||
.. option:: --show-suites
|
||||
|
||||
List the discovered test suites as part of the standard output.
|
||||
List the discovered test suites and exit.
|
||||
|
||||
.. option:: --repeat=N
|
||||
.. option:: --show-tests
|
||||
|
||||
Run each test ``N`` times. Currently this is primarily useful for timing
|
||||
tests, other results are not collated in any reasonable fashion.
|
||||
List all of the the discovered tests and exit.
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
@ -283,7 +282,7 @@ executed, two important global variables are predefined:
|
||||
discover and run tests in the test suite. Generally this will be a builtin test
|
||||
format available from the *lit.formats* module.
|
||||
|
||||
**test_src_root** The filesystem path to the test suite root. For out-of-dir
|
||||
**test_source_root** The filesystem path to the test suite root. For out-of-dir
|
||||
builds this is the directory that will be scanned for tests.
|
||||
|
||||
**test_exec_root** For out-of-dir builds, the path to the test suite root inside
|
||||
@ -316,11 +315,15 @@ executed, two important global variables are predefined:
|
||||
*on_clone* function will generally modify), and (3) the test path to the new
|
||||
directory being scanned.
|
||||
|
||||
**pipefail** Normally a test using a shell pipe fails if any of the commands
|
||||
on the pipe fail. If this is not desired, setting this variable to false
|
||||
makes the test fail only if the last command in the pipe fails.
|
||||
|
||||
TEST DISCOVERY
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Once test suites are located, :program:`lit` recursively traverses the source
|
||||
directory (following *test_src_root*) looking for tests. When :program:`lit`
|
||||
directory (following *test_source_root*) looking for tests. When :program:`lit`
|
||||
enters a sub-directory, it first checks to see if a nested test suite is
|
||||
defined in that directory. If so, it loads that test suite recursively,
|
||||
otherwise it instantiates a local test config for the directory (see
|
||||
|
@ -141,24 +141,24 @@ Tuning/Configuration Options
|
||||
|
||||
.. option:: --regalloc=<allocator>
|
||||
|
||||
Specify the register allocator to use. The default ``allocator`` is *local*.
|
||||
Specify the register allocator to use.
|
||||
Valid register allocators are:
|
||||
|
||||
*simple*
|
||||
*basic*
|
||||
|
||||
Very simple "always spill" register allocator
|
||||
Basic register allocator.
|
||||
|
||||
*local*
|
||||
*fast*
|
||||
|
||||
Local register allocator
|
||||
Fast register allocator. It is the default for unoptimized code.
|
||||
|
||||
*linearscan*
|
||||
*greedy*
|
||||
|
||||
Linear scan global register allocator
|
||||
Greedy register allocator. It is the default for optimized code.
|
||||
|
||||
*iterativescan*
|
||||
*pbqp*
|
||||
|
||||
Iterative scan global register allocator
|
||||
Register allocator based on 'Partitioned Boolean Quadratic Programming'.
|
||||
|
||||
.. option:: --spiller=<spiller>
|
||||
|
||||
|
@ -21,64 +21,24 @@ LLVM program. However, the archive can contain any kind of file. By default,
|
||||
only the symbol table needs to be consulted, not each individual file member
|
||||
of the archive.
|
||||
|
||||
The **llvm-ar** command can be used to *read* both SVR4 and BSD style archive
|
||||
files. However, it cannot be used to write them. While the **llvm-ar** command
|
||||
produces files that are *almost* identical to the format used by other ``ar``
|
||||
implementations, it has two significant departures in order to make the
|
||||
archive appropriate for LLVM. The first departure is that **llvm-ar** only
|
||||
uses BSD4.4 style long path names (stored immediately after the header) and
|
||||
never contains a string table for long names. The second departure is that the
|
||||
symbol table is formated for efficient construction of an in-memory data
|
||||
structure that permits rapid (red-black tree) lookups. Consequently, archives
|
||||
produced with **llvm-ar** usually won't be readable or editable with any
|
||||
``ar`` implementation or useful for linking. Using the ``f`` modifier to flatten
|
||||
file names will make the archive readable by other ``ar`` implementations
|
||||
but not for linking because the symbol table format for LLVM is unique. If an
|
||||
The **llvm-ar** command can be used to *read* SVR4, GNU and BSD style archive
|
||||
files. However, right now it can only write in the GNU format. If an
|
||||
SVR4 or BSD style archive is used with the ``r`` (replace) or ``q`` (quick
|
||||
update) operations, the archive will be reconstructed in LLVM format. This
|
||||
means that the string table will be dropped (in deference to BSD 4.4 long names)
|
||||
and an LLVM symbol table will be added (by default). The system symbol table
|
||||
will be retained.
|
||||
update) operations, the archive will be reconstructed in GNU format.
|
||||
|
||||
Here's where **llvm-ar** departs from previous ``ar`` implementations:
|
||||
|
||||
|
||||
*Symbol Table*
|
||||
|
||||
Since **llvm-ar** is intended to archive bitcode files, the symbol table
|
||||
won't make much sense to anything but LLVM. Consequently, the symbol table's
|
||||
format has been simplified. It consists simply of a sequence of pairs
|
||||
of a file member index number as an LSB 4byte integer and a null-terminated
|
||||
string.
|
||||
|
||||
Since **llvm-ar** supports bitcode files. The symbol table it creates
|
||||
is in GNU format and includes both native and bitcode files.
|
||||
|
||||
|
||||
*Long Paths*
|
||||
|
||||
Some ``ar`` implementations (SVR4) use a separate file member to record long
|
||||
path names (> 15 characters). **llvm-ar** takes the BSD 4.4 and Mac OS X
|
||||
approach which is to simply store the full path name immediately preceding
|
||||
the data for the file. The path name is null terminated and may contain the
|
||||
slash (/) character.
|
||||
|
||||
|
||||
|
||||
*Directory Recursion*
|
||||
|
||||
Most ``ar`` implementations do not recurse through directories but simply
|
||||
ignore directories if they are presented to the program in the *files*
|
||||
option. **llvm-ar**, however, can recurse through directory structures and
|
||||
add all the files under a directory, if requested.
|
||||
|
||||
|
||||
|
||||
*TOC Verbose Output*
|
||||
|
||||
When **llvm-ar** prints out the verbose table of contents (``tv`` option), it
|
||||
precedes the usual output with a character indicating the basic kind of
|
||||
content in the file. A blank means the file is a regular file. A 'B' means
|
||||
the file is an LLVM bitcode file. An 'S' means the file is the symbol table.
|
||||
|
||||
Currently **llvm-ar** can read GNU and BSD long file names, but only writes
|
||||
archives with the GNU format.
|
||||
|
||||
|
||||
|
||||
@ -124,20 +84,19 @@ m[abi]
|
||||
|
||||
|
||||
|
||||
p[k]
|
||||
p
|
||||
|
||||
Print files to the standard output. The *k* modifier applies to this
|
||||
operation. This operation simply prints the *files* indicated to the
|
||||
standard output. If no *files* are specified, the entire archive is printed.
|
||||
Printing bitcode files is ill-advised as they might confuse your terminal
|
||||
settings. The *p* operation never modifies the archive.
|
||||
Print files to the standard output. This operation simply prints the
|
||||
*files* indicated to the standard output. If no *files* are
|
||||
specified, the entire archive is printed. Printing bitcode files is
|
||||
ill-advised as they might confuse your terminal settings. The *p*
|
||||
operation never modifies the archive.
|
||||
|
||||
|
||||
|
||||
q[Rf]
|
||||
q
|
||||
|
||||
Quickly append files to the end of the archive. The *R*, and *f*
|
||||
modifiers apply to this operation. This operation quickly adds the
|
||||
Quickly append files to the end of the archive. This operation quickly adds the
|
||||
*files* to the archive without checking for duplicates that should be
|
||||
removed first. If no *files* are specified, the archive is not modified.
|
||||
Because of the way that **llvm-ar** constructs the archive file, its dubious
|
||||
@ -145,9 +104,9 @@ q[Rf]
|
||||
|
||||
|
||||
|
||||
r[Rabfu]
|
||||
r[abu]
|
||||
|
||||
Replace or insert file members. The *R*, *a*, *b*, *f*, and *u*
|
||||
Replace or insert file members. The *a*, *b*, and *u*
|
||||
modifiers apply to this operation. This operation will replace existing
|
||||
*files* or insert them at the end of the archive if they do not exist. If no
|
||||
*files* are specified, the archive is not modified.
|
||||
@ -201,37 +160,12 @@ section (above) to determine which modifiers are applicable to which operations.
|
||||
|
||||
|
||||
|
||||
[f]
|
||||
|
||||
Normally, **llvm-ar** stores the full path name to a file as presented to it on
|
||||
the command line. With this option, truncated (15 characters max) names are
|
||||
used. This ensures name compatibility with older versions of ``ar`` but may also
|
||||
thwart correct extraction of the files (duplicates may overwrite). If used with
|
||||
the *R* option, the directory recursion will be performed but the file names
|
||||
will all be flattened to simple file names.
|
||||
|
||||
|
||||
|
||||
[i]
|
||||
|
||||
A synonym for the *b* option.
|
||||
|
||||
|
||||
|
||||
[k]
|
||||
|
||||
Normally, **llvm-ar** will not print the contents of bitcode files when the
|
||||
*p* operation is used. This modifier defeats the default and allows the
|
||||
bitcode members to be printed.
|
||||
|
||||
|
||||
|
||||
[N]
|
||||
|
||||
This option is ignored by **llvm-ar** but provided for compatibility.
|
||||
|
||||
|
||||
|
||||
[o]
|
||||
|
||||
When extracting files, this option will cause **llvm-ar** to preserve the
|
||||
@ -239,22 +173,6 @@ section (above) to determine which modifiers are applicable to which operations.
|
||||
|
||||
|
||||
|
||||
[P]
|
||||
|
||||
use full path names when matching
|
||||
|
||||
|
||||
|
||||
[R]
|
||||
|
||||
This modifier instructions the *r* option to recursively process directories.
|
||||
Without *R*, directories are ignored and only those *files* that refer to
|
||||
files will be added to the archive. When *R* is used, any directories specified
|
||||
with *files* will be scanned (recursively) to find files to be added to the
|
||||
archive. Any file whose name begins with a dot will not be added.
|
||||
|
||||
|
||||
|
||||
[u]
|
||||
|
||||
When replacing existing files in the archive, only replace those files that have
|
||||
@ -283,8 +201,7 @@ The modifiers below may be applied to any operation.
|
||||
This modifier requests that an archive index (or symbol table) be added to the
|
||||
archive. This is the default mode of operation. The symbol table will contain
|
||||
all the externally visible functions and global variables defined by all the
|
||||
bitcode files in the archive. Using this modifier is more efficient that using
|
||||
llvm-ranlib|llvm-ranlib which also creates the symbol table.
|
||||
bitcode files in the archive.
|
||||
|
||||
|
||||
|
||||
@ -401,14 +318,6 @@ fmag - char[2]
|
||||
utility in identifying archive files that have been corrupted.
|
||||
|
||||
|
||||
|
||||
The LLVM symbol table has the special name "#_LLVM_SYM_TAB_#". It is presumed
|
||||
that no regular archive member file will want this name. The LLVM symbol table
|
||||
is simply composed of a sequence of triplets: byte offset, length of symbol,
|
||||
and the symbol itself. Symbols are not null or newline terminated. Here are
|
||||
the details on each of these items:
|
||||
|
||||
|
||||
offset - vbr encoded 32-bit integer
|
||||
|
||||
The offset item provides the offset into the archive file where the bitcode
|
||||
@ -455,4 +364,4 @@ SEE ALSO
|
||||
--------
|
||||
|
||||
|
||||
llvm-ranlib|llvm-ranlib, ar(1)
|
||||
ar(1)
|
||||
|
@ -1,104 +1,79 @@
|
||||
llvm-extract - extract a function from an LLVM module
|
||||
=====================================================
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
|
||||
**llvm-extract** [*options*] **--func** *function-name* [*filename*]
|
||||
|
||||
:program:`llvm-extract` [*options*] **--func** *function-name* [*filename*]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
|
||||
The **llvm-extract** command takes the name of a function and extracts it from
|
||||
the specified LLVM bitcode file. It is primarily used as a debugging tool to
|
||||
reduce test cases from larger programs that are triggering a bug.
|
||||
The :program:`llvm-extract` command takes the name of a function and extracts
|
||||
it from the specified LLVM bitcode file. It is primarily used as a debugging
|
||||
tool to reduce test cases from larger programs that are triggering a bug.
|
||||
|
||||
In addition to extracting the bitcode of the specified function,
|
||||
**llvm-extract** will also remove unreachable global variables, prototypes, and
|
||||
unused types.
|
||||
|
||||
The **llvm-extract** command reads its input from standard input if filename is
|
||||
omitted or if filename is -. The output is always written to standard output,
|
||||
unless the **-o** option is specified (see below).
|
||||
:program:`llvm-extract` will also remove unreachable global variables,
|
||||
prototypes, and unused types.
|
||||
|
||||
The :program:`llvm-extract` command reads its input from standard input if
|
||||
filename is omitted or if filename is ``-``. The output is always written to
|
||||
standard output, unless the **-o** option is specified (see below).
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
|
||||
|
||||
**-f**
|
||||
|
||||
Enable binary output on terminals. Normally, **llvm-extract** will refuse to
|
||||
write raw bitcode output if the output stream is a terminal. With this option,
|
||||
**llvm-extract** will write raw bitcode regardless of the output device.
|
||||
|
||||
|
||||
Enable binary output on terminals. Normally, :program:`llvm-extract` will
|
||||
refuse to write raw bitcode output if the output stream is a terminal. With
|
||||
this option, :program:`llvm-extract` will write raw bitcode regardless of the
|
||||
output device.
|
||||
|
||||
**--func** *function-name*
|
||||
|
||||
Extract the function named *function-name* from the LLVM bitcode. May be
|
||||
Extract the function named *function-name* from the LLVM bitcode. May be
|
||||
specified multiple times to extract multiple functions at once.
|
||||
|
||||
|
||||
|
||||
**--rfunc** *function-regular-expr*
|
||||
|
||||
Extract the function(s) matching *function-regular-expr* from the LLVM bitcode.
|
||||
All functions matching the regular expression will be extracted. May be
|
||||
specified multiple times.
|
||||
|
||||
|
||||
|
||||
**--glob** *global-name*
|
||||
|
||||
Extract the global variable named *global-name* from the LLVM bitcode. May be
|
||||
Extract the global variable named *global-name* from the LLVM bitcode. May be
|
||||
specified multiple times to extract multiple global variables at once.
|
||||
|
||||
|
||||
|
||||
**--rglob** *glob-regular-expr*
|
||||
|
||||
Extract the global variable(s) matching *global-regular-expr* from the LLVM
|
||||
bitcode. All global variables matching the regular expression will be extracted.
|
||||
May be specified multiple times.
|
||||
|
||||
|
||||
bitcode. All global variables matching the regular expression will be
|
||||
extracted. May be specified multiple times.
|
||||
|
||||
**-help**
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
|
||||
|
||||
**-o** *filename*
|
||||
|
||||
Specify the output filename. If filename is "-" (the default), then
|
||||
**llvm-extract** sends its output to standard output.
|
||||
|
||||
|
||||
:program:`llvm-extract` sends its output to standard output.
|
||||
|
||||
**-S**
|
||||
|
||||
Write output in LLVM intermediate language (instead of bitcode).
|
||||
|
||||
|
||||
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
|
||||
|
||||
If **llvm-extract** succeeds, it will exit with 0. Otherwise, if an error
|
||||
If :program:`llvm-extract` succeeds, it will exit with 0. Otherwise, if an error
|
||||
occurs, it will exit with a non-zero value.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
bugpoint
|
||||
|
||||
bugpoint|bugpoint
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user