Vendor import of llvm trunk r238337:
https://llvm.org/svn/llvm-project/llvm/trunk@238337
This commit is contained in:
parent
f03b5bed27
commit
5a5ac124e1
.gitignoreCMakeLists.txtCODE_OWNERS.TXTLICENSE.TXTMakefile.config.inMakefile.rulesREADME.txt
autoconf
bindings
go/llvm
DIBuilderBindings.cppDIBuilderBindings.hIRBindings.cppInstrumentationBindings.cppInstrumentationBindings.hSupportBindings.cppdibuilder.golinker.gotransforms_instrumentation.go
ocaml
cmake
config-ix.cmake
configuremodules
AddLLVM.cmakeCheckAtomic.cmakeCrossCompile.cmakeHandleLLVMOptions.cmakeHandleLLVMStdlib.cmakeLLVM-Config.cmakeLLVMConfig.cmake.inLLVMProcessSources.cmakeMakefileTableGen.cmake
platforms
docs
BitCodeFormat.rstBitSets.rstBranchWeightMetadata.rstBugpoint.rstBuildingLLVMWithAutotools.rstCMake.rstCodeGenerator.rstCodingStandards.rst
CommandGuide
CompilerWriterInfo.rstDeveloperPolicy.rstExceptionHandling.rstExtendingLLVM.rstExtensions.rstFAQ.rstFrontend
GarbageCollection.rstGetElementPtr.rstGettingStarted.rstGettingStartedVS.rstHowToBuildOnARM.rstHowToSetUpLLVMStyleRTTI.rstLangRef.rstLexicon.rstLibFuzzer.rstMakefileMergeFunctions.rstPasses.rstPhabricator.rstProgrammersManual.rstR600Usage.rstReleaseNotes.rstSourceLevelDebugging.rstStackMaps.rstStatepoints.rstTestingGuide.rstVectorizers.rstWritingAnLLVMPass.rstYamlIO.rstconf.pydoxygen.cfg.indoxygen.cssdoxygen.footerdoxygen.headerindex.rsttutorial
examples
BrainF
ExceptionDemo
HowToUseJIT
Kaleidoscope
4
.gitignore
vendored
4
.gitignore
vendored
@ -16,7 +16,7 @@
|
||||
# Byte compiled python modules.
|
||||
*.pyc
|
||||
# vim swap files
|
||||
.*.swp
|
||||
.*.sw?
|
||||
.sw?
|
||||
#OS X specific files.
|
||||
.DS_store
|
||||
@ -37,7 +37,7 @@ cscope.files
|
||||
cscope.out
|
||||
autoconf/aclocal.m4
|
||||
autoconf/autom4te.cache
|
||||
compile_commands.json
|
||||
/compile_commands.json
|
||||
|
||||
#==============================================================================#
|
||||
# Directories to ignore (do not add trailing '/'s, they skip symlinks).
|
||||
|
@ -1,19 +1,23 @@
|
||||
# See docs/CMake.html for instructions about how to build LLVM with CMake.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.8)
|
||||
cmake_minimum_required(VERSION 2.8.12.2)
|
||||
|
||||
# FIXME: It may be removed when we use 2.8.12.
|
||||
if(CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
# Invalidate a couple of keywords.
|
||||
set(cmake_2_8_12_INTERFACE)
|
||||
set(cmake_2_8_12_PRIVATE)
|
||||
else()
|
||||
# Use ${cmake_2_8_12_KEYWORD} intead of KEYWORD in target_link_libraries().
|
||||
set(cmake_2_8_12_INTERFACE INTERFACE)
|
||||
set(cmake_2_8_12_PRIVATE PRIVATE)
|
||||
if(POLICY CMP0022)
|
||||
cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required
|
||||
endif()
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "No build type selected, default to Debug")
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0022)
|
||||
cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required
|
||||
endif()
|
||||
|
||||
if (POLICY CMP0051)
|
||||
# CMake 3.1 and higher include generator expressions of the form
|
||||
# $<TARGETLIB:obj> in the SOURCES property. These need to be
|
||||
# stripped everywhere that access the SOURCES property, so we just
|
||||
# defer to the OLD behavior of not including generator expressions
|
||||
# in the output for now.
|
||||
cmake_policy(SET CMP0051 OLD)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.1.20141117)
|
||||
@ -47,13 +51,17 @@ set(CMAKE_MODULE_PATH
|
||||
)
|
||||
|
||||
set(LLVM_VERSION_MAJOR 3)
|
||||
set(LLVM_VERSION_MINOR 6)
|
||||
set(LLVM_VERSION_PATCH 1)
|
||||
set(LLVM_VERSION_MINOR 7)
|
||||
set(LLVM_VERSION_PATCH 0)
|
||||
set(LLVM_VERSION_SUFFIX svn)
|
||||
|
||||
if (NOT PACKAGE_VERSION)
|
||||
set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
|
||||
set(PACKAGE_VERSION
|
||||
"${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX}")
|
||||
endif()
|
||||
|
||||
option(LLVM_INSTALL_UTILS "Include utility binaries in the 'install' target." OFF)
|
||||
|
||||
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)
|
||||
@ -85,6 +93,7 @@ set(CPACK_PACKAGE_VERSION_MINOR ${LLVM_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${LLVM_VERSION_PATCH})
|
||||
set(CPACK_PACKAGE_VERSION ${PACKAGE_VERSION})
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.TXT")
|
||||
set(CPACK_NSIS_COMPRESSOR "/SOLID lzma \r\n SetCompressorDictSize 32")
|
||||
if(WIN32 AND NOT UNIX)
|
||||
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "LLVM")
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\cmake\\\\nsis_logo.bmp")
|
||||
@ -96,6 +105,9 @@ if(WIN32 AND NOT UNIX)
|
||||
"ExecWait '$INSTDIR/tools/msbuild/install.bat'")
|
||||
set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
|
||||
"ExecWait '$INSTDIR/tools/msbuild/uninstall.bat'")
|
||||
if( CMAKE_CL_64 )
|
||||
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
|
||||
endif()
|
||||
endif()
|
||||
include(CPack)
|
||||
|
||||
@ -222,17 +234,11 @@ list(REMOVE_DUPLICATES LLVM_TARGETS_TO_BUILD)
|
||||
include(AddLLVMDefinitions)
|
||||
|
||||
option(LLVM_ENABLE_PIC "Build Position-Independent Code" ON)
|
||||
|
||||
# MSVC has a gazillion warnings with this.
|
||||
if( MSVC )
|
||||
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." OFF)
|
||||
else()
|
||||
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
|
||||
endif()
|
||||
|
||||
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
|
||||
option(LLVM_ENABLE_MODULES "Compile with C++ modules enabled." OFF)
|
||||
option(LLVM_ENABLE_CXX1Y "Compile with C++1y enabled." OFF)
|
||||
option(LLVM_ENABLE_LIBCXX "Use libc++ if available." OFF)
|
||||
option(LLVM_ENABLE_LIBCXXABI "Use libc++abi when using libc++." OFF)
|
||||
option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
|
||||
option(LLVM_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
|
||||
|
||||
@ -242,6 +248,9 @@ else()
|
||||
option(LLVM_ENABLE_ASSERTIONS "Enable assertions" ON)
|
||||
endif()
|
||||
|
||||
set(LLVM_ABI_BREAKING_CHECKS "WITH_ASSERTS" CACHE STRING
|
||||
"Enable abi-breaking checks. Can be WITH_ASSERTS, FORCE_ON or FORCE_OFF.")
|
||||
|
||||
option(LLVM_FORCE_USE_OLD_HOST_TOOLCHAIN
|
||||
"Set to ON to force using an old, unsupported host toolchain." OFF)
|
||||
|
||||
@ -325,11 +334,17 @@ option (LLVM_BUILD_EXTERNAL_COMPILER_RT
|
||||
"Build compiler-rt as an external project." OFF)
|
||||
|
||||
option(LLVM_BUILD_LLVM_DYLIB "Build libllvm dynamic library" OFF)
|
||||
option(LLVM_DYLIB_EXPORT_ALL "Export all symbols from libLLVM.dylib (default is C API only" OFF)
|
||||
option(LLVM_DISABLE_LLVM_DYLIB_ATEXIT "Disable llvm-shlib's atexit destructors." ON)
|
||||
if(LLVM_DISABLE_LLVM_DYLIB_ATEXIT)
|
||||
set(DISABLE_LLVM_DYLIB_ATEXIT 1)
|
||||
endif()
|
||||
|
||||
option(LLVM_OPTIMIZED_TABLEGEN "Force TableGen to be built with optimization" OFF)
|
||||
if(CMAKE_CROSSCOMPILING OR (LLVM_OPTIMIZED_TABLEGEN AND LLVM_ENABLE_ASSERTIONS))
|
||||
set(LLVM_USE_HOST_TOOLS ON)
|
||||
endif()
|
||||
|
||||
# All options referred to from HandleLLVMOptions have to be specified
|
||||
# BEFORE this include, otherwise options will not be correctly set on
|
||||
# first cmake run
|
||||
@ -516,9 +531,9 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
include_directories( ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR})
|
||||
|
||||
# when crosscompiling import the executable targets from a file
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
if(LLVM_USE_HOST_TOOLS)
|
||||
include(CrossCompile)
|
||||
endif(CMAKE_CROSSCOMPILING)
|
||||
endif(LLVM_USE_HOST_TOOLS)
|
||||
|
||||
if( ${CMAKE_SYSTEM_NAME} MATCHES FreeBSD )
|
||||
# On FreeBSD, /usr/local/* is not used by default. In order to build LLVM
|
||||
@ -532,7 +547,7 @@ if( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
|
||||
endif( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
|
||||
|
||||
# Make sure we don't get -rdynamic in every binary. For those that need it,
|
||||
# use set_target_properties(target PROPERTIES ENABLE_EXPORTS 1)
|
||||
# use export_executable_symbols(target).
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||
|
||||
include(AddLLVM)
|
||||
@ -627,6 +642,7 @@ add_subdirectory(cmake/modules)
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
install(DIRECTORY include/llvm include/llvm-c
|
||||
DESTINATION include
|
||||
COMPONENT llvm-headers
|
||||
FILES_MATCHING
|
||||
PATTERN "*.def"
|
||||
PATTERN "*.h"
|
||||
@ -638,6 +654,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
|
||||
install(DIRECTORY ${LLVM_INCLUDE_DIR}/llvm
|
||||
DESTINATION include
|
||||
COMPONENT llvm-headers
|
||||
FILES_MATCHING
|
||||
PATTERN "*.def"
|
||||
PATTERN "*.h"
|
||||
@ -648,4 +665,12 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
PATTERN "config.h" EXCLUDE
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_custom_target(installhdrs
|
||||
DEPENDS ${name}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=llvm-headers
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -49,6 +49,10 @@ N: Peter Collingbourne
|
||||
E: peter@pcc.me.uk
|
||||
D: llgo
|
||||
|
||||
N: Quentin Colombet
|
||||
E: qcolombet@apple.com
|
||||
D: Register allocators
|
||||
|
||||
N: Anshuman Dasgupta
|
||||
E: adasgupt@codeaurora.org
|
||||
D: Hexagon Backend
|
||||
@ -85,6 +89,10 @@ N: Lang Hames
|
||||
E: lhames@gmail.com
|
||||
D: MCJIT, RuntimeDyld and JIT event listeners
|
||||
|
||||
N: David Majnemer
|
||||
E: david.majnemer@gmail.com
|
||||
D: IR Constant Folder
|
||||
|
||||
N: Galina Kistanova
|
||||
E: gkistanova@gmail.com
|
||||
D: LLVM Buildbot
|
||||
@ -116,7 +124,7 @@ D: SampleProfile and related parts of ProfileData
|
||||
|
||||
N: Jakob Olesen
|
||||
E: stoklund@2pi.dk
|
||||
D: Register allocators and TableGen
|
||||
D: TableGen
|
||||
|
||||
N: Richard Osborne
|
||||
E: richard@xmos.com
|
||||
@ -126,6 +134,10 @@ N: Chad Rosier
|
||||
E: mcrosier@codeaurora.org
|
||||
D: Fast-Isel
|
||||
|
||||
N: Alex Rosenberg
|
||||
E: alexr@leftfield.org
|
||||
D: Sony PlayStation®4 support
|
||||
|
||||
N: Nadav Rotem
|
||||
E: nrotem@apple.com
|
||||
D: X86 Backend, Loop Vectorizer
|
||||
@ -146,10 +158,14 @@ N: Michael Spencer
|
||||
E: bigcheesegs@gmail.com
|
||||
D: Windows parts of Support, Object, ar, nm, objdump, ranlib, size
|
||||
|
||||
N: Alexei Starovoitov
|
||||
E: alexei.starovoitov@gmail.com
|
||||
D: BPF backend
|
||||
|
||||
N: Tom Stellard
|
||||
E: thomas.stellard@amd.com
|
||||
E: mesa-dev@lists.freedesktop.org
|
||||
D: Release manager for the 3.5 branch, R600 Backend, libclc
|
||||
D: Release manager for the 3.5 and 3.6 branches, R600 Backend, libclc
|
||||
|
||||
N: Evgeniy Stepanov
|
||||
E: eugenis@google.com
|
||||
@ -170,3 +186,7 @@ D: libLTO, IR Linker
|
||||
N: Peter Zotov
|
||||
E: whitequark@whitequark.org
|
||||
D: OCaml bindings
|
||||
|
||||
N: Andrey Churbanov
|
||||
E: andrey.churbanov@intel.com
|
||||
D: OpenMP runtime library
|
||||
|
@ -4,7 +4,7 @@ LLVM Release License
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
|
||||
Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
@ -58,6 +58,22 @@ LLVM_OBJ_ROOT := $(call realpath, @abs_top_builddir@)
|
||||
PROJ_SRC_ROOT := $(LLVM_SRC_ROOT)
|
||||
PROJ_SRC_DIR := $(LLVM_SRC_ROOT)$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR))
|
||||
|
||||
# FIXME: This is temporary during the grace period where in-source builds are
|
||||
# deprecated. Convert to a hard error when that period is up.
|
||||
#
|
||||
# See: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20150323/268067.html
|
||||
ifeq ($(LLVM_SRC_ROOT), $(LLVM_OBJ_ROOT))
|
||||
$(warning ######################################################################################)
|
||||
$(warning # #)
|
||||
$(warning # WARNING #)
|
||||
$(warning # #)
|
||||
$(warning # In-source builds are deprecated. #)
|
||||
$(warning # #)
|
||||
$(warning # Please configure from a separate build directory! #)
|
||||
$(warning # #)
|
||||
$(warning ######################################################################################)
|
||||
endif
|
||||
|
||||
ifneq ($(CLANG_SRC_ROOT),)
|
||||
CLANG_SRC_ROOT:= $(call realpath, $(CLANG_SRC_ROOT))
|
||||
PROJ_SRC_DIR := $(patsubst $(LLVM_SRC_ROOT)/tools/clang%,$(CLANG_SRC_ROOT)%,$(PROJ_SRC_DIR))
|
||||
@ -293,6 +309,11 @@ ENABLE_TERMINFO = @ENABLE_TERMINFO@
|
||||
#ENABLE_EXPENSIVE_CHECKS = 0
|
||||
@ENABLE_EXPENSIVE_CHECKS@
|
||||
|
||||
# --enable-abi-breaking-checks : decide whether we should compile in asserts and
|
||||
# checks that make the build ABI incompatible with an llvm built without these
|
||||
# checks enabled.
|
||||
ENABLE_ABI_BREAKING_CHECKS = @ENABLE_ABI_BREAKING_CHECKS@
|
||||
|
||||
# When DEBUG_RUNTIME is enabled, the runtime libraries will retain debug
|
||||
# symbols.
|
||||
#DEBUG_RUNTIME = 1
|
||||
|
@ -631,6 +631,9 @@ ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
ifneq ($(HOST_OS),Darwin)
|
||||
ifneq ($(HOST_ARCH),Mips)
|
||||
CXX.Flags += -ffunction-sections -fdata-sections
|
||||
ifeq ($(HOST_OS),SunOS)
|
||||
CXX.Flags += -falign-functions=8
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@ -638,8 +641,12 @@ ifndef NO_DEAD_STRIP
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
LD.Flags += -Wl,-dead_strip
|
||||
else
|
||||
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
LD.Flags += -Wl,--gc-sections
|
||||
ifeq ($(HOST_OS),SunOS)
|
||||
LD.Flags += -Wl,-z -Wl,discard-unused=sections
|
||||
else
|
||||
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
LD.Flags += -Wl,--gc-sections
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -15,4 +15,3 @@ documentation setup.
|
||||
|
||||
If you're writing a package for LLVM, see docs/Packaging.rst for our
|
||||
suggestions.
|
||||
|
||||
|
4
autoconf/config.sub
vendored
4
autoconf/config.sub
vendored
@ -1354,7 +1354,7 @@ case $os in
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -bitrig*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@ -1489,6 +1489,8 @@ case $os in
|
||||
;;
|
||||
-nacl*)
|
||||
;;
|
||||
-ps4)
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
|
@ -32,12 +32,12 @@ dnl===-----------------------------------------------------------------------===
|
||||
dnl Initialize autoconf and define the package name, version number and
|
||||
dnl address for reporting bugs.
|
||||
|
||||
AC_INIT([LLVM],[3.6.1],[http://llvm.org/bugs/])
|
||||
AC_INIT([LLVM],[3.7.0svn],[http://llvm.org/bugs/])
|
||||
|
||||
LLVM_VERSION_MAJOR=3
|
||||
LLVM_VERSION_MINOR=6
|
||||
LLVM_VERSION_PATCH=1
|
||||
LLVM_VERSION_SUFFIX=
|
||||
LLVM_VERSION_MINOR=7
|
||||
LLVM_VERSION_PATCH=0
|
||||
LLVM_VERSION_SUFFIX=svn
|
||||
|
||||
AC_DEFINE_UNQUOTED([LLVM_VERSION_MAJOR], $LLVM_VERSION_MAJOR, [Major version of the LLVM API])
|
||||
AC_DEFINE_UNQUOTED([LLVM_VERSION_MINOR], $LLVM_VERSION_MINOR, [Minor version of the LLVM API])
|
||||
@ -51,8 +51,8 @@ AC_SUBST([LLVM_VERSION_SUFFIX])
|
||||
|
||||
dnl Provide a copyright substitution and ensure the copyright notice is included
|
||||
dnl in the output of --version option of the generated configure script.
|
||||
AC_SUBST(LLVM_COPYRIGHT,["Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign."])
|
||||
AC_COPYRIGHT([Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.])
|
||||
AC_SUBST(LLVM_COPYRIGHT,["Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign."])
|
||||
AC_COPYRIGHT([Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign.])
|
||||
|
||||
dnl Indicate that we require autoconf 2.60 or later.
|
||||
AC_PREREQ(2.60)
|
||||
@ -73,6 +73,19 @@ if test ${srcdir} != "." ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Quit if it is an in-source build
|
||||
if test ${srcdir} == "." ; then
|
||||
AC_MSG_WARN([**************************************************************************************])
|
||||
AC_MSG_WARN([* *])
|
||||
AC_MSG_WARN([* WARNING *])
|
||||
AC_MSG_WARN([* *])
|
||||
AC_MSG_WARN([* In-source builds are deprecated. *])
|
||||
AC_MSG_WARN([* *])
|
||||
AC_MSG_WARN([* Please configure from a separate build directory! *])
|
||||
AC_MSG_WARN([* *])
|
||||
AC_MSG_WARN([**************************************************************************************])
|
||||
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=}
|
||||
@ -105,7 +118,7 @@ if test "$CXX" = "clang++" ; then
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Selected compiler could not find or parse C++ standard library headers. Rerun with CC=c-compiler CXX=c++-compiler ./configure ...])
|
||||
AC_MSG_ERROR([Selected compiler could not find or parse C++ standard library headers. Rerun with CC=c-compiler CXX=c++-compiler LLVM_SRC_DIR/configure ...])
|
||||
])
|
||||
AC_LANG_POP([C++])
|
||||
fi
|
||||
@ -267,6 +280,11 @@ AC_CACHE_CHECK([type of operating system we're going to host on],
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
llvm_cv_os_type="DragonFly"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-bitrig*)
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
llvm_cv_os_type="Bitrig"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-hpux*)
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
@ -347,6 +365,8 @@ AC_CACHE_CHECK([type of operating system we're going to target],
|
||||
llvm_cv_target_os_type="NetBSD" ;;
|
||||
*-*-dragonfly*)
|
||||
llvm_cv_target_os_type="DragonFly" ;;
|
||||
*-*-bitrig*)
|
||||
llvm_cv_target_os_type="Bitrig" ;;
|
||||
*-*-hpux*)
|
||||
llvm_cv_target_os_type="HP-UX" ;;
|
||||
*-*-interix*)
|
||||
@ -369,6 +389,8 @@ AC_CACHE_CHECK([type of operating system we're going to target],
|
||||
llvm_cv_target_os_type="NativeClient" ;;
|
||||
*-unknown-eabi*)
|
||||
llvm_cv_target_os_type="Freestanding" ;;
|
||||
*-*-ps4)
|
||||
llvm_cv_target_os_type="PS4" ;;
|
||||
*)
|
||||
llvm_cv_target_os_type="Unknown" ;;
|
||||
esac])
|
||||
@ -692,8 +714,10 @@ AC_ARG_ENABLE(assertions,AS_HELP_STRING(
|
||||
--enable-assertions,[Compile with assertion checks enabled (default is YES)]),, enableval="yes")
|
||||
if test ${enableval} = "yes" ; then
|
||||
AC_SUBST(DISABLE_ASSERTIONS,[[]])
|
||||
assertions_enabled="yes"
|
||||
else
|
||||
AC_SUBST(DISABLE_ASSERTIONS,[[DISABLE_ASSERTIONS=1]])
|
||||
assertions_enabled="no"
|
||||
fi
|
||||
|
||||
dnl --enable-werror : check whether we want Werror on by default
|
||||
@ -717,6 +741,28 @@ else
|
||||
AC_SUBST(EXPENSIVE_CHECKS,[[no]])
|
||||
fi
|
||||
|
||||
dnl --enable-abi-breaking-checks : decide whether we should compile in asserts and
|
||||
dnl checks that make the build ABI incompatible with an llvm built without these
|
||||
dnl checks enabled.
|
||||
AC_ARG_ENABLE(abi-breaking-checks,AS_HELP_STRING(
|
||||
--enable-abi-breaking-checks,[Compile with abi-breaking asserts support (default is with-asserts)]),, enableval="with-asserts")
|
||||
case "$enableval" in
|
||||
with-asserts) if test ${assertions_enabled} = "yes" ; then
|
||||
AC_DEFINE([LLVM_ENABLE_ABI_BREAKING_CHECKS],[1],[Define to enable checks that alter the LLVM C++ ABI])
|
||||
AC_SUBST(ENABLE_ABI_BREAKING_CHECKS,[1])
|
||||
else
|
||||
AC_SUBST(ENABLE_ABI_BREAKING_CHECKS,[0])
|
||||
fi ;;
|
||||
yes)
|
||||
AC_DEFINE([LLVM_ENABLE_ABI_BREAKING_CHECKS],[1],[Define to enable checks that alter the LLVM C++ ABI])
|
||||
AC_SUBST(ENABLE_ABI_BREAKING_CHECKS,[1])
|
||||
;;
|
||||
no)
|
||||
AC_SUBST(ENABLE_ABI_BREAKING_CHECKS,[0])
|
||||
;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-abi-breaking-checks. Use "with-asserts", "yes" or "no"])
|
||||
esac
|
||||
|
||||
dnl --enable-debug-runtime : should runtime libraries have debug symbols?
|
||||
AC_ARG_ENABLE(debug-runtime,
|
||||
AS_HELP_STRING(--enable-debug-runtime,[Build runtime libs with debug symbols (default is NO)]),,enableval=no)
|
||||
@ -792,11 +838,139 @@ AC_ARG_ENABLE(doxygen,
|
||||
enableval=default)
|
||||
case "$enableval" in
|
||||
yes) AC_SUBST(ENABLE_DOXYGEN,[1]) ;;
|
||||
no) AC_SUBST(ENABLE_DOXYGEN,[0]) ;;
|
||||
default) AC_SUBST(ENABLE_DOXYGEN,[0]) ;;
|
||||
no|default) AC_SUBST(ENABLE_DOXYGEN,[0]) ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-doxygen. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
|
||||
dnl Allow enablement of doxygen search engine
|
||||
AC_ARG_ENABLE(doxygen-search,
|
||||
AS_HELP_STRING([--enable-doxygen-search],
|
||||
[Enable doxygen search support (default is NO)]),,
|
||||
enableval=default)
|
||||
ENABLE_DOXYGEN_SEARCH="$enableval"
|
||||
|
||||
case "$enableval" in
|
||||
yes|no|default) ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-doxygen-search. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(doxygen-external-search,
|
||||
AS_HELP_STRING([--enable-doxygen-external-search],
|
||||
[Enable doxygen exteranl search (default is NO)]),,
|
||||
enableval=default)
|
||||
ENABLE_DOXYGEN_EXTERNAL_SEARCH="$enableval"
|
||||
|
||||
case "$enableval" in
|
||||
yes)
|
||||
dnl To match with the CMake behavior, enable doxygen when
|
||||
dnl --enable-doxygen-external-search is enabled.
|
||||
case "$ENABLE_DOXYGEN_SEARCH" in
|
||||
yes|default) ENABLE_DOXYGEN_SEARCH="yes" ;;
|
||||
no) AC_MSG_ERROR([The option --enable-doxygen-external-search requires --enable-doxygen-search]) ;;
|
||||
esac
|
||||
;;
|
||||
no|default) ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-doxygen-external-search. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
|
||||
AC_ARG_WITH(doxygen-search-engine-url,
|
||||
AS_HELP_STRING([--with-doxygen-search-engine-url],
|
||||
[Specify the external search engine for doxygen]),,)
|
||||
WITH_DOXYGEN_SEARCH_ENGINE_URL="$withval"
|
||||
|
||||
AC_ARG_WITH(doxygen-search-mappings,
|
||||
AS_HELP_STRING([--with-doxygen-search-mappings],
|
||||
[Specify the extra search mapping for doxygen]),,)
|
||||
WITH_DOXYGEN_SEARCH_MAPPINGS="$withval"
|
||||
|
||||
case "$ENABLE_DOXYGEN_SEARCH" in
|
||||
yes)
|
||||
if test "$ENABLE_DOXYGEN" = "0" ; then
|
||||
AC_MSG_ERROR([The option --enable-doxygen-search requires --enable-doxygen.])
|
||||
fi
|
||||
|
||||
AC_SUBST(enable_searchengine,[YES])
|
||||
|
||||
case "$ENABLE_DOXYGEN_EXTERNAL_SEARCH" in
|
||||
yes)
|
||||
AC_SUBST(enable_external_search,[YES])
|
||||
AC_SUBST(enable_server_based_search,[YES])
|
||||
AC_SUBST(searchengine_url,["$WITH_DOXYGEN_SEARCH_ENGINE_URL"])
|
||||
AC_SUBST(extra_search_mappings,["$WITH_DOXYGEN_SEARCH_MAPPINGS"])
|
||||
;;
|
||||
|
||||
no|default)
|
||||
AC_SUBST(enable_external_search,[NO])
|
||||
AC_SUBST(enable_server_based_search,[NO])
|
||||
AC_SUBST(searchengine_url,[])
|
||||
AC_SUBST(extra_search_mappings,[])
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
no|default)
|
||||
AC_SUBST(enable_searchengine,[NO])
|
||||
AC_SUBST(searchengine_url,[])
|
||||
AC_SUBST(enable_server_based_search,[NO])
|
||||
AC_SUBST(enable_external_search,[NO])
|
||||
AC_SUBST(extra_search_mappings,[])
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid setting for --enable-doxygen-search. Use "yes" or "no"])
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl Allow enablement of doxygen generated Qt help files
|
||||
AC_ARG_ENABLE(doxygen-qt-help,
|
||||
AS_HELP_STRING([--enable-doxygen-qt-help],
|
||||
[Build Qt help files (default is NO)]),,
|
||||
enableval=default)
|
||||
case "$enableval" in
|
||||
yes)
|
||||
if test "$ENABLE_DOXYGEN" = "0" ; then
|
||||
AC_MSG_ERROR([The option --enable-doxygen-qt-help requires --enable-doxygen.])
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(QHELPGENERATOR, [qhelpgenerator], [qhelpgenerator])
|
||||
|
||||
dnl Qt help file for llvm doxygen documentation
|
||||
AC_SUBST(llvm_doxygen_generate_qhp,[YES])
|
||||
AC_SUBST(llvm_doxygen_qch_filename,[org.llvm.qch])
|
||||
AC_SUBST(llvm_doxygen_qhp_namespace,[org.llvm])
|
||||
AC_SUBST(llvm_doxygen_qhelpgenerator_path,["$QHELPGENERATOR"])
|
||||
AC_SUBST(llvm_doxygen_qhp_cust_filter_name,["$PACKAGE_STRING"])
|
||||
AC_SUBST(llvm_doxygen_qhp_cust_filter_attrs,["$PACKAGE_NAME,$PACKAGE_VERSION"])
|
||||
|
||||
dnl Qt help file for clang doxygen documentation
|
||||
AC_SUBST(clang_doxygen_generate_qhp,[YES])
|
||||
AC_SUBST(clang_doxygen_qch_filename,[org.llvm.clang.qch])
|
||||
AC_SUBST(clang_doxygen_qhp_namespace,[org.llvm.clang])
|
||||
AC_SUBST(clang_doxygen_qhelpgenerator_path,["$QHELPGENERATOR"])
|
||||
AC_SUBST(clang_doxygen_qhp_cust_filter_name,["Clang $PACKAGE_VERSION"])
|
||||
AC_SUBST(clang_doxygen_qhp_cust_filter_attrs,["Clang,$PACKAGE_VERSION"])
|
||||
;;
|
||||
|
||||
no|default)
|
||||
AC_SUBST(llvm_doxygen_generate_qhp,[NO])
|
||||
AC_SUBST(llvm_doxygen_qch_filename,[])
|
||||
AC_SUBST(llvm_doxygen_qhp_namespace,[])
|
||||
AC_SUBST(llvm_doxygen_qhelpgenerator_path,[])
|
||||
AC_SUBST(llvm_doxygen_qhp_cust_filter_name,[])
|
||||
AC_SUBST(llvm_doxygen_qhp_cust_filter_attrs,[])
|
||||
|
||||
AC_SUBST(clang_doxygen_generate_qhp,[NO])
|
||||
AC_SUBST(clang_doxygen_qch_filename,[])
|
||||
AC_SUBST(clang_doxygen_qhp_namespace,[])
|
||||
AC_SUBST(clang_doxygen_qhelpgenerator_path,[])
|
||||
AC_SUBST(clang_doxygen_qhp_cust_filter_name,["Clang $PACKAGE_VERSION"])
|
||||
AC_SUBST(clang_doxygen_qhp_cust_filter_attrs,["Clang,$PACKAGE_VERSION"])
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid setting for --enable-doxygen-qt-help. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
|
||||
dnl Allow disablement of threads
|
||||
AC_ARG_ENABLE(threads,
|
||||
AS_HELP_STRING([--enable-threads],
|
||||
@ -1533,11 +1707,11 @@ AC_ARG_WITH(oprofile,
|
||||
AC_SEARCH_LIBS(bfd_init, bfd, [], [])
|
||||
AC_SEARCH_LIBS(op_open_agent, opagent, [], [
|
||||
echo "Error! You need to have libopagent around."
|
||||
exit -1
|
||||
exit 1
|
||||
])
|
||||
AC_CHECK_HEADER([opagent.h], [], [
|
||||
echo "Error! You need to have opagent.h around."
|
||||
exit -1
|
||||
exit 1
|
||||
])
|
||||
fi ;;
|
||||
*)
|
||||
@ -1690,9 +1864,7 @@ dnl=== SECTION 8: Check for specific functions needed
|
||||
dnl===
|
||||
dnl===-----------------------------------------------------------------------===
|
||||
|
||||
AC_CHECK_FUNCS([backtrace ceilf floorf roundf rintf nearbyintf getcwd ])
|
||||
AC_CHECK_FUNCS([powf fmodf strtof round ])
|
||||
AC_CHECK_FUNCS([log log2 log10 exp exp2])
|
||||
AC_CHECK_FUNCS([backtrace getcwd ])
|
||||
AC_CHECK_FUNCS([getpagesize getrusage getrlimit setrlimit gettimeofday ])
|
||||
AC_CHECK_FUNCS([isatty mkdtemp mkstemp ])
|
||||
AC_CHECK_FUNCS([mktemp posix_spawn pread realpath sbrk setrlimit ])
|
||||
@ -1756,11 +1928,6 @@ if test "$llvm_cv_os_type" = "MingW" ; then
|
||||
AC_DEFINE_UNQUOTED([WIN32_ELMCB_PCSTR],$llvm_cv_win32_elmcb_pcstr,[Type of 1st arg on ELM Callback])
|
||||
fi
|
||||
|
||||
dnl Check for variations in the Standard C++ library and STL. These macros are
|
||||
dnl provided by LLVM in the autoconf/m4 directory.
|
||||
AC_FUNC_ISNAN
|
||||
AC_FUNC_ISINF
|
||||
|
||||
dnl Check for mmap support.We also need to know if /dev/zero is required to
|
||||
dnl be opened for allocating RWX memory.
|
||||
dnl Make sure we aren't attempting to configure for an unknown system
|
||||
|
@ -1,42 +0,0 @@
|
||||
dnl
|
||||
dnl This function determins if the isinf function isavailable on this
|
||||
dnl platform.
|
||||
dnl
|
||||
|
||||
AC_DEFUN([AC_FUNC_ISINF],[
|
||||
|
||||
AC_SINGLE_CXX_CHECK([ac_cv_func_isinf_in_math_h],
|
||||
[isinf], [<math.h>],
|
||||
[float f; isinf(f);])
|
||||
if test "$ac_cv_func_isinf_in_math_h" = "yes" ; then
|
||||
AC_DEFINE([HAVE_ISINF_IN_MATH_H], [1],
|
||||
[Set to 1 if the isinf function is found in <math.h>])
|
||||
fi
|
||||
|
||||
AC_SINGLE_CXX_CHECK([ac_cv_func_isinf_in_cmath],
|
||||
[isinf], [<cmath>],
|
||||
[float f; isinf(f);])
|
||||
if test "$ac_cv_func_isinf_in_cmath" = "yes" ; then
|
||||
AC_DEFINE([HAVE_ISINF_IN_CMATH], [1],
|
||||
[Set to 1 if the isinf function is found in <cmath>])
|
||||
fi
|
||||
|
||||
AC_SINGLE_CXX_CHECK([ac_cv_func_std_isinf_in_cmath],
|
||||
[std::isinf], [<cmath>],
|
||||
[float f; std::isinf(f);])
|
||||
if test "$ac_cv_func_std_isinf_in_cmath" = "yes" ; then
|
||||
AC_DEFINE([HAVE_STD_ISINF_IN_CMATH], [1],
|
||||
[Set to 1 if the std::isinf function is found in <cmath>])
|
||||
fi
|
||||
|
||||
AC_SINGLE_CXX_CHECK([ac_cv_func_finite_in_ieeefp_h],
|
||||
[finite], [<ieeefp.h>],
|
||||
[float f; finite(f);])
|
||||
if test "$ac_cv_func_finite_in_ieeefp_h" = "yes" ; then
|
||||
AC_DEFINE([HAVE_FINITE_IN_IEEEFP_H], [1],
|
||||
[Set to 1 if the finite function is found in <ieeefp.h>])
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
#
|
||||
# This function determines if the isnan function is available on this
|
||||
# platform.
|
||||
#
|
||||
AC_DEFUN([AC_FUNC_ISNAN],[
|
||||
AC_SINGLE_CXX_CHECK([ac_cv_func_isnan_in_math_h],
|
||||
[isnan], [<math.h>],
|
||||
[float f; isnan(f);])
|
||||
|
||||
if test "$ac_cv_func_isnan_in_math_h" = "yes" ; then
|
||||
AC_DEFINE([HAVE_ISNAN_IN_MATH_H],1,[Set to 1 if the isnan function is found in <math.h>])
|
||||
fi
|
||||
|
||||
AC_SINGLE_CXX_CHECK([ac_cv_func_isnan_in_cmath],
|
||||
[isnan], [<cmath>],
|
||||
[float f; isnan(f);])
|
||||
if test "$ac_cv_func_isnan_in_cmath" = "yes" ; then
|
||||
AC_DEFINE([HAVE_ISNAN_IN_CMATH],1,[Set to 1 if the isnan function is found in <cmath>])
|
||||
fi
|
||||
|
||||
AC_SINGLE_CXX_CHECK([ac_cv_func_std_isnan_in_cmath],
|
||||
[std::isnan], [<cmath>],
|
||||
[float f; std::isnan(f);])
|
||||
if test "$ac_cv_func_std_isnan_in_cmath" = "yes" ; then
|
||||
AC_DEFINE([HAVE_STD_ISNAN_IN_CMATH],1,[Set to 1 if the std::isnan function is found in <cmath>])
|
||||
fi
|
||||
])
|
@ -12,22 +12,15 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "DIBuilderBindings.h"
|
||||
|
||||
#include "IRBindings.h"
|
||||
#include "llvm/IR/DIBuilder.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/DIBuilder.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef)
|
||||
|
||||
namespace {
|
||||
template <typename T> T unwrapDI(LLVMMetadataRef v) {
|
||||
return v ? T(unwrap<MDNode>(v)) : T();
|
||||
}
|
||||
}
|
||||
|
||||
LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef mref) {
|
||||
Module *m = unwrap(mref);
|
||||
return wrap(new DIBuilder(*m));
|
||||
@ -47,16 +40,14 @@ LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef Dref,
|
||||
int Optimized, const char *Flags,
|
||||
unsigned RuntimeVersion) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DICompileUnit CU = D->createCompileUnit(Lang, File, Dir, Producer, Optimized,
|
||||
Flags, RuntimeVersion);
|
||||
return wrap(CU);
|
||||
return wrap(D->createCompileUnit(Lang, File, Dir, Producer, Optimized, Flags,
|
||||
RuntimeVersion));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Dref, const char *File,
|
||||
const char *Dir) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DIFile F = D->createFile(File, Dir);
|
||||
return wrap(F);
|
||||
return wrap(D->createFile(File, Dir));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
|
||||
@ -65,8 +56,8 @@ LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
|
||||
unsigned Line,
|
||||
unsigned Column) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DILexicalBlock LB = D->createLexicalBlock(
|
||||
unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Column);
|
||||
auto *LB = D->createLexicalBlock(unwrap<DILocalScope>(Scope),
|
||||
unwrap<DIFile>(File), Line, Column);
|
||||
return wrap(LB);
|
||||
}
|
||||
|
||||
@ -75,9 +66,8 @@ LLVMMetadataRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref,
|
||||
LLVMMetadataRef File,
|
||||
unsigned Discriminator) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DILexicalBlockFile LBF = D->createLexicalBlockFile(
|
||||
unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Discriminator);
|
||||
return wrap(LBF);
|
||||
return wrap(D->createLexicalBlockFile(unwrap<DILocalScope>(Scope),
|
||||
unwrap<DIFile>(File), Discriminator));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateFunction(
|
||||
@ -86,11 +76,11 @@ LLVMMetadataRef LLVMDIBuilderCreateFunction(
|
||||
LLVMMetadataRef CompositeType, int IsLocalToUnit, int IsDefinition,
|
||||
unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Func) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DISubprogram SP = D->createFunction(
|
||||
unwrapDI<DIDescriptor>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
|
||||
Line, unwrapDI<DICompositeType>(CompositeType), IsLocalToUnit,
|
||||
IsDefinition, ScopeLine, Flags, IsOptimized, unwrap<Function>(Func));
|
||||
return wrap(SP);
|
||||
return wrap(D->createFunction(unwrap<DIScope>(Scope), Name, LinkageName,
|
||||
File ? unwrap<DIFile>(File) : nullptr, Line,
|
||||
unwrap<DISubroutineType>(CompositeType),
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, Flags,
|
||||
IsOptimized, unwrap<Function>(Func)));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateLocalVariable(
|
||||
@ -98,10 +88,9 @@ LLVMMetadataRef LLVMDIBuilderCreateLocalVariable(
|
||||
const char *Name, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty,
|
||||
int AlwaysPreserve, unsigned Flags, unsigned ArgNo) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DIVariable V = D->createLocalVariable(
|
||||
Tag, unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
|
||||
unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo);
|
||||
return wrap(V);
|
||||
return wrap(D->createLocalVariable(
|
||||
Tag, unwrap<DIScope>(Scope), Name, unwrap<DIFile>(File), Line,
|
||||
unwrap<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref,
|
||||
@ -110,8 +99,7 @@ LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref,
|
||||
uint64_t AlignInBits,
|
||||
unsigned Encoding) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DIBasicType T = D->createBasicType(Name, SizeInBits, AlignInBits, Encoding);
|
||||
return wrap(T);
|
||||
return wrap(D->createBasicType(Name, SizeInBits, AlignInBits, Encoding));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
|
||||
@ -120,18 +108,17 @@ LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
|
||||
uint64_t AlignInBits,
|
||||
const char *Name) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DIDerivedType T = D->createPointerType(unwrapDI<DIType>(PointeeType),
|
||||
SizeInBits, AlignInBits, Name);
|
||||
return wrap(T);
|
||||
return wrap(D->createPointerType(unwrap<DIType>(PointeeType), SizeInBits,
|
||||
AlignInBits, Name));
|
||||
}
|
||||
|
||||
LLVMMetadataRef
|
||||
LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref, LLVMMetadataRef File,
|
||||
LLVMMetadataRef ParameterTypes) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DICompositeType CT = D->createSubroutineType(
|
||||
unwrapDI<DIFile>(File), unwrapDI<DITypeArray>(ParameterTypes));
|
||||
return wrap(CT);
|
||||
return wrap(
|
||||
D->createSubroutineType(File ? unwrap<DIFile>(File) : nullptr,
|
||||
DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateStructType(
|
||||
@ -140,11 +127,22 @@ LLVMMetadataRef LLVMDIBuilderCreateStructType(
|
||||
uint64_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom,
|
||||
LLVMMetadataRef ElementTypes) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DICompositeType CT = D->createStructType(
|
||||
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
|
||||
SizeInBits, AlignInBits, Flags, unwrapDI<DIType>(DerivedFrom),
|
||||
unwrapDI<DIArray>(ElementTypes));
|
||||
return wrap(CT);
|
||||
return wrap(D->createStructType(
|
||||
unwrap<DIScope>(Scope), Name, File ? unwrap<DIFile>(File) : nullptr, Line,
|
||||
SizeInBits, AlignInBits, Flags,
|
||||
DerivedFrom ? unwrap<DIType>(DerivedFrom) : nullptr,
|
||||
ElementTypes ? DINodeArray(unwrap<MDTuple>(ElementTypes)) : nullptr));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType(
|
||||
LLVMDIBuilderRef Dref, unsigned Tag, const char *Name,
|
||||
LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line,
|
||||
unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits,
|
||||
unsigned Flags) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
return wrap(D->createReplaceableCompositeType(
|
||||
Tag, Name, unwrap<DIScope>(Scope), File ? unwrap<DIFile>(File) : nullptr,
|
||||
Line, RuntimeLang, SizeInBits, AlignInBits, Flags));
|
||||
}
|
||||
|
||||
LLVMMetadataRef
|
||||
@ -154,10 +152,9 @@ LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef Dref, LLVMMetadataRef Scope,
|
||||
uint64_t AlignInBits, uint64_t OffsetInBits,
|
||||
unsigned Flags, LLVMMetadataRef Ty) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DIDerivedType DT = D->createMemberType(
|
||||
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
|
||||
SizeInBits, AlignInBits, OffsetInBits, Flags, unwrapDI<DIType>(Ty));
|
||||
return wrap(DT);
|
||||
return wrap(D->createMemberType(
|
||||
unwrap<DIScope>(Scope), Name, File ? unwrap<DIFile>(File) : nullptr, Line,
|
||||
SizeInBits, AlignInBits, OffsetInBits, Flags, unwrap<DIType>(Ty)));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref,
|
||||
@ -166,10 +163,9 @@ LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref,
|
||||
LLVMMetadataRef ElementType,
|
||||
LLVMMetadataRef Subscripts) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DICompositeType CT =
|
||||
D->createArrayType(SizeInBits, AlignInBits, unwrapDI<DIType>(ElementType),
|
||||
unwrapDI<DIArray>(Subscripts));
|
||||
return wrap(CT);
|
||||
return wrap(D->createArrayType(SizeInBits, AlignInBits,
|
||||
unwrap<DIType>(ElementType),
|
||||
DINodeArray(unwrap<MDTuple>(Subscripts))));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref,
|
||||
@ -177,17 +173,15 @@ LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref,
|
||||
LLVMMetadataRef File, unsigned Line,
|
||||
LLVMMetadataRef Context) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DIDerivedType DT =
|
||||
D->createTypedef(unwrapDI<DIType>(Ty), Name, unwrapDI<DIFile>(File), Line,
|
||||
unwrapDI<DIDescriptor>(Context));
|
||||
return wrap(DT);
|
||||
return wrap(D->createTypedef(unwrap<DIType>(Ty), Name,
|
||||
File ? unwrap<DIFile>(File) : nullptr, Line,
|
||||
Context ? unwrap<DIScope>(Context) : nullptr));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Dref,
|
||||
int64_t Lo, int64_t Count) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DISubrange S = D->getOrCreateSubrange(Lo, Count);
|
||||
return wrap(S);
|
||||
return wrap(D->getOrCreateSubrange(Lo, Count));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref,
|
||||
@ -196,8 +190,8 @@ LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref,
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
Metadata **DataValue = unwrap(Data);
|
||||
ArrayRef<Metadata *> Elements(DataValue, Length);
|
||||
DIArray A = D->getOrCreateArray(Elements);
|
||||
return wrap(A);
|
||||
DINodeArray A = D->getOrCreateArray(Elements);
|
||||
return wrap(A.get());
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref,
|
||||
@ -206,15 +200,14 @@ LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref,
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
Metadata **DataValue = unwrap(Data);
|
||||
ArrayRef<Metadata *> Elements(DataValue, Length);
|
||||
DITypeArray A = D->getOrCreateTypeArray(Elements);
|
||||
return wrap(A);
|
||||
DITypeRefArray A = D->getOrCreateTypeArray(Elements);
|
||||
return wrap(A.get());
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref,
|
||||
int64_t *Addr, size_t Length) {
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
DIExpression Expr = D->createExpression(ArrayRef<int64_t>(Addr, Length));
|
||||
return wrap(Expr);
|
||||
return wrap(D->createExpression(ArrayRef<int64_t>(Addr, Length)));
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref,
|
||||
@ -222,10 +215,14 @@ LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref,
|
||||
LLVMMetadataRef VarInfo,
|
||||
LLVMMetadataRef Expr,
|
||||
LLVMBasicBlockRef Block) {
|
||||
// Fail immediately here until the llgo folks update their bindings. The
|
||||
// called function is going to assert out anyway.
|
||||
llvm_unreachable("DIBuilder API change requires a DebugLoc");
|
||||
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
Instruction *Instr =
|
||||
D->insertDeclare(unwrap(Storage), unwrapDI<DIVariable>(VarInfo),
|
||||
unwrapDI<DIExpression>(Expr), unwrap(Block));
|
||||
Instruction *Instr = D->insertDeclare(
|
||||
unwrap(Storage), unwrap<DILocalVariable>(VarInfo),
|
||||
unwrap<DIExpression>(Expr), /* DebugLoc */ nullptr, unwrap(Block));
|
||||
return wrap(Instr);
|
||||
}
|
||||
|
||||
@ -234,9 +231,13 @@ LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef Dref,
|
||||
LLVMMetadataRef VarInfo,
|
||||
LLVMMetadataRef Expr,
|
||||
LLVMBasicBlockRef Block) {
|
||||
// Fail immediately here until the llgo folks update their bindings. The
|
||||
// called function is going to assert out anyway.
|
||||
llvm_unreachable("DIBuilder API change requires a DebugLoc");
|
||||
|
||||
DIBuilder *D = unwrap(Dref);
|
||||
Instruction *Instr = D->insertDbgValueIntrinsic(
|
||||
unwrap(Val), Offset, unwrapDI<DIVariable>(VarInfo),
|
||||
unwrapDI<DIExpression>(Expr), unwrap(Block));
|
||||
unwrap(Val), Offset, unwrap<DILocalVariable>(VarInfo),
|
||||
unwrap<DIExpression>(Expr), /* DebugLoc */ nullptr, unwrap(Block));
|
||||
return wrap(Instr);
|
||||
}
|
||||
|
@ -14,8 +14,8 @@
|
||||
#ifndef LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H
|
||||
#define LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
#include "IRBindings.h"
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -84,6 +84,11 @@ LLVMMetadataRef LLVMDIBuilderCreateStructType(
|
||||
uint64_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom,
|
||||
LLVMMetadataRef ElementTypes);
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType(
|
||||
LLVMDIBuilderRef D, unsigned Tag, const char *Name, LLVMMetadataRef Scope,
|
||||
LLVMMetadataRef File, unsigned Line, unsigned RuntimeLang,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags);
|
||||
|
||||
LLVMMetadataRef
|
||||
LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef D, LLVMMetadataRef Scope,
|
||||
const char *Name, LLVMMetadataRef File,
|
||||
|
@ -12,7 +12,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "IRBindings.h"
|
||||
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
@ -66,8 +65,9 @@ LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs,
|
||||
|
||||
LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs,
|
||||
unsigned Count) {
|
||||
return wrap(MDNode::getTemporary(*unwrap(C),
|
||||
ArrayRef<Metadata *>(unwrap(MDs), Count)));
|
||||
return wrap(MDTuple::getTemporary(*unwrap(C),
|
||||
ArrayRef<Metadata *>(unwrap(MDs), Count))
|
||||
.release());
|
||||
}
|
||||
|
||||
void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name,
|
||||
@ -86,8 +86,8 @@ void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) {
|
||||
}
|
||||
|
||||
void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New) {
|
||||
auto *Node = unwrap<MDNodeFwdDecl>(MD);
|
||||
Node->replaceAllUsesWith(unwrap<MDNode>(New));
|
||||
auto *Node = unwrap<MDNode>(MD);
|
||||
Node->replaceAllUsesWith(unwrap<Metadata>(New));
|
||||
MDNode::deleteTemporary(Node);
|
||||
}
|
||||
|
||||
|
@ -12,10 +12,9 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "InstrumentationBindings.h"
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -37,6 +36,11 @@ void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM) {
|
||||
}
|
||||
|
||||
void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM,
|
||||
const char *ABIListFile) {
|
||||
unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFile));
|
||||
int ABIListFilesNum,
|
||||
const char **ABIListFiles) {
|
||||
std::vector<std::string> ABIListFilesVec;
|
||||
for (int i = 0; i != ABIListFilesNum; ++i) {
|
||||
ABIListFilesVec.push_back(ABIListFiles[i]);
|
||||
}
|
||||
unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFilesVec));
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM);
|
||||
void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM);
|
||||
void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM);
|
||||
void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM);
|
||||
void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM,
|
||||
const char *ABIListFile);
|
||||
void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, int ABIListFilesNum,
|
||||
const char **ABIListFiles);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SupportBindings.h"
|
||||
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -343,6 +343,38 @@ func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
|
||||
return Metadata{C: result}
|
||||
}
|
||||
|
||||
// DIReplaceableCompositeType holds the values for creating replaceable
|
||||
// composite type debug metadata.
|
||||
type DIReplaceableCompositeType struct {
|
||||
Tag dwarf.Tag
|
||||
Name string
|
||||
File Metadata
|
||||
Line int
|
||||
RuntimeLang int
|
||||
SizeInBits uint64
|
||||
AlignInBits uint64
|
||||
Flags int
|
||||
}
|
||||
|
||||
// CreateReplaceableCompositeType creates replaceable composite type debug metadata.
|
||||
func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
|
||||
name := C.CString(t.Name)
|
||||
defer C.free(unsafe.Pointer(name))
|
||||
result := C.LLVMDIBuilderCreateReplaceableCompositeType(
|
||||
d.ref,
|
||||
C.unsigned(t.Tag),
|
||||
name,
|
||||
scope.C,
|
||||
t.File.C,
|
||||
C.unsigned(t.Line),
|
||||
C.unsigned(t.RuntimeLang),
|
||||
C.uint64_t(t.SizeInBits),
|
||||
C.uint64_t(t.AlignInBits),
|
||||
C.unsigned(t.Flags),
|
||||
)
|
||||
return Metadata{C: result}
|
||||
}
|
||||
|
||||
// DIMemberType holds the values for creating member type debug metadata.
|
||||
type DIMemberType struct {
|
||||
Name string
|
||||
|
@ -20,16 +20,9 @@ package llvm
|
||||
import "C"
|
||||
import "errors"
|
||||
|
||||
type LinkerMode C.LLVMLinkerMode
|
||||
|
||||
const (
|
||||
LinkerDestroySource = C.LLVMLinkerDestroySource
|
||||
LinkerPreserveSource = C.LLVMLinkerPreserveSource
|
||||
)
|
||||
|
||||
func LinkModules(Dest, Src Module, Mode LinkerMode) error {
|
||||
func LinkModules(Dest, Src Module) error {
|
||||
var cmsg *C.char
|
||||
failed := C.LLVMLinkModules(Dest.C, Src.C, C.LLVMLinkerMode(Mode), &cmsg)
|
||||
failed := C.LLVMLinkModules(Dest.C, Src.C, C.LLVMLinkerDestroySource, &cmsg)
|
||||
if failed != 0 {
|
||||
err := errors.New(C.GoString(cmsg))
|
||||
C.LLVMDisposeMessage(cmsg)
|
||||
|
@ -36,8 +36,11 @@ func (pm PassManager) AddMemorySanitizerPass() {
|
||||
C.LLVMAddMemorySanitizerPass(pm.C)
|
||||
}
|
||||
|
||||
func (pm PassManager) AddDataFlowSanitizerPass(abilist string) {
|
||||
cabilist := C.CString(abilist)
|
||||
defer C.free(unsafe.Pointer(cabilist))
|
||||
C.LLVMAddDataFlowSanitizerPass(pm.C, cabilist)
|
||||
func (pm PassManager) AddDataFlowSanitizerPass(abilist []string) {
|
||||
abiliststrs := make([]*C.char, len(abilist))
|
||||
for i, arg := range abilist {
|
||||
abiliststrs[i] = C.CString(arg)
|
||||
defer C.free(unsafe.Pointer(abiliststrs[i]))
|
||||
}
|
||||
C.LLVMAddDataFlowSanitizerPass(pm.C, C.int(len(abilist)), &abiliststrs[0])
|
||||
}
|
||||
|
@ -23,11 +23,11 @@
|
||||
|
||||
void llvm_raise(value Prototype, char *Message);
|
||||
|
||||
/* llmodule -> llmodule -> Mode.t -> unit */
|
||||
CAMLprim value llvm_link_modules(LLVMModuleRef Dst, LLVMModuleRef Src, value Mode) {
|
||||
/* llmodule -> llmodule -> unit */
|
||||
CAMLprim value llvm_link_modules(LLVMModuleRef Dst, LLVMModuleRef Src) {
|
||||
char* Message;
|
||||
|
||||
if (LLVMLinkModules(Dst, Src, Int_val(Mode), &Message))
|
||||
if (LLVMLinkModules(Dst, Src, 0, &Message))
|
||||
llvm_raise(*caml_named_value("Llvm_linker.Error"), Message);
|
||||
|
||||
return Val_unit;
|
||||
|
@ -11,11 +11,5 @@ exception Error of string
|
||||
|
||||
let () = Callback.register_exception "Llvm_linker.Error" (Error "")
|
||||
|
||||
module Mode = struct
|
||||
type t =
|
||||
| DestroySource
|
||||
| PreserveSource
|
||||
end
|
||||
|
||||
external link_modules : Llvm.llmodule -> Llvm.llmodule -> Mode.t -> unit
|
||||
external link_modules : Llvm.llmodule -> Llvm.llmodule -> unit
|
||||
= "llvm_link_modules"
|
||||
|
@ -14,13 +14,6 @@
|
||||
|
||||
exception Error of string
|
||||
|
||||
(** Linking mode. *)
|
||||
module Mode : sig
|
||||
type t =
|
||||
| DestroySource
|
||||
| PreserveSource
|
||||
end
|
||||
|
||||
(** [link_modules dst src mode] links [src] into [dst], raising [Error]
|
||||
if the linking fails. *)
|
||||
val link_modules : Llvm.llmodule -> Llvm.llmodule -> Mode.t -> unit
|
||||
val link_modules : Llvm.llmodule -> Llvm.llmodule -> unit
|
@ -1300,6 +1300,8 @@ external build_fcmp : Fcmp.t -> llvalue -> llvalue -> string ->
|
||||
(*--... Miscellaneous instructions .........................................--*)
|
||||
external build_phi : (llvalue * llbasicblock) list -> string -> llbuilder ->
|
||||
llvalue = "llvm_build_phi"
|
||||
external build_empty_phi : lltype -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_empty_phi"
|
||||
external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_call"
|
||||
external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder ->
|
||||
|
@ -2422,6 +2422,12 @@ val build_fcmp : Fcmp.t -> llvalue -> llvalue -> string ->
|
||||
val build_phi : (llvalue * llbasicblock) list -> string -> llbuilder ->
|
||||
llvalue
|
||||
|
||||
(** [build_empty_phi ty name b] creates a
|
||||
[%name = phi %ty] instruction at the position specified by
|
||||
the instruction builder [b]. [ty] is the type of the instruction.
|
||||
See the method [llvm::LLVMBuilder::CreatePHI]. *)
|
||||
val build_empty_phi : lltype -> string -> llbuilder -> llvalue
|
||||
|
||||
(** [build_call fn args name b] creates a
|
||||
[%name = call %fn(args...)]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
|
@ -2191,6 +2191,15 @@ CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
|
||||
return PhiNode;
|
||||
}
|
||||
|
||||
/* lltype -> string -> llbuilder -> value */
|
||||
CAMLprim LLVMValueRef llvm_build_empty_phi(LLVMTypeRef Type, value Name, value B) {
|
||||
LLVMValueRef PhiNode;
|
||||
|
||||
return LLVMBuildPhi(Builder_val(B), Type, String_val(Name));
|
||||
|
||||
return PhiNode;
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params,
|
||||
value Name, value B) {
|
||||
|
@ -79,6 +79,7 @@ check_symbol_exists(FE_INEXACT "fenv.h" HAVE_DECL_FE_INEXACT)
|
||||
|
||||
check_include_file(mach/mach.h HAVE_MACH_MACH_H)
|
||||
check_include_file(mach-o/dyld.h HAVE_MACH_O_DYLD_H)
|
||||
check_include_file(histedit.h HAVE_HISTEDIT_H)
|
||||
|
||||
# size_t must be defined before including cxxabi.h on FreeBSD 10.0.
|
||||
check_cxx_source_compiles("
|
||||
@ -110,7 +111,9 @@ if( NOT PURE_WINDOWS )
|
||||
else()
|
||||
set(HAVE_LIBZ 0)
|
||||
endif()
|
||||
check_library_exists(edit el_init "" HAVE_LIBEDIT)
|
||||
if (HAVE_HISTEDIT_H)
|
||||
check_library_exists(edit el_init "" HAVE_LIBEDIT)
|
||||
endif()
|
||||
if(LLVM_ENABLE_TERMINFO)
|
||||
set(HAVE_TERMINFO 0)
|
||||
foreach(library tinfo terminfo curses ncurses ncursesw)
|
||||
@ -134,20 +137,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(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)
|
||||
check_symbol_exists(isnan cmath HAVE_ISNAN_IN_CMATH)
|
||||
check_symbol_exists(isnan math.h HAVE_ISNAN_IN_MATH_H)
|
||||
check_symbol_exists(ceilf math.h HAVE_CEILF)
|
||||
check_symbol_exists(floorf math.h HAVE_FLOORF)
|
||||
check_symbol_exists(fmodf math.h HAVE_FMODF)
|
||||
check_symbol_exists(log math.h HAVE_LOG)
|
||||
check_symbol_exists(log2 math.h HAVE_LOG2)
|
||||
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 )
|
||||
@ -159,7 +148,7 @@ endif()
|
||||
if( HAVE_SYS_UIO_H )
|
||||
check_symbol_exists(writev sys/uio.h HAVE_WRITEV)
|
||||
endif()
|
||||
check_symbol_exists(nearbyintf math.h HAVE_NEARBYINTF)
|
||||
check_symbol_exists(mallctl malloc_np.h HAVE_MALLCTL)
|
||||
check_symbol_exists(mallinfo malloc.h HAVE_MALLINFO)
|
||||
check_symbol_exists(malloc_zone_statistics malloc/malloc.h
|
||||
HAVE_MALLOC_ZONE_STATISTICS)
|
||||
@ -426,6 +415,24 @@ if( MSVC )
|
||||
set(SHLIBEXT ".lib")
|
||||
set(stricmp "_stricmp")
|
||||
set(strdup "_strdup")
|
||||
|
||||
# See if the DIA SDK is available and usable.
|
||||
set(MSVC_DIA_SDK_DIR "$ENV{VSINSTALLDIR}DIA SDK")
|
||||
|
||||
# Due to a bug in MSVC 2013's installation software, it is possible
|
||||
# for MSVC 2013 to write the DIA SDK into the Visual Studio 2012
|
||||
# install directory. If this happens, the installation is corrupt
|
||||
# and there's nothing we can do. It happens with enough frequency
|
||||
# though that we should handle it. We do so by simply checking that
|
||||
# the DIA SDK folder exists. Should this happen you will need to
|
||||
# uninstall VS 2012 and then re-install VS 2013.
|
||||
if (IS_DIRECTORY ${MSVC_DIA_SDK_DIR})
|
||||
set(HAVE_DIA_SDK 1)
|
||||
else()
|
||||
set(HAVE_DIA_SDK 0)
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_DIA_SDK 0)
|
||||
endif( MSVC )
|
||||
|
||||
if( PURE_WINDOWS )
|
||||
@ -519,6 +526,14 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(GOLD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.gold ld.gold ${LLVM_DEFAULT_TARGET_TRIPLE}-ld ld DOC "The gold linker")
|
||||
set(LLVM_BINUTILS_INCDIR "" CACHE PATH
|
||||
"PATH to binutils/include containing plugin-api.h for gold plugin.")
|
||||
|
||||
if(APPLE)
|
||||
find_program(LD64_EXECUTABLE NAMES ld DOC "The ld64 linker")
|
||||
endif()
|
||||
|
||||
include(FindOCaml)
|
||||
include(AddOCaml)
|
||||
if(WIN32)
|
||||
|
@ -10,7 +10,7 @@ function(llvm_update_compile_flags name)
|
||||
|
||||
# LLVM_REQUIRES_EH is an internal flag that individual
|
||||
# targets can use to force EH
|
||||
if(LLVM_REQUIRES_EH OR LLVM_ENABLE_EH)
|
||||
if((LLVM_REQUIRES_EH OR LLVM_ENABLE_EH) AND NOT CLANG_CL)
|
||||
if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
|
||||
message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI for ${name}")
|
||||
set(LLVM_REQUIRES_RTTI ON)
|
||||
@ -22,6 +22,10 @@ function(llvm_update_compile_flags name)
|
||||
list(APPEND LLVM_COMPILE_DEFINITIONS _HAS_EXCEPTIONS=0)
|
||||
list(APPEND LLVM_COMPILE_FLAGS "/EHs-c-")
|
||||
endif()
|
||||
if (CLANG_CL)
|
||||
# FIXME: Remove this once clang-cl supports SEH
|
||||
list(APPEND LLVM_COMPILE_DEFINITIONS "GTEST_HAS_SEH=0")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# LLVM_REQUIRES_RTTI is an internal flag that individual
|
||||
@ -87,7 +91,7 @@ function(add_llvm_symbol_exports target_name export_file)
|
||||
|
||||
set(CAT "cat")
|
||||
set(export_file_nativeslashes ${export_file})
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
if(WIN32 AND NOT CYGWIN AND NOT MSYS)
|
||||
set(CAT "type")
|
||||
# Convert ${export_file} to native format (backslashes) for "type"
|
||||
# Does not use file(TO_NATIVE_PATH) as it doesn't create a native
|
||||
@ -104,7 +108,7 @@ function(add_llvm_symbol_exports target_name export_file)
|
||||
COMMENT "Creating export file for ${target_name}")
|
||||
set(export_file_linker_flag "${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
|
||||
if(MSVC)
|
||||
set(export_file_linker_flag "/DEF:${export_file_linker_flag}")
|
||||
set(export_file_linker_flag "/DEF:\"${export_file_linker_flag}\"")
|
||||
endif()
|
||||
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " ${export_file_linker_flag}")
|
||||
@ -154,33 +158,38 @@ if(NOT WIN32 AND NOT APPLE)
|
||||
endif()
|
||||
|
||||
function(add_link_opts target_name)
|
||||
# Pass -O3 to the linker. This enabled different optimizations on different
|
||||
# linkers.
|
||||
if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR WIN32))
|
||||
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " -Wl,-O3")
|
||||
endif()
|
||||
# Don't use linker optimizations in debug builds since it slows down the
|
||||
# linker in a context where the optimizations are not important.
|
||||
if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
|
||||
|
||||
if(LLVM_LINKER_IS_GOLD)
|
||||
# With gold gc-sections is always safe.
|
||||
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " -Wl,--gc-sections")
|
||||
# Note that there is a bug with -Wl,--icf=safe so it is not safe
|
||||
# to enable. See https://sourceware.org/bugzilla/show_bug.cgi?id=17704.
|
||||
endif()
|
||||
|
||||
if(NOT LLVM_NO_DEAD_STRIP)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
# ld64's implementation of -dead_strip breaks tools that use plugins.
|
||||
# Pass -O3 to the linker. This enabled different optimizations on different
|
||||
# linkers.
|
||||
if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR WIN32))
|
||||
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " -Wl,-dead_strip")
|
||||
elseif(NOT WIN32 AND NOT LLVM_LINKER_IS_GOLD)
|
||||
# Object files are compiled with -ffunction-data-sections.
|
||||
# Versions of bfd ld < 2.23.1 have a bug in --gc-sections that breaks
|
||||
# tools that use plugins. Always pass --gc-sections once we require
|
||||
# a newer linker.
|
||||
LINK_FLAGS " -Wl,-O3")
|
||||
endif()
|
||||
|
||||
if(LLVM_LINKER_IS_GOLD)
|
||||
# With gold gc-sections is always safe.
|
||||
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " -Wl,--gc-sections")
|
||||
# Note that there is a bug with -Wl,--icf=safe so it is not safe
|
||||
# to enable. See https://sourceware.org/bugzilla/show_bug.cgi?id=17704.
|
||||
endif()
|
||||
|
||||
if(NOT LLVM_NO_DEAD_STRIP)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
# ld64's implementation of -dead_strip breaks tools that use plugins.
|
||||
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " -Wl,-dead_strip")
|
||||
elseif(NOT WIN32 AND NOT LLVM_LINKER_IS_GOLD)
|
||||
# Object files are compiled with -ffunction-data-sections.
|
||||
# Versions of bfd ld < 2.23.1 have a bug in --gc-sections that breaks
|
||||
# tools that use plugins. Always pass --gc-sections once we require
|
||||
# a newer linker.
|
||||
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " -Wl,--gc-sections")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction(add_link_opts)
|
||||
@ -334,6 +343,11 @@ function(llvm_add_library name)
|
||||
PREFIX ""
|
||||
)
|
||||
endif()
|
||||
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
SOVERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}
|
||||
VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX})
|
||||
endif()
|
||||
|
||||
if(ARG_MODULE OR ARG_SHARED)
|
||||
@ -393,6 +407,11 @@ function(llvm_add_library name)
|
||||
endfunction()
|
||||
|
||||
macro(add_llvm_library name)
|
||||
cmake_parse_arguments(ARG
|
||||
"SHARED"
|
||||
""
|
||||
""
|
||||
${ARGN})
|
||||
if( BUILD_SHARED_LIBS )
|
||||
llvm_add_library(${name} SHARED ${ARGN})
|
||||
else()
|
||||
@ -404,11 +423,28 @@ macro(add_llvm_library name)
|
||||
set_target_properties( ${name} PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
else()
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "LTO")
|
||||
if(ARG_SHARED OR BUILD_SHARED_LIBS)
|
||||
if(WIN32 OR CYGWIN)
|
||||
set(install_type RUNTIME)
|
||||
else()
|
||||
set(install_type LIBRARY)
|
||||
endif()
|
||||
else()
|
||||
set(install_type ARCHIVE)
|
||||
endif()
|
||||
|
||||
install(TARGETS ${name}
|
||||
EXPORT LLVMExports
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
|
||||
EXPORT LLVMExports
|
||||
${install_type} DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
COMPONENT ${name})
|
||||
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_custom_target(install-${name}
|
||||
DEPENDS ${name}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=${name}
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
endif()
|
||||
set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
|
||||
endif()
|
||||
@ -472,6 +508,12 @@ macro(add_llvm_executable name)
|
||||
endif( LLVM_COMMON_DEPENDS )
|
||||
endmacro(add_llvm_executable name)
|
||||
|
||||
function(export_executable_symbols target)
|
||||
if (NOT MSVC) # MSVC's linker doesn't support exporting all symbols.
|
||||
set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
set (LLVM_TOOLCHAIN_TOOLS
|
||||
llvm-ar
|
||||
@ -489,7 +531,16 @@ macro(add_llvm_tool name)
|
||||
if( LLVM_BUILD_TOOLS )
|
||||
install(TARGETS ${name}
|
||||
EXPORT LLVMExports
|
||||
RUNTIME DESTINATION bin)
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT ${name})
|
||||
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_custom_target(install-${name}
|
||||
DEPENDS ${name}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=${name}
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if( LLVM_BUILD_TOOLS )
|
||||
@ -514,6 +565,18 @@ endmacro(add_llvm_example name)
|
||||
macro(add_llvm_utility name)
|
||||
add_llvm_executable(${name} ${ARGN})
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Utils")
|
||||
if( LLVM_INSTALL_UTILS )
|
||||
install (TARGETS ${name}
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT ${name})
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_custom_target(install-${name}
|
||||
DEPENDS ${name}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DCMAKE_INSTALL_COMPONENT=${name}
|
||||
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
endif()
|
||||
endmacro(add_llvm_utility name)
|
||||
|
||||
|
||||
@ -584,12 +647,6 @@ function(add_unittest test_suite test_name)
|
||||
set(EXCLUDE_FROM_ALL ON)
|
||||
endif()
|
||||
|
||||
# Visual Studio 2012 only supports up to 8 template parameters in
|
||||
# std::tr1::tuple by default, but gtest requires 10
|
||||
if (MSVC AND MSVC_VERSION EQUAL 1700)
|
||||
list(APPEND LLVM_COMPILE_DEFINITIONS _VARIADIC_MAX=10)
|
||||
endif ()
|
||||
|
||||
include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include)
|
||||
if (NOT LLVM_ENABLE_THREADS)
|
||||
list(APPEND LLVM_COMPILE_DEFINITIONS GTEST_HAS_PTHREAD=0)
|
||||
@ -719,18 +776,20 @@ function(add_lit_target target comment)
|
||||
foreach(param ${ARG_PARAMS})
|
||||
list(APPEND LIT_COMMAND --param ${param})
|
||||
endforeach()
|
||||
if( ARG_DEPENDS )
|
||||
if (ARG_DEFAULT_ARGS)
|
||||
add_custom_target(${target}
|
||||
COMMAND ${LIT_COMMAND} ${ARG_DEFAULT_ARGS}
|
||||
COMMENT "${comment}"
|
||||
${cmake_3_2_USES_TERMINAL}
|
||||
)
|
||||
add_dependencies(${target} ${ARG_DEPENDS})
|
||||
else()
|
||||
add_custom_target(${target}
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, no tools built.")
|
||||
message(STATUS "${target} does nothing.")
|
||||
endif()
|
||||
if (ARG_DEPENDS)
|
||||
add_dependencies(${target} ${ARG_DEPENDS})
|
||||
endif()
|
||||
|
||||
# Tests should be excluded from "Build Solution".
|
||||
set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)
|
||||
@ -757,3 +816,30 @@ function(add_lit_testsuite target comment)
|
||||
ARGS ${ARG_ARGS}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(add_lit_testsuites project directory)
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||
parse_arguments(ARG "PARAMS;DEPENDS;ARGS" "" ${ARGN})
|
||||
file(GLOB_RECURSE litCfg ${directory}/lit*.cfg)
|
||||
set(lit_suites)
|
||||
foreach(f ${litCfg})
|
||||
get_filename_component(dir ${f} DIRECTORY)
|
||||
set(lit_suites ${lit_suites} ${dir})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES lit_suites)
|
||||
foreach(dir ${lit_suites})
|
||||
string(REPLACE ${directory} "" name_slash ${dir})
|
||||
if (name_slash)
|
||||
string(REPLACE "/" "-" name_slash ${name_slash})
|
||||
string(REPLACE "\\" "-" name_dashes ${name_slash})
|
||||
string(TOLOWER "${project}${name_dashes}" name_var)
|
||||
add_lit_target("check-${name_var}" "Running lit suite ${dir}"
|
||||
${dir}
|
||||
PARAMS ${ARG_PARAMS}
|
||||
DEPENDS ${ARG_DEPENDS}
|
||||
ARGS ${ARG_ARGS}
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
@ -2,13 +2,18 @@
|
||||
|
||||
INCLUDE(CheckCXXSourceCompiles)
|
||||
|
||||
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
|
||||
if (HAVE_LIBATOMIC)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_function_exists(__atomic_fetch_add_4 HAVE___ATOMIC_FETCH_ADD_4)
|
||||
if( NOT HAVE___ATOMIC_FETCH_ADD_4 )
|
||||
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
|
||||
set(HAVE_LIBATOMIC False)
|
||||
if( HAVE_LIBATOMIC )
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#ifdef _MSC_VER
|
||||
#include <Intrin.h> /* Workaround for PR19898. */
|
||||
#include <windows.h>
|
||||
#endif
|
||||
int main() {
|
||||
|
@ -1,33 +1,55 @@
|
||||
if(NOT DEFINED LLVM_NATIVE_BUILD)
|
||||
set(LLVM_NATIVE_BUILD "${CMAKE_BINARY_DIR}/native")
|
||||
message(STATUS "Setting native build dir to ${LLVM_NATIVE_BUILD}")
|
||||
endif(NOT DEFINED LLVM_NATIVE_BUILD)
|
||||
function(llvm_create_cross_target_internal target_name toochain buildtype)
|
||||
|
||||
add_custom_command(OUTPUT ${LLVM_NATIVE_BUILD}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${LLVM_NATIVE_BUILD}
|
||||
COMMENT "Creating ${LLVM_NATIVE_BUILD}...")
|
||||
if(NOT DEFINED LLVM_${target_name}_BUILD)
|
||||
set(LLVM_${target_name}_BUILD "${CMAKE_BINARY_DIR}/${target_name}")
|
||||
set(LLVM_${target_name}_BUILD ${LLVM_${target_name}_BUILD} PARENT_SCOPE)
|
||||
message(STATUS "Setting native build dir to " ${LLVM_${target_name}_BUILD})
|
||||
endif(NOT DEFINED LLVM_${target_name}_BUILD)
|
||||
|
||||
add_custom_command(OUTPUT ${LLVM_NATIVE_BUILD}/CMakeCache.txt
|
||||
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${LLVM_NATIVE_BUILD}
|
||||
DEPENDS ${LLVM_NATIVE_BUILD}
|
||||
COMMENT "Configuring native LLVM...")
|
||||
if (EXISTS ${LLVM_MAIN_SRC_DIR}/cmake/platforms/${toolchain}.cmake)
|
||||
set(CROSS_TOOLCHAIN_FLAGS_${target_name}
|
||||
-DCMAKE_TOOLCHAIN_FILE=\"${LLVM_MAIN_SRC_DIR}/cmake/platforms/${toolchain}.cmake\"
|
||||
CACHE STRING "Toolchain file for ${target_name}")
|
||||
endif()
|
||||
|
||||
add_custom_target(ConfigureNativeLLVM DEPENDS ${LLVM_NATIVE_BUILD}/CMakeCache.txt)
|
||||
add_custom_command(OUTPUT ${LLVM_${target_name}_BUILD}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${LLVM_${target_name}_BUILD}
|
||||
COMMENT "Creating ${LLVM_${target_name}_BUILD}...")
|
||||
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${LLVM_NATIVE_BUILD})
|
||||
add_custom_command(OUTPUT ${LLVM_${target_name}_BUILD}/CMakeCache.txt
|
||||
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
|
||||
${CROSS_TOOLCHAIN_FLAGS_${target_name}} ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${LLVM_${target_name}_BUILD}
|
||||
DEPENDS ${LLVM_${target_name}_BUILD}
|
||||
COMMENT "Configuring ${target_name} LLVM...")
|
||||
|
||||
if(NOT IS_DIRECTORY ${LLVM_NATIVE_BUILD})
|
||||
if(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(HOST_SYSROOT_FLAGS -DCMAKE_OSX_SYSROOT=macosx)
|
||||
endif(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Darwin")
|
||||
add_custom_target(CONFIGURE_LLVM_${target_name}
|
||||
DEPENDS ${LLVM_${target_name}_BUILD}/CMakeCache.txt)
|
||||
|
||||
message(STATUS "Configuring native build...")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
${LLVM_NATIVE_BUILD} )
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
|
||||
${LLVM_${target_name}_BUILD})
|
||||
|
||||
message(STATUS "Configuring native targets...")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release
|
||||
-G "${CMAKE_GENERATOR}" -DLLVM_TARGETS_TO_BUILD=${LLVM_TARGETS_TO_BUILD} ${HOST_SYSROOT_FLAGS} ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${LLVM_NATIVE_BUILD} )
|
||||
endif(NOT IS_DIRECTORY ${LLVM_NATIVE_BUILD})
|
||||
if(NOT IS_DIRECTORY ${LLVM_${target_name}_BUILD})
|
||||
|
||||
|
||||
message(STATUS "Configuring ${target_name} build...")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
${LLVM_${target_name}_BUILD} )
|
||||
|
||||
message(STATUS "Configuring ${target_name} targets...")
|
||||
if (buildtype)
|
||||
set(build_type_flags "-DCMAKE_BUILD_TYPE=${buildtype}")
|
||||
endif()
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} ${build_type_flags}
|
||||
-G "${CMAKE_GENERATOR}" -DLLVM_TARGETS_TO_BUILD=${LLVM_TARGETS_TO_BUILD}
|
||||
${CROSS_TOOLCHAIN_FLAGS_${target_name}} ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${LLVM_${target_name}_BUILD} )
|
||||
endif(NOT IS_DIRECTORY ${LLVM_${target_name}_BUILD})
|
||||
|
||||
endfunction()
|
||||
|
||||
function(llvm_create_cross_target target_name sysroot)
|
||||
llvm_create_cross_target_internal(${target_name} ${sysroot} ${CMAKE_BUILD_TYPE})
|
||||
endfunction()
|
||||
|
||||
llvm_create_cross_target_internal(NATIVE "" Release)
|
||||
|
@ -21,11 +21,16 @@ if(NOT LLVM_FORCE_USE_OLD_TOOLCHAIN)
|
||||
message(FATAL_ERROR "Host Clang version must be at least 3.1!")
|
||||
endif()
|
||||
|
||||
# Also test that we aren't using too old of a version of libstdc++ with the
|
||||
# Clang compiler. This is tricky as there is no real way to check the
|
||||
# version of libstdc++ directly. Instead we test for a known bug in
|
||||
# libstdc++4.6 that is fixed in libstdc++4.7.
|
||||
if(NOT LLVM_ENABLE_LIBCXX)
|
||||
if (CMAKE_CXX_SIMULATE_ID MATCHES "MSVC")
|
||||
if (CMAKE_CXX_SIMULATE_VERSION VERSION_LESS 18.0)
|
||||
message(FATAL_ERROR "Host Clang must have at least -fms-compatibility-version=18.0")
|
||||
endif()
|
||||
set(CLANG_CL 1)
|
||||
elseif(NOT LLVM_ENABLE_LIBCXX)
|
||||
# Otherwise, test that we aren't using too old of a version of libstdc++
|
||||
# with the Clang compiler. This is tricky as there is no real way to
|
||||
# check the version of libstdc++ directly. Instead we test for a known
|
||||
# bug in libstdc++4.6 that is fixed in libstdc++4.7.
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
set(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++0x")
|
||||
@ -41,8 +46,11 @@ int main() { return (float)x; }"
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0)
|
||||
message(FATAL_ERROR "Host Visual Studio must be at least 2012 (MSVC 17.0)")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
|
||||
message(FATAL_ERROR "Host Visual Studio must be at least 2013")
|
||||
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0.31101)
|
||||
message(WARNING "Host Visual Studio should at least be 2013 Update 4 (MSVC 18.0.31101)"
|
||||
" due to miscompiles from earlier versions")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@ -70,6 +78,23 @@ if( LLVM_ENABLE_ASSERTIONS )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(TOUPPER "${LLVM_ABI_BREAKING_CHECKS}" uppercase_LLVM_ABI_BREAKING_CHECKS)
|
||||
|
||||
if( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL "WITH_ASSERTS" )
|
||||
if( LLVM_ENABLE_ASSERTIONS )
|
||||
set( LLVM_ENABLE_ABI_BREAKING_CHECKS 1 )
|
||||
endif()
|
||||
elseif( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL "FORCE_ON" )
|
||||
set( LLVM_ENABLE_ABI_BREAKING_CHECKS 1 )
|
||||
elseif( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL "FORCE_OFF" )
|
||||
# We don't need to do anything special to turn off ABI breaking checks.
|
||||
elseif( NOT DEFINED LLVM_ABI_BREAKING_CHECKS )
|
||||
# Treat LLVM_ABI_BREAKING_CHECKS like "FORCE_OFF" when it has not been
|
||||
# defined.
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown value for LLVM_ABI_BREAKING_CHECKS: \"${LLVM_ABI_BREAKING_CHECKS}\"!")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
|
||||
if(CYGWIN)
|
||||
@ -104,6 +129,15 @@ if(APPLE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
|
||||
endif()
|
||||
|
||||
# Pass -Wl,-z,defs. This makes sure all symbols are defined. Otherwise a DSO
|
||||
# build might work on ELF but fail on MachO/COFF.
|
||||
if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR WIN32 OR
|
||||
${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") AND
|
||||
NOT LLVM_USE_SANITIZER)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
|
||||
endif()
|
||||
|
||||
|
||||
function(append value)
|
||||
foreach(variable ${ARGN})
|
||||
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
|
||||
@ -236,7 +270,9 @@ if( MSVC )
|
||||
-D_CRT_NONSTDC_NO_WARNINGS
|
||||
-D_SCL_SECURE_NO_DEPRECATE
|
||||
-D_SCL_SECURE_NO_WARNINGS
|
||||
)
|
||||
|
||||
set(msvc_warning_flags
|
||||
# Disabled warnings.
|
||||
-wd4146 # Suppress 'unary minus operator applied to unsigned type, result still unsigned'
|
||||
-wd4180 # Suppress 'qualifier applied to function type has no meaning; ignored'
|
||||
@ -255,7 +291,31 @@ if( MSVC )
|
||||
-wd4624 # Suppress ''derived class' : destructor could not be generated because a base class destructor is inaccessible'
|
||||
-wd4722 # Suppress 'function' : destructor never returns, potential memory leak
|
||||
-wd4800 # Suppress ''type' : forcing value to bool 'true' or 'false' (performance warning)'
|
||||
|
||||
-wd4100 # Suppress 'unreferenced formal parameter'
|
||||
-wd4127 # Suppress 'conditional expression is constant'
|
||||
-wd4512 # Suppress 'assignment operator could not be generated'
|
||||
-wd4505 # Suppress 'unreferenced local function has been removed'
|
||||
-wd4610 # Suppress '<class> can never be instantiated'
|
||||
-wd4510 # Suppress 'default constructor could not be generated'
|
||||
-wd4702 # Suppress 'unreachable code'
|
||||
-wd4245 # Suppress 'signed/unsigned mismatch'
|
||||
-wd4706 # Suppress 'assignment within conditional expression'
|
||||
-wd4310 # Suppress 'cast truncates constant value'
|
||||
-wd4701 # Suppress 'potentially uninitialized local variable'
|
||||
-wd4703 # Suppress 'potentially uninitialized local pointer variable'
|
||||
-wd4389 # Suppress 'signed/unsigned mismatch'
|
||||
-wd4611 # Suppress 'interaction between '_setjmp' and C++ object destruction is non-portable'
|
||||
-wd4805 # Suppress 'unsafe mix of type <type> and type <type> in operation'
|
||||
-wd4204 # Suppress 'nonstandard extension used : non-constant aggregate initializer'
|
||||
|
||||
# Idelly, we'd like this warning to be enabled, but MSVC 2013 doesn't
|
||||
# support the 'aligned' attribute in the way that clang sources requires (for
|
||||
# any code that uses the LLVM_ALIGNAS marco), so this is must be disabled to
|
||||
# avoid unwanted alignment warnings.
|
||||
# When we switch to requiring a version of MSVC that supports the 'alignas'
|
||||
# specifier (MSVC 2015?) this warning can be re-enabled.
|
||||
-wd4324 # Suppress 'structure was padded due to __declspec(align())'
|
||||
|
||||
# Promoted warnings.
|
||||
-w14062 # Promote 'enumerator in switch of enum is not handled' to level 1 warning.
|
||||
|
||||
@ -265,14 +325,31 @@ if( MSVC )
|
||||
|
||||
# Enable warnings
|
||||
if (LLVM_ENABLE_WARNINGS)
|
||||
add_llvm_definitions( /W4 )
|
||||
append("/W4" msvc_warning_flags)
|
||||
# CMake appends /W3 by default, and having /W3 followed by /W4 will result in
|
||||
# cl : Command line warning D9025 : overriding '/W3' with '/W4'. Since this is
|
||||
# a command line warning and not a compiler warning, it cannot be suppressed except
|
||||
# by fixing the command line.
|
||||
string(REGEX REPLACE " /W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string(REGEX REPLACE " /W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
if (LLVM_ENABLE_PEDANTIC)
|
||||
# No MSVC equivalent available
|
||||
endif (LLVM_ENABLE_PEDANTIC)
|
||||
endif (LLVM_ENABLE_WARNINGS)
|
||||
if (LLVM_ENABLE_WERROR)
|
||||
add_llvm_definitions( /WX )
|
||||
append("/WX" msvc_warning_flags)
|
||||
endif (LLVM_ENABLE_WERROR)
|
||||
|
||||
foreach(flag ${msvc_warning_flags})
|
||||
append("${flag}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
endforeach(flag)
|
||||
|
||||
# Disable sized deallocation if the flag is supported. MSVC fails to compile
|
||||
# the operator new overload in User otherwise.
|
||||
check_c_compiler_flag("/WX /Zc:sizedDealloc-" SUPPORTS_SIZED_DEALLOC)
|
||||
append_if(SUPPORTS_SIZED_DEALLOC "/Zc:sizedDealloc-" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
|
||||
elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
|
||||
if (LLVM_ENABLE_WARNINGS)
|
||||
append("-Wall -W -Wno-unused-parameter -Wwrite-strings" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
@ -390,17 +467,25 @@ if(LLVM_USE_SANITIZER)
|
||||
endif()
|
||||
elseif (LLVM_USE_SANITIZER STREQUAL "Undefined")
|
||||
append_common_sanitizer_flags()
|
||||
append("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover"
|
||||
append("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all"
|
||||
CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
elseif (LLVM_USE_SANITIZER STREQUAL "Thread")
|
||||
append_common_sanitizer_flags()
|
||||
append("-fsanitize=thread" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
elseif (LLVM_USE_SANITIZER STREQUAL "Address;Undefined" OR
|
||||
LLVM_USE_SANITIZER STREQUAL "Undefined;Address")
|
||||
append_common_sanitizer_flags()
|
||||
append("-fsanitize=address,undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all"
|
||||
CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
else()
|
||||
message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
|
||||
endif()
|
||||
if (LLVM_USE_SANITIZE_COVERAGE)
|
||||
append("-fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Turn on -gsplit-dwarf if requested
|
||||
@ -424,7 +509,8 @@ endif()
|
||||
# But MinSizeRel seems to add that automatically, so maybe disable these
|
||||
# flags instead if LLVM_NO_DEAD_STRIP is set.
|
||||
if(NOT CYGWIN AND NOT WIN32)
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND
|
||||
NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
|
||||
check_c_compiler_flag("-Werror -fno-function-sections" C_SUPPORTS_FNO_FUNCTION_SECTIONS)
|
||||
if (C_SUPPORTS_FNO_FUNCTION_SECTIONS)
|
||||
# Don't add -ffunction-section if it can be disabled with -fno-function-sections.
|
||||
|
@ -12,22 +12,28 @@ if(NOT DEFINED LLVM_STDLIB_HANDLED)
|
||||
set(LLVM_COMPILER_IS_GCC_COMPATIBLE ON)
|
||||
endif()
|
||||
|
||||
function(append_if condition value)
|
||||
if(${condition})
|
||||
foreach(variable ${ARGN})
|
||||
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
|
||||
endforeach(variable)
|
||||
endif()
|
||||
function(append value)
|
||||
foreach(variable ${ARGN})
|
||||
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
|
||||
endforeach(variable)
|
||||
endfunction()
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
if(LLVM_ENABLE_LIBCXX)
|
||||
if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
|
||||
check_cxx_compiler_flag("-stdlib=libc++" CXX_SUPPORTS_STDLIB)
|
||||
append_if(CXX_SUPPORTS_STDLIB "-stdlib=libc++" CMAKE_CXX_FLAGS)
|
||||
append_if(CXX_SUPPORTS_STDLIB "-stdlib=libc++" CMAKE_EXE_LINKER_FLAGS)
|
||||
append_if(CXX_SUPPORTS_STDLIB "-stdlib=libc++" CMAKE_SHARED_LINKER_FLAGS)
|
||||
append_if(CXX_SUPPORTS_STDLIB "-stdlib=libc++" CMAKE_MODULE_LINKER_FLAGS)
|
||||
if(CXX_SUPPORTS_STDLIB)
|
||||
append("-stdlib=libc++"
|
||||
CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS
|
||||
CMAKE_MODULE_LINKER_FLAGS)
|
||||
if(LLVM_ENABLE_LIBCXXABI)
|
||||
append("-lc++abi"
|
||||
CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS
|
||||
CMAKE_MODULE_LINKER_FLAGS)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Can't specify libc++ with '-stdlib='")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Not sure how to specify libc++ for this compiler")
|
||||
endif()
|
||||
|
@ -41,9 +41,9 @@ function(explicit_llvm_config executable)
|
||||
llvm_map_components_to_libnames(LIBRARIES ${link_components})
|
||||
get_target_property(t ${executable} TYPE)
|
||||
if("x${t}" STREQUAL "xSTATIC_LIBRARY")
|
||||
target_link_libraries(${executable} ${cmake_2_8_12_INTERFACE} ${LIBRARIES})
|
||||
target_link_libraries(${executable} INTERFACE ${LIBRARIES})
|
||||
elseif("x${t}" STREQUAL "xSHARED_LIBRARY" OR "x${t}" STREQUAL "xMODULE_LIBRARY")
|
||||
target_link_libraries(${executable} ${cmake_2_8_12_PRIVATE} ${LIBRARIES})
|
||||
target_link_libraries(${executable} PRIVATE ${LIBRARIES})
|
||||
else()
|
||||
# Use plain form for legacy user.
|
||||
target_link_libraries(${executable} ${LIBRARIES})
|
||||
@ -132,6 +132,41 @@ function(llvm_map_components_to_libnames out_libs)
|
||||
# already processed
|
||||
elseif( c STREQUAL "all" )
|
||||
list(APPEND expanded_components ${LLVM_AVAILABLE_LIBS})
|
||||
elseif( c STREQUAL "AllTargetsAsmPrinters" )
|
||||
# Link all the asm printers from all the targets
|
||||
foreach(t ${LLVM_TARGETS_TO_BUILD})
|
||||
if( TARGET LLVM${t}AsmPrinter )
|
||||
list(APPEND expanded_components "LLVM${t}AsmPrinter")
|
||||
endif()
|
||||
endforeach(t)
|
||||
elseif( c STREQUAL "AllTargetsAsmParsers" )
|
||||
# Link all the asm parsers from all the targets
|
||||
foreach(t ${LLVM_TARGETS_TO_BUILD})
|
||||
if( TARGET LLVM${t}AsmParser )
|
||||
list(APPEND expanded_components "LLVM${t}AsmParser")
|
||||
endif()
|
||||
endforeach(t)
|
||||
elseif( c STREQUAL "AllTargetsDescs" )
|
||||
# Link all the descs from all the targets
|
||||
foreach(t ${LLVM_TARGETS_TO_BUILD})
|
||||
if( TARGET LLVM${t}Desc )
|
||||
list(APPEND expanded_components "LLVM${t}Desc")
|
||||
endif()
|
||||
endforeach(t)
|
||||
elseif( c STREQUAL "AllTargetsDisassemblers" )
|
||||
# Link all the disassemblers from all the targets
|
||||
foreach(t ${LLVM_TARGETS_TO_BUILD})
|
||||
if( TARGET LLVM${t}Disassembler )
|
||||
list(APPEND expanded_components "LLVM${t}Disassembler")
|
||||
endif()
|
||||
endforeach(t)
|
||||
elseif( c STREQUAL "AllTargetsInfos" )
|
||||
# Link all the infos from all the targets
|
||||
foreach(t ${LLVM_TARGETS_TO_BUILD})
|
||||
if( TARGET LLVM${t}Info )
|
||||
list(APPEND expanded_components "LLVM${t}Info")
|
||||
endif()
|
||||
endforeach(t)
|
||||
else( NOT idx LESS 0 )
|
||||
# Canonize the component name:
|
||||
string(TOUPPER "${c}" capitalized)
|
||||
|
@ -21,6 +21,8 @@ set(LLVM_TARGETS_WITH_JIT @LLVM_TARGETS_WITH_JIT@)
|
||||
|
||||
set(TARGET_TRIPLE "@TARGET_TRIPLE@")
|
||||
|
||||
set(LLVM_ABI_BREAKING_CHECKS @LLVM_ABI_BREAKING_CHECKS@)
|
||||
|
||||
set(LLVM_ENABLE_ASSERTIONS @LLVM_ENABLE_ASSERTIONS@)
|
||||
|
||||
set(LLVM_ENABLE_EH @LLVM_ENABLE_EH@)
|
||||
|
@ -28,26 +28,39 @@ macro(add_td_sources srcs)
|
||||
endif()
|
||||
endmacro(add_td_sources)
|
||||
|
||||
function(add_header_files_for_glob hdrs_out glob)
|
||||
file(GLOB hds ${glob})
|
||||
set(${hdrs_out} ${hds} PARENT_SCOPE)
|
||||
endfunction(add_header_files_for_glob)
|
||||
|
||||
macro(add_header_files srcs)
|
||||
file(GLOB hds *.h)
|
||||
if( hds )
|
||||
set_source_files_properties(${hds} PROPERTIES HEADER_FILE_ONLY ON)
|
||||
list(APPEND ${srcs} ${hds})
|
||||
endif()
|
||||
endmacro(add_header_files)
|
||||
function(find_all_header_files hdrs_out additional_headerdirs)
|
||||
add_header_files_for_glob(hds *.h)
|
||||
list(APPEND all_headers ${hds})
|
||||
|
||||
foreach(additional_dir ${additional_headerdirs})
|
||||
add_header_files_for_glob(hds "${additional_dir}/*.h")
|
||||
list(APPEND all_headers ${hds})
|
||||
add_header_files_for_glob(hds "${additional_dir}/*.inc")
|
||||
list(APPEND all_headers ${hds})
|
||||
endforeach(additional_dir)
|
||||
|
||||
set( ${hdrs_out} ${all_headers} PARENT_SCOPE )
|
||||
endfunction(find_all_header_files)
|
||||
|
||||
|
||||
function(llvm_process_sources OUT_VAR)
|
||||
cmake_parse_arguments(ARG "" "" "ADDITIONAL_HEADERS" ${ARGN})
|
||||
cmake_parse_arguments(ARG "" "" "ADDITIONAL_HEADERS;ADDITIONAL_HEADER_DIRS" ${ARGN})
|
||||
set(sources ${ARG_UNPARSED_ARGUMENTS})
|
||||
llvm_check_source_file_list( ${sources} )
|
||||
if( MSVC_IDE OR XCODE )
|
||||
# This adds .td and .h files to the Visual Studio solution:
|
||||
add_td_sources(sources)
|
||||
add_header_files(sources)
|
||||
find_all_header_files(hdrs "${ARG_ADDITIONAL_HEADER_DIRS}")
|
||||
if (hdrs)
|
||||
set_source_files_properties(${hdrs} PROPERTIES HEADER_FILE_ONLY ON)
|
||||
endif()
|
||||
set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)
|
||||
list(APPEND sources ${ARG_ADDITIONAL_HEADERS})
|
||||
list(APPEND sources ${ARG_ADDITIONAL_HEADERS} ${hdrs})
|
||||
endif()
|
||||
|
||||
set( ${OUT_VAR} ${sources} PARENT_SCOPE )
|
||||
|
@ -21,6 +21,12 @@ else
|
||||
LLVM_ENABLE_ASSERTIONS := 1
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_ABI_BREAKING_CHECKS),1)
|
||||
LLVM_ABI_BREAKING_CHECKS := FORCE_ON
|
||||
else
|
||||
LLVM_ABI_BREAKING_CHECKS := FORCE_OFF
|
||||
endif
|
||||
|
||||
ifeq ($(REQUIRES_EH),1)
|
||||
LLVM_ENABLE_EH := 1
|
||||
else
|
||||
@ -63,6 +69,7 @@ $(PROJ_OBJ_DIR)/LLVMConfig.cmake: LLVMConfig.cmake.in Makefile $(LLVMBuildCMakeF
|
||||
-e 's/@LLVM_TARGETS_TO_BUILD@/'"$(TARGETS_TO_BUILD)"'/' \
|
||||
-e 's/@LLVM_TARGETS_WITH_JIT@/'"$(TARGETS_WITH_JIT)"'/' \
|
||||
-e 's/@TARGET_TRIPLE@/'"$(TARGET_TRIPLE)"'/' \
|
||||
-e 's/@LLVM_ABI_BREAKING_CHECKS@/'"$(LLVM_ABI_BREAKING_CHECKS)"'/' \
|
||||
-e 's/@LLVM_ENABLE_ASSERTIONS@/'"$(LLVM_ENABLE_ASSERTIONS)"'/' \
|
||||
-e 's/@LLVM_ENABLE_EH@/'"$(LLVM_ENABLE_EH)"'/' \
|
||||
-e 's/@LLVM_ENABLE_RTTI@/'"$(LLVM_ENABLE_RTTI)"'/' \
|
||||
|
@ -32,7 +32,7 @@ function(tablegen project ofn)
|
||||
# The file in LLVM_TARGET_DEFINITIONS may be not in the current
|
||||
# directory and local_tds may not contain it, so we must
|
||||
# explicitly list it here:
|
||||
DEPENDS ${${project}_TABLEGEN_EXE} ${local_tds} ${global_tds}
|
||||
DEPENDS ${${project}_TABLEGEN_TARGET} ${local_tds} ${global_tds}
|
||||
${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
|
||||
COMMENT "Building ${ofn}..."
|
||||
)
|
||||
@ -90,21 +90,20 @@ macro(add_tablegen target project)
|
||||
|
||||
# Effective tblgen executable to be used:
|
||||
set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN} PARENT_SCOPE)
|
||||
set(${project}_TABLEGEN_TARGET ${${project}_TABLEGEN} PARENT_SCOPE)
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
if(LLVM_USE_HOST_TOOLS)
|
||||
if( ${${project}_TABLEGEN} STREQUAL "${target}" )
|
||||
set(${project}_TABLEGEN_EXE "${LLVM_NATIVE_BUILD}/bin/${target}")
|
||||
set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN_EXE} PARENT_SCOPE)
|
||||
|
||||
add_custom_command(OUTPUT ${${project}_TABLEGEN_EXE}
|
||||
COMMAND ${CMAKE_COMMAND} --build . --target ${target} --config $<CONFIGURATION>
|
||||
DEPENDS ${LLVM_NATIVE_BUILD}/CMakeCache.txt
|
||||
COMMAND ${CMAKE_COMMAND} --build . --target ${target} --config Release
|
||||
DEPENDS CONFIGURE_LLVM_NATIVE ${target}
|
||||
WORKING_DIRECTORY ${LLVM_NATIVE_BUILD}
|
||||
COMMENT "Building native TableGen...")
|
||||
add_custom_target(${project}NativeTableGen DEPENDS ${${project}_TABLEGEN_EXE})
|
||||
add_dependencies(${project}NativeTableGen ConfigureNativeLLVM)
|
||||
|
||||
add_dependencies(${target} ${project}NativeTableGen)
|
||||
add_custom_target(${project}-tablegen-host DEPENDS ${${project}_TABLEGEN_EXE})
|
||||
set(${project}_TABLEGEN_TARGET ${project}-tablegen-host PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -15,11 +15,25 @@ SET(CMAKE_C_COMPILER_WORKS True)
|
||||
SET(DARWIN_TARGET_OS_NAME ios)
|
||||
|
||||
IF(NOT DEFINED ENV{SDKROOT})
|
||||
MESSAGE(FATAL_ERROR "SDKROOT env var must be set: " $ENV{SDKROOT})
|
||||
execute_process(COMMAND xcodebuild -version -sdk iphoneos Path
|
||||
OUTPUT_VARIABLE SDKROOT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
ELSE()
|
||||
execute_process(COMMAND xcodebuild -version -sdk $ENV{SDKROOT} Path
|
||||
OUTPUT_VARIABLE SDKROOT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT EXISTS ${SDKROOT})
|
||||
MESSAGE(FATAL_ERROR "SDKROOT could not be detected!")
|
||||
ENDIF()
|
||||
|
||||
set(CMAKE_OSX_SYSROOT ${SDKROOT})
|
||||
|
||||
IF(NOT CMAKE_C_COMPILER)
|
||||
execute_process(COMMAND xcrun -sdk iphoneos -find clang
|
||||
execute_process(COMMAND xcrun -sdk ${SDKROOT} -find clang
|
||||
OUTPUT_VARIABLE CMAKE_C_COMPILER
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
@ -27,21 +41,39 @@ IF(NOT CMAKE_C_COMPILER)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT CMAKE_CXX_COMPILER)
|
||||
execute_process(COMMAND xcrun -sdk iphoneos -find clang++
|
||||
execute_process(COMMAND xcrun -sdk ${SDKROOT} -find clang++
|
||||
OUTPUT_VARIABLE CMAKE_CXX_COMPILER
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "Using c compiler ${CMAKE_CXX_COMPILER}")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT CMAKE_AR)
|
||||
execute_process(COMMAND xcrun -sdk ${SDKROOT} -find ar
|
||||
OUTPUT_VARIABLE CMAKE_AR_val
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
SET(CMAKE_AR ${CMAKE_AR_val} CACHE FILEPATH "Archiver")
|
||||
message(STATUS "Using ar ${CMAKE_AR}")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT CMAKE_RANLIB)
|
||||
execute_process(COMMAND xcrun -sdk ${SDKROOT} -find ranlib
|
||||
OUTPUT_VARIABLE CMAKE_RANLIB_val
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
SET(CMAKE_RANLIB ${CMAKE_RANLIB_val} CACHE FILEPATH "Ranlib")
|
||||
message(STATUS "Using ranlib ${CMAKE_RANLIB}")
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED IOS_MIN_TARGET)
|
||||
execute_process(COMMAND xcodebuild -sdk iphoneos -version SDKVersion
|
||||
execute_process(COMMAND xcodebuild -sdk ${SDKROOT} -version SDKVersion
|
||||
OUTPUT_VARIABLE IOS_MIN_TARGET
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
ENDIF()
|
||||
|
||||
SET(IOS_COMMON_FLAGS "-isysroot $ENV{SDKROOT} -mios-version-min=${IOS_MIN_TARGET}")
|
||||
SET(IOS_COMMON_FLAGS "-mios-version-min=${IOS_MIN_TARGET}")
|
||||
SET(CMAKE_C_FLAGS "${IOS_COMMON_FLAGS}" CACHE STRING "toolchain_cflags" FORCE)
|
||||
SET(CMAKE_CXX_FLAGS "${IOS_COMMON_FLAGS}" CACHE STRING "toolchain_cxxflags" FORCE)
|
||||
SET(CMAKE_LINK_FLAGS "${IOS_COMMON_FLAGS}" CACHE STRING "toolchain_linkflags" FORCE)
|
||||
|
@ -672,7 +672,7 @@ for each library name referenced.
|
||||
MODULE_CODE_GLOBALVAR Record
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``[GLOBALVAR, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr, dllstorageclass]``
|
||||
``[GLOBALVAR, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr, externally_initialized, dllstorageclass, comdat]``
|
||||
|
||||
The ``GLOBALVAR`` record (code 7) marks the declaration or definition of a
|
||||
global variable. The operand fields are:
|
||||
|
70
docs/BitSets.rst
Normal file
70
docs/BitSets.rst
Normal file
@ -0,0 +1,70 @@
|
||||
=======
|
||||
Bitsets
|
||||
=======
|
||||
|
||||
This is a mechanism that allows IR modules to co-operatively build pointer
|
||||
sets corresponding to addresses within a given set of globals. One example
|
||||
of a use case for this is to allow a C++ program to efficiently verify (at
|
||||
each call site) that a vtable pointer is in the set of valid vtable pointers
|
||||
for the type of the class or its derived classes.
|
||||
|
||||
To use the mechanism, a client creates a global metadata node named
|
||||
``llvm.bitsets``. Each element is a metadata node with three elements:
|
||||
the first is a metadata string containing an identifier for the bitset,
|
||||
the second is a global variable and the third is a byte offset into the
|
||||
global variable.
|
||||
|
||||
This will cause a link-time optimization pass to generate bitsets from the
|
||||
memory addresses referenced from the elements of the bitset metadata. The pass
|
||||
will lay out the referenced globals consecutively, so their definitions must
|
||||
be available at LTO time. The `GlobalLayoutBuilder`_ class is responsible for
|
||||
laying out the globals efficiently to minimize the sizes of the underlying
|
||||
bitsets. An intrinsic, :ref:`llvm.bitset.test <bitset.test>`, generates code
|
||||
to test whether a given pointer is a member of a bitset.
|
||||
|
||||
:Example:
|
||||
|
||||
::
|
||||
|
||||
target datalayout = "e-p:32:32"
|
||||
|
||||
@a = internal global i32 0
|
||||
@b = internal global i32 0
|
||||
@c = internal global i32 0
|
||||
@d = internal global [2 x i32] [i32 0, i32 0]
|
||||
|
||||
!llvm.bitsets = !{!0, !1, !2, !3, !4}
|
||||
|
||||
!0 = !{!"bitset1", i32* @a, i32 0}
|
||||
!1 = !{!"bitset1", i32* @b, i32 0}
|
||||
!2 = !{!"bitset2", i32* @b, i32 0}
|
||||
!3 = !{!"bitset2", i32* @c, i32 0}
|
||||
!4 = !{!"bitset2", i32* @d, i32 4}
|
||||
|
||||
declare i1 @llvm.bitset.test(i8* %ptr, metadata %bitset) nounwind readnone
|
||||
|
||||
define i1 @foo(i32* %p) {
|
||||
%pi8 = bitcast i32* %p to i8*
|
||||
%x = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset1")
|
||||
ret i1 %x
|
||||
}
|
||||
|
||||
define i1 @bar(i32* %p) {
|
||||
%pi8 = bitcast i32* %p to i8*
|
||||
%x = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset2")
|
||||
ret i1 %x
|
||||
}
|
||||
|
||||
define void @main() {
|
||||
%a1 = call i1 @foo(i32* @a) ; returns 1
|
||||
%b1 = call i1 @foo(i32* @b) ; returns 1
|
||||
%c1 = call i1 @foo(i32* @c) ; returns 0
|
||||
%a2 = call i1 @bar(i32* @a) ; returns 0
|
||||
%b2 = call i1 @bar(i32* @b) ; returns 1
|
||||
%c2 = call i1 @bar(i32* @c) ; returns 1
|
||||
%d02 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 0)) ; returns 0
|
||||
%d12 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 1)) ; returns 1
|
||||
ret void
|
||||
}
|
||||
|
||||
.. _GlobalLayoutBuilder: http://llvm.org/klaus/llvm/blob/master/include/llvm/Transforms/IPO/LowerBitSets.h
|
@ -115,3 +115,26 @@ CFG Modifications
|
||||
Branch Weight Metatada is not proof against CFG changes. If terminator operands'
|
||||
are changed some action should be taken. In other case some misoptimizations may
|
||||
occur due to incorrent branch prediction information.
|
||||
|
||||
Function Entry Counts
|
||||
=====================
|
||||
|
||||
To allow comparing different functions durint inter-procedural analysis and
|
||||
optimization, ``MD_prof`` nodes can also be assigned to a function definition.
|
||||
The first operand is a string indicating the name of the associated counter.
|
||||
|
||||
Currently, one counter is supported: "function_entry_count". This is a 64-bit
|
||||
counter that indicates the number of times that this function was invoked (in
|
||||
the case of instrumentation-based profiles). In the case of sampling-based
|
||||
profiles, this counter is an approximation of how many times the function was
|
||||
invoked.
|
||||
|
||||
For example, in the code below, the instrumentation for function foo()
|
||||
indicates that it was called 2,590 times at runtime.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define i32 @foo() !prof !1 {
|
||||
ret i32 0
|
||||
}
|
||||
!1 = !{!"function_entry_count", i64 2590}
|
||||
|
@ -208,7 +208,7 @@ point---a simple binary search may not be sufficient, as transformations that
|
||||
interact may require isolating more than one call. In TargetLowering, use
|
||||
``return SDNode();`` instead of ``return false;``.
|
||||
|
||||
Now that that the number of transformations is down to a manageable number, try
|
||||
Now that the number of transformations is down to a manageable number, try
|
||||
examining the output to see if you can figure out which transformations are
|
||||
being done. If that can be figured out, then do the usual debugging. If which
|
||||
code corresponds to the transformation being performed isn't obvious, set a
|
||||
|
332
docs/BuildingLLVMWithAutotools.rst
Normal file
332
docs/BuildingLLVMWithAutotools.rst
Normal file
@ -0,0 +1,332 @@
|
||||
====================================
|
||||
Building LLVM With Autotools
|
||||
====================================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This document details how to use the LLVM autotools based build system to
|
||||
configure and build LLVM from source. The normal developer process using CMake
|
||||
is detailed `here <GettingStarted.html#check-here>`_.
|
||||
|
||||
A Quick Summary
|
||||
---------------
|
||||
|
||||
#. Configure and build LLVM and Clang:
|
||||
|
||||
* ``cd where-you-want-to-build-llvm``
|
||||
* ``mkdir build`` (for building without polluting the source dir)
|
||||
* ``cd build``
|
||||
* ``../llvm/configure [options]``
|
||||
Some common options:
|
||||
|
||||
* ``--prefix=directory`` --- Specify for *directory* the full pathname of
|
||||
where you want the LLVM tools and libraries to be installed (default
|
||||
``/usr/local``).
|
||||
|
||||
* ``--enable-optimized`` --- Compile with optimizations enabled (default
|
||||
is NO).
|
||||
|
||||
* ``--enable-assertions`` --- Compile with assertion checks enabled
|
||||
(default is YES).
|
||||
|
||||
* ``make [-j]`` --- The ``-j`` specifies the number of jobs (commands) to run
|
||||
simultaneously. This builds both LLVM and Clang for Debug+Asserts mode.
|
||||
The ``--enable-optimized`` configure option is used to specify a Release
|
||||
build.
|
||||
|
||||
* ``make check-all`` --- This run the regression tests to ensure everything
|
||||
is in working order.
|
||||
|
||||
* If you get an "internal compiler error (ICE)" or test failures, see
|
||||
`here <GettingStarted.html#check-here>`_.
|
||||
|
||||
Local LLVM Configuration
|
||||
------------------------
|
||||
|
||||
Once checked out from the Subversion repository, the LLVM suite source code must
|
||||
be configured via the ``configure`` script. This script sets variables in the
|
||||
various ``*.in`` files, most notably ``llvm/Makefile.config`` and
|
||||
``llvm/include/Config/config.h``. It also populates *OBJ_ROOT* with the
|
||||
Makefiles needed to begin building LLVM.
|
||||
|
||||
The following environment variables are used by the ``configure`` script to
|
||||
configure the build system:
|
||||
|
||||
+------------+-----------------------------------------------------------+
|
||||
| Variable | Purpose |
|
||||
+============+===========================================================+
|
||||
| CC | Tells ``configure`` which C compiler to use. By default, |
|
||||
| | ``configure`` will check ``PATH`` for ``clang`` and GCC C |
|
||||
| | compilers (in this order). Use this variable to override |
|
||||
| | ``configure``\'s default behavior. |
|
||||
+------------+-----------------------------------------------------------+
|
||||
| CXX | Tells ``configure`` which C++ compiler to use. By |
|
||||
| | default, ``configure`` will check ``PATH`` for |
|
||||
| | ``clang++`` and GCC C++ compilers (in this order). Use |
|
||||
| | this variable to override ``configure``'s default |
|
||||
| | behavior. |
|
||||
+------------+-----------------------------------------------------------+
|
||||
|
||||
The following options can be used to set or enable LLVM specific options:
|
||||
|
||||
``--enable-optimized``
|
||||
|
||||
Enables optimized compilation (debugging symbols are removed and GCC
|
||||
optimization flags are enabled). Note that this is the default setting if you
|
||||
are using the LLVM distribution. The default behavior of a Subversion
|
||||
checkout is to use an unoptimized build (also known as a debug build).
|
||||
|
||||
``--enable-debug-runtime``
|
||||
|
||||
Enables debug symbols in the runtime libraries. The default is to strip debug
|
||||
symbols from the runtime libraries.
|
||||
|
||||
``--enable-jit``
|
||||
|
||||
Compile the Just In Time (JIT) compiler functionality. This is not available
|
||||
on all platforms. The default is dependent on platform, so it is best to
|
||||
explicitly enable it if you want it.
|
||||
|
||||
``--enable-targets=target-option``
|
||||
|
||||
Controls which targets will be built and linked into llc. The default value
|
||||
for ``target_options`` is "all" which builds and links all available targets.
|
||||
The "host" target is selected as the target of the build host. You can also
|
||||
specify a comma separated list of target names that you want available in llc.
|
||||
The target names use all lower case. The current set of targets is:
|
||||
|
||||
``aarch64, arm, arm64, cpp, hexagon, mips, mipsel, mips64, mips64el, msp430,
|
||||
powerpc, nvptx, r600, sparc, systemz, x86, x86_64, xcore``.
|
||||
|
||||
``--enable-doxygen``
|
||||
|
||||
Look for the doxygen program and enable construction of doxygen based
|
||||
documentation from the source code. This is disabled by default because
|
||||
generating the documentation can take a long time and producess 100s of
|
||||
megabytes of output.
|
||||
|
||||
To configure LLVM, follow these steps:
|
||||
|
||||
#. Change directory into the object root directory:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% cd OBJ_ROOT
|
||||
|
||||
#. Run the ``configure`` script located in the LLVM source tree:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% $LLVM_SRC_DIR/configure --prefix=/install/path [other options]
|
||||
|
||||
Compiling the LLVM Suite Source Code
|
||||
------------------------------------
|
||||
|
||||
Once you have configured LLVM, you can build it. There are three types of
|
||||
builds:
|
||||
|
||||
Debug Builds
|
||||
|
||||
These builds are the default when one is using a Subversion checkout and
|
||||
types ``gmake`` (unless the ``--enable-optimized`` option was used during
|
||||
configuration). The build system will compile the tools and libraries with
|
||||
debugging information. To get a Debug Build using the LLVM distribution the
|
||||
``--disable-optimized`` option must be passed to ``configure``.
|
||||
|
||||
Release (Optimized) Builds
|
||||
|
||||
These builds are enabled with the ``--enable-optimized`` option to
|
||||
``configure`` or by specifying ``ENABLE_OPTIMIZED=1`` on the ``gmake`` command
|
||||
line. For these builds, the build system will compile the tools and libraries
|
||||
with GCC optimizations enabled and strip debugging information from the
|
||||
libraries and executables it generates. Note that Release Builds are default
|
||||
when using an LLVM distribution.
|
||||
|
||||
Profile Builds
|
||||
|
||||
These builds are for use with profiling. They compile profiling information
|
||||
into the code for use with programs like ``gprof``. Profile builds must be
|
||||
started by specifying ``ENABLE_PROFILING=1`` on the ``gmake`` command line.
|
||||
|
||||
Once you have LLVM configured, you can build it by entering the *OBJ_ROOT*
|
||||
directory and issuing the following command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% gmake
|
||||
|
||||
If the build fails, please `check here <GettingStarted.html#check-here>`_
|
||||
to see if you are using a version of GCC that is known not to compile LLVM.
|
||||
|
||||
If you have multiple processors in your machine, you may wish to use some of the
|
||||
parallel build options provided by GNU Make. For example, you could use the
|
||||
command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% gmake -j2
|
||||
|
||||
There are several special targets which are useful when working with the LLVM
|
||||
source code:
|
||||
|
||||
``gmake clean``
|
||||
|
||||
Removes all files generated by the build. This includes object files,
|
||||
generated C/C++ files, libraries, and executables.
|
||||
|
||||
``gmake dist-clean``
|
||||
|
||||
Removes everything that ``gmake clean`` does, but also removes files generated
|
||||
by ``configure``. It attempts to return the source tree to the original state
|
||||
in which it was shipped.
|
||||
|
||||
``gmake install``
|
||||
|
||||
Installs LLVM header files, libraries, tools, and documentation in a hierarchy
|
||||
under ``$PREFIX``, specified with ``$LLVM_SRC_DIR/configure --prefix=[dir]``, which
|
||||
defaults to ``/usr/local``.
|
||||
|
||||
``gmake -C runtime install-bytecode``
|
||||
|
||||
Assuming you built LLVM into $OBJDIR, when this command is run, it will
|
||||
install bitcode libraries into the GCC front end's bitcode library directory.
|
||||
If you need to update your bitcode libraries, this is the target to use once
|
||||
you've built them.
|
||||
|
||||
Please see the `Makefile Guide <MakefileGuide.html>`_ for further details on
|
||||
these ``make`` targets and descriptions of other targets available.
|
||||
|
||||
It is also possible to override default values from ``configure`` by declaring
|
||||
variables on the command line. The following are some examples:
|
||||
|
||||
``gmake ENABLE_OPTIMIZED=1``
|
||||
|
||||
Perform a Release (Optimized) build.
|
||||
|
||||
``gmake ENABLE_OPTIMIZED=1 DISABLE_ASSERTIONS=1``
|
||||
|
||||
Perform a Release (Optimized) build without assertions enabled.
|
||||
|
||||
``gmake ENABLE_OPTIMIZED=0``
|
||||
|
||||
Perform a Debug build.
|
||||
|
||||
``gmake ENABLE_PROFILING=1``
|
||||
|
||||
Perform a Profiling build.
|
||||
|
||||
``gmake VERBOSE=1``
|
||||
|
||||
Print what ``gmake`` is doing on standard output.
|
||||
|
||||
``gmake TOOL_VERBOSE=1``
|
||||
|
||||
Ask each tool invoked by the makefiles to print out what it is doing on
|
||||
the standard output. This also implies ``VERBOSE=1``.
|
||||
|
||||
Every directory in the LLVM object tree includes a ``Makefile`` to build it and
|
||||
any subdirectories that it contains. Entering any directory inside the LLVM
|
||||
object tree and typing ``gmake`` should rebuild anything in or below that
|
||||
directory that is out of date.
|
||||
|
||||
This does not apply to building the documentation.
|
||||
LLVM's (non-Doxygen) documentation is produced with the
|
||||
`Sphinx <http://sphinx-doc.org/>`_ documentation generation system.
|
||||
There are some HTML documents that have not yet been converted to the new
|
||||
system (which uses the easy-to-read and easy-to-write
|
||||
`reStructuredText <http://sphinx-doc.org/rest.html>`_ plaintext markup
|
||||
language).
|
||||
The generated documentation is built in the ``$LLVM_SRC_DIR/docs`` directory using
|
||||
a special makefile.
|
||||
For instructions on how to install Sphinx, see
|
||||
`Sphinx Introduction for LLVM Developers
|
||||
<http://lld.llvm.org/sphinx_intro.html>`_.
|
||||
After following the instructions there for installing Sphinx, build the LLVM
|
||||
HTML documentation by doing the following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd $LLVM_SRC_DIR/docs
|
||||
$ make -f Makefile.sphinx
|
||||
|
||||
This creates a ``_build/html`` sub-directory with all of the HTML files, not
|
||||
just the generated ones.
|
||||
This directory corresponds to ``llvm.org/docs``.
|
||||
For example, ``_build/html/SphinxQuickstartTemplate.html`` corresponds to
|
||||
``llvm.org/docs/SphinxQuickstartTemplate.html``.
|
||||
The :doc:`SphinxQuickstartTemplate` is useful when creating a new document.
|
||||
|
||||
Cross-Compiling LLVM
|
||||
--------------------
|
||||
|
||||
It is possible to cross-compile LLVM itself. That is, you can create LLVM
|
||||
executables and libraries to be hosted on a platform different from the platform
|
||||
where they are built (a Canadian Cross build). To configure a cross-compile,
|
||||
supply the configure script with ``--build`` and ``--host`` options that are
|
||||
different. The values of these options must be legal target triples that your
|
||||
GCC compiler supports.
|
||||
|
||||
The result of such a build is executables that are not runnable on on the build
|
||||
host (--build option) but can be executed on the compile host (--host option).
|
||||
|
||||
Check :doc:`HowToCrossCompileLLVM` and `Clang docs on how to cross-compile in general
|
||||
<http://clang.llvm.org/docs/CrossCompilation.html>`_ for more information
|
||||
about cross-compiling.
|
||||
|
||||
The Location of LLVM Object Files
|
||||
---------------------------------
|
||||
|
||||
The LLVM build system is capable of sharing a single LLVM source tree among
|
||||
several LLVM builds. Hence, it is possible to build LLVM for several different
|
||||
platforms or configurations using the same source tree.
|
||||
|
||||
This is accomplished in the typical autoconf manner:
|
||||
|
||||
* Change directory to where the LLVM object files should live:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% cd OBJ_ROOT
|
||||
|
||||
* Run the ``configure`` script found in the LLVM source directory:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% $LLVM_SRC_DIR/configure
|
||||
|
||||
The LLVM build will place files underneath *OBJ_ROOT* in directories named after
|
||||
the build type:
|
||||
|
||||
Debug Builds with assertions enabled (the default)
|
||||
|
||||
Tools
|
||||
|
||||
``OBJ_ROOT/Debug+Asserts/bin``
|
||||
|
||||
Libraries
|
||||
|
||||
``OBJ_ROOT/Debug+Asserts/lib``
|
||||
|
||||
Release Builds
|
||||
|
||||
Tools
|
||||
|
||||
``OBJ_ROOT/Release/bin``
|
||||
|
||||
Libraries
|
||||
|
||||
``OBJ_ROOT/Release/lib``
|
||||
|
||||
Profile Builds
|
||||
|
||||
Tools
|
||||
|
||||
``OBJ_ROOT/Profile/bin``
|
||||
|
||||
Libraries
|
||||
|
||||
``OBJ_ROOT/Profile/lib``
|
@ -26,7 +26,7 @@ Quick start
|
||||
We use here the command-line, non-interactive CMake interface.
|
||||
|
||||
#. `Download <http://www.cmake.org/cmake/resources/software.html>`_ and install
|
||||
CMake. Version 2.8 is the minimum required.
|
||||
CMake. Version 2.8.8 is the minimum required.
|
||||
|
||||
#. Open a shell. Your development tools must be reachable from this shell
|
||||
through the PATH environment variable.
|
||||
@ -59,6 +59,36 @@ We use here the command-line, non-interactive CMake interface.
|
||||
environment variable, for instance. You can force CMake to use a given build
|
||||
tool, see the `Usage`_ section.
|
||||
|
||||
#. After CMake has finished running, proceed to use IDE project files or start
|
||||
the build from the build directory:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cmake --build .
|
||||
|
||||
The ``--build`` option tells ``cmake`` to invoke the underlying build
|
||||
tool (``make``, ``ninja``, ``xcodebuild``, ``msbuild``, etc).
|
||||
|
||||
The underlying build tool can be invoked directly either of course, but
|
||||
the ``--build`` option is portable.
|
||||
|
||||
#. After LLVM has finished building, install it from the build directory:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cmake --build . --target install
|
||||
|
||||
The ``--target`` option with ``install`` parameter in addition to
|
||||
the ``--build`` option tells ``cmake`` to build the ``install`` target.
|
||||
|
||||
It is possible to set a different install prefix at installation time
|
||||
by invoking the ``cmake_install.cmake`` script generated in the
|
||||
build directory:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cmake -DCMAKE_INSTALL_PREFIX=/tmp/llvm -P cmake_install.cmake
|
||||
|
||||
.. _Basic CMake usage:
|
||||
.. _Usage:
|
||||
|
||||
@ -215,8 +245,8 @@ LLVM-specific variables
|
||||
Build in C++1y mode, if available. Defaults to OFF.
|
||||
|
||||
**LLVM_ENABLE_ASSERTIONS**:BOOL
|
||||
Enables code assertions. Defaults to OFF if and only if ``CMAKE_BUILD_TYPE``
|
||||
is *Release*.
|
||||
Enables code assertions. Defaults to ON if and only if ``CMAKE_BUILD_TYPE``
|
||||
is *Debug*.
|
||||
|
||||
**LLVM_ENABLE_EH**:BOOL
|
||||
Build LLVM with exception handling support. This is necessary if you wish to
|
||||
@ -240,6 +270,15 @@ LLVM-specific variables
|
||||
**LLVM_ENABLE_WERROR**:BOOL
|
||||
Stop and fail build, if a compiler warning is triggered. Defaults to OFF.
|
||||
|
||||
**LLVM_ABI_BREAKING_CHECKS**:STRING
|
||||
Used to decide if LLVM should be built with ABI breaking checks or
|
||||
not. Allowed values are `WITH_ASSERTS` (default), `FORCE_ON` and
|
||||
`FORCE_OFF`. `WITH_ASSERTS` turns on ABI breaking checks in an
|
||||
assertion enabled build. `FORCE_ON` (`FORCE_OFF`) turns them on
|
||||
(off) irrespective of whether normal (`NDEBUG` based) assertions are
|
||||
enabled or not. A version of LLVM built with ABI breaking checks
|
||||
is not ABI compatible with a version built without it.
|
||||
|
||||
**LLVM_BUILD_32_BITS**:BOOL
|
||||
Build 32-bits executables and libraries on 64-bits systems. This option is
|
||||
available only on some 64-bits unix systems. Defaults to OFF.
|
||||
@ -316,8 +355,8 @@ LLVM-specific variables
|
||||
otherwise this has no effect.
|
||||
|
||||
**LLVM_DOXYGEN_QCH_FILENAME**:STRING
|
||||
The filename of the Qt Compressed Help file that will be genrated when
|
||||
``-DLLVM_ENABLE_DOXYGEN=ON`` and
|
||||
The filename of the Qt Compressed Help file that will be generated when
|
||||
``-DLLVM_ENABLE_DOXYGEN=ON`` and
|
||||
``-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON`` are given. Defaults to
|
||||
``org.llvm.qch``.
|
||||
This option is only useful in combination with
|
||||
@ -330,7 +369,7 @@ LLVM-specific variables
|
||||
for more information. Defaults to "org.llvm". This option is only useful in
|
||||
combination with ``-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON``; otherwise
|
||||
this has no effect.
|
||||
|
||||
|
||||
**LLVM_DOXYGEN_QHP_CUST_FILTER_NAME**:STRING
|
||||
See `Qt Help Project`_ for
|
||||
more information. Defaults to the CMake variable ``${PACKAGE_STRING}`` which
|
||||
@ -429,7 +468,7 @@ and uses them to build a simple application ``simple-tool``.
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
|
||||
# Now build our tools
|
||||
add_excutable(simple-tool tool.cpp)
|
||||
add_executable(simple-tool tool.cpp)
|
||||
|
||||
# Find the libraries that correspond to the LLVM components
|
||||
# that we wish to use
|
||||
|
@ -1340,7 +1340,7 @@ found before being stored or after being reloaded.
|
||||
If the indirect strategy is used, after all the virtual registers have been
|
||||
mapped to physical registers or stack slots, it is necessary to use a spiller
|
||||
object to place load and store instructions in the code. Every virtual that has
|
||||
been mapped to a stack slot will be stored to memory after been defined and will
|
||||
been mapped to a stack slot will be stored to memory after being defined and will
|
||||
be loaded before being used. The implementation of the spiller tries to recycle
|
||||
load/store instructions, avoiding unnecessary instructions. For an example of
|
||||
how to invoke the spiller, see ``RegAllocLinearScan::runOnMachineFunction`` in
|
||||
@ -1353,7 +1353,7 @@ With very rare exceptions (e.g., function calls), the LLVM machine code
|
||||
instructions are three address instructions. That is, each instruction is
|
||||
expected to define at most one register, and to use at most two registers.
|
||||
However, some architectures use two address instructions. In this case, the
|
||||
defined register is also one of the used register. For instance, an instruction
|
||||
defined register is also one of the used registers. For instance, an instruction
|
||||
such as ``ADD %EAX, %EBX``, in X86 is actually equivalent to ``%EAX = %EAX +
|
||||
%EBX``.
|
||||
|
||||
@ -1578,7 +1578,7 @@ three important things that you have to implement for your target:
|
||||
correspond to. The MCInsts that are generated by this are fed into the
|
||||
instruction printer or the encoder.
|
||||
|
||||
Finally, at your choosing, you can also implement an subclass of MCCodeEmitter
|
||||
Finally, at your choosing, you can also implement a subclass of MCCodeEmitter
|
||||
which lowers MCInst's into machine code bytes and relocations. This is
|
||||
important if you want to support direct .o file emission, or would like to
|
||||
implement an assembler for your target.
|
||||
|
@ -83,7 +83,7 @@ Supported C++11 Language and Library Features
|
||||
|
||||
While LLVM, Clang, and LLD use C++11, not all features are available in all of
|
||||
the toolchains which we support. The set of features supported for use in LLVM
|
||||
is the intersection of those supported in MSVC 2012, GCC 4.7, and Clang 3.1.
|
||||
is the intersection of those supported in MSVC 2013, GCC 4.7, and Clang 3.1.
|
||||
The ultimate definition of this set is what build bots with those respective
|
||||
toolchains accept. Don't argue with the build bots. However, we have some
|
||||
guidance below to help you know what to expect.
|
||||
@ -123,6 +123,20 @@ unlikely to be supported by our host compilers.
|
||||
|
||||
* ``override`` and ``final``: N2928_, N3206_, N3272_
|
||||
* Atomic operations and the C++11 memory model: N2429_
|
||||
* Variadic templates: N2242_
|
||||
* Explicit conversion operators: N2437_
|
||||
* Defaulted and deleted functions: N2346_
|
||||
|
||||
* But not defaulted move constructors or move assignment operators, MSVC 2013
|
||||
cannot synthesize them.
|
||||
* Initializer lists: N2627_
|
||||
* Delegating constructors: N1986_
|
||||
* Default member initializers (non-static data member initializers): N2756_
|
||||
|
||||
* Only use these for scalar members that would otherwise be left
|
||||
uninitialized. Non-scalar members generally have appropriate default
|
||||
constructors, and MSVC 2013 has problems when braced initializer lists are
|
||||
involved.
|
||||
|
||||
.. _N2118: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html
|
||||
.. _N2439: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm
|
||||
@ -143,7 +157,12 @@ unlikely to be supported by our host compilers.
|
||||
.. _N3206: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm
|
||||
.. _N3272: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm
|
||||
.. _N2429: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm
|
||||
.. _MSVC-compatible RTTI: http://llvm.org/PR18951
|
||||
.. _N2242: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf
|
||||
.. _N2437: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf
|
||||
.. _N2346: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm
|
||||
.. _N2627: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm
|
||||
.. _N1986: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
|
||||
.. _N2756: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2756.htm
|
||||
|
||||
The supported features in the C++11 standard libraries are less well tracked,
|
||||
but also much greater. Most of the standard libraries implement most of C++11's
|
||||
@ -159,9 +178,6 @@ being aware of:
|
||||
* While most of the atomics library is well implemented, the fences are
|
||||
missing. Fortunately, they are rarely needed.
|
||||
* The locale support is incomplete.
|
||||
* ``std::initializer_list`` (and the constructors and functions that take it as
|
||||
an argument) are not always available, so you cannot (for example) initialize
|
||||
a ``std::vector`` with a braced initializer list.
|
||||
* ``std::equal()`` (and other algorithms) incorrectly assert in MSVC when given
|
||||
``nullptr`` as an iterator.
|
||||
|
||||
@ -231,8 +247,8 @@ tree. The standard header looks like this:
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file contains the declaration of the Instruction class, which is
|
||||
/// the base class for all of the VM instructions.
|
||||
/// This file contains the declaration of the Instruction class, which is the
|
||||
/// base class for all of the VM instructions.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -251,10 +267,11 @@ The next section in the file is a concise note that defines the license that the
|
||||
file is released under. This makes it perfectly clear what terms the source
|
||||
code can be distributed under and should not be modified in any way.
|
||||
|
||||
The main body is a ``doxygen`` comment describing the purpose of the file. It
|
||||
should have a ``\brief`` command that describes the file in one or two
|
||||
sentences. Any additional information should be separated by a blank line. If
|
||||
an algorithm is being implemented or something tricky is going on, a reference
|
||||
The main body is a ``doxygen`` comment (identified by the ``///`` comment
|
||||
marker instead of the usual ``//``) describing the purpose of the file. The
|
||||
first sentence or a passage beginning with ``\brief`` is used as an abstract.
|
||||
Any additional information should be separated by a blank line. If an
|
||||
algorithm is being implemented or something tricky is going on, a reference
|
||||
to the paper where it is published should be included, as well as any notes or
|
||||
*gotchas* in the code to watch out for.
|
||||
|
||||
@ -281,7 +298,8 @@ happens: does the method return null? Abort? Format your hard disk?
|
||||
Comment Formatting
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In general, prefer C++ style (``//``) comments. They take less space, require
|
||||
In general, prefer C++ style comments (``//`` for normal comments, ``///`` for
|
||||
``doxygen`` documentation comments). They take less space, require
|
||||
less typing, don't have nesting problems, etc. There are a few cases when it is
|
||||
useful to use C style (``/* */``) comments however:
|
||||
|
||||
@ -302,10 +320,11 @@ Doxygen Use in Documentation Comments
|
||||
Use the ``\file`` command to turn the standard file header into a file-level
|
||||
comment.
|
||||
|
||||
Include descriptive ``\brief`` paragraphs for all public interfaces (public
|
||||
classes, member and non-member functions). Explain API use and purpose in
|
||||
``\brief`` paragraphs, don't just restate the information that can be inferred
|
||||
from the API name. Put detailed discussion into separate paragraphs.
|
||||
Include descriptive paragraphs for all public interfaces (public classes,
|
||||
member and non-member functions). Don't just restate the information that can
|
||||
be inferred from the API name. The first sentence or a paragraph beginning
|
||||
with ``\brief`` is used as an abstract. Put detailed discussion into separate
|
||||
paragraphs.
|
||||
|
||||
To refer to parameter names inside a paragraph, use the ``\p name`` command.
|
||||
Don't use the ``\arg name`` command since it starts a new paragraph that
|
||||
@ -325,8 +344,8 @@ A minimal documentation comment:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
/// \brief Does foo and bar.
|
||||
void fooBar(bool Baz);
|
||||
/// Sets the xyzzy property to \p Baz.
|
||||
void setXyzzy(bool Baz);
|
||||
|
||||
A documentation comment that uses all Doxygen features in a preferred way:
|
||||
|
||||
@ -383,10 +402,10 @@ Correct:
|
||||
|
||||
// In Something.h:
|
||||
|
||||
/// \brief An abstraction for some complicated thing.
|
||||
/// An abstraction for some complicated thing.
|
||||
class Something {
|
||||
public:
|
||||
/// \brief Does foo and bar.
|
||||
/// Does foo and bar.
|
||||
void fooBar();
|
||||
};
|
||||
|
||||
@ -710,7 +729,7 @@ the symbol (e.g., MSVC). This can lead to problems at link time.
|
||||
// Bar isn't POD, but it does look like a struct.
|
||||
struct Bar {
|
||||
int Data;
|
||||
Foo() : Data(0) { }
|
||||
Bar() : Data(0) { }
|
||||
};
|
||||
|
||||
Do not use Braced Initializer Lists to Call a Constructor
|
||||
@ -1290,34 +1309,6 @@ that the enum expression may take any representable value, not just those of
|
||||
individual enumerators. To suppress this warning, use ``llvm_unreachable`` after
|
||||
the switch.
|
||||
|
||||
Use ``LLVM_DELETED_FUNCTION`` to mark uncallable methods
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Prior to C++11, a common pattern to make a class uncopyable was to declare an
|
||||
unimplemented copy constructor and copy assignment operator and make them
|
||||
private. This would give a compiler error for accessing a private method or a
|
||||
linker error because it wasn't implemented.
|
||||
|
||||
With C++11, we can mark methods that won't be implemented with ``= delete``.
|
||||
This will trigger a much better error message and tell the compiler that the
|
||||
method will never be implemented. This enables other checks like
|
||||
``-Wunused-private-field`` to run correctly on classes that contain these
|
||||
methods.
|
||||
|
||||
For compatibility with MSVC, ``LLVM_DELETED_FUNCTION`` should be used which
|
||||
will expand to ``= delete`` on compilers that support it. These methods should
|
||||
still be declared private. Example of the uncopyable pattern:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
class DontCopy {
|
||||
private:
|
||||
DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION;
|
||||
DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
...
|
||||
};
|
||||
|
||||
Don't evaluate ``end()`` every time through a loop
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -185,6 +185,31 @@ For example, something like this works as you'd expect:
|
||||
newline between it and the previous directive. A "``CHECK-NEXT:``" cannot be
|
||||
the first directive in a file.
|
||||
|
||||
The "CHECK-SAME:" directive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes you want to match lines and would like to verify that matches happen
|
||||
on the same line as the previous match. In this case, you can use "``CHECK:``"
|
||||
and "``CHECK-SAME:``" directives to specify this. If you specified a custom
|
||||
check prefix, just use "``<PREFIX>-SAME:``".
|
||||
|
||||
"``CHECK-SAME:``" is particularly powerful in conjunction with "``CHECK-NOT:``"
|
||||
(described below).
|
||||
|
||||
For example, the following works like you'd expect:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!0 = !DILocation(line: 5, scope: !1, inlinedAt: !2)
|
||||
|
||||
; CHECK: !DILocation(line: 5,
|
||||
; CHECK-NOT: column:
|
||||
; CHECK-SAME: scope: ![[SCOPE:[0-9]+]]
|
||||
|
||||
"``CHECK-SAME:``" directives reject the input if there are any newlines between
|
||||
it and the previous directive. A "``CHECK-SAME:``" cannot be the first
|
||||
directive in a file.
|
||||
|
||||
The "CHECK-NOT:" directive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -339,7 +364,7 @@ simply uniquely match a single line in the file being verified.
|
||||
FileCheck Pattern Matching Syntax
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The "``CHECK:``" and "``CHECK-NOT:``" directives both take a pattern to match.
|
||||
All FileCheck directives take a pattern to match.
|
||||
For most uses of FileCheck, fixed string matching is perfectly sufficient. For
|
||||
some things, a more flexible form of matching is desired. To support this,
|
||||
FileCheck allows you to specify regular expressions in matching strings,
|
||||
|
@ -56,7 +56,7 @@ GENERAL OPTIONS
|
||||
Search for :file:`{NAME}.cfg` and :file:`{NAME}.site.cfg` when searching for
|
||||
test suites, instead of :file:`lit.cfg` and :file:`lit.site.cfg`.
|
||||
|
||||
.. option:: --param NAME, --param NAME=VALUE
|
||||
.. option:: -D NAME, -D NAME=VALUE, --param NAME, --param NAME=VALUE
|
||||
|
||||
Add a user defined parameter ``NAME`` with the given ``VALUE`` (or the empty
|
||||
string if not given). The meaning and use of these parameters is test suite
|
||||
@ -341,7 +341,7 @@ LOCAL CONFIGURATION FILES
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When :program:`lit` loads a subdirectory in a test suite, it instantiates a
|
||||
local test configuration by cloning the configuration for the parent direction
|
||||
local test configuration by cloning the configuration for the parent directory
|
||||
--- the root of this configuration chain will always be a test suite. Once the
|
||||
test configuration is cloned :program:`lit` checks for a *lit.local.cfg* file
|
||||
in the subdirectory. If present, this file will be loaded and can be used to
|
||||
|
@ -4,18 +4,49 @@ llvm-cov - emit coverage information
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
:program:`llvm-cov` [options] SOURCEFILE
|
||||
:program:`llvm-cov` *command* [*args...*]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
The :program:`llvm-cov` tool reads code coverage data files and displays the
|
||||
coverage information for a specified source file. It is compatible with the
|
||||
``gcov`` tool from version 4.2 of ``GCC`` and may also be compatible with
|
||||
some later versions of ``gcov``.
|
||||
The :program:`llvm-cov` tool shows code coverage information for
|
||||
programs that are instrumented to emit profile data. It can be used to
|
||||
work with ``gcov``\-style coverage or with ``clang``\'s instrumentation
|
||||
based profiling.
|
||||
|
||||
To use llvm-cov, you must first build an instrumented version of your
|
||||
application that collects coverage data as it runs. Compile with the
|
||||
If the program is invoked with a base name of ``gcov``, it will behave as if
|
||||
the :program:`llvm-cov gcov` command were called. Otherwise, a command should
|
||||
be provided.
|
||||
|
||||
COMMANDS
|
||||
--------
|
||||
|
||||
* :ref:`gcov <llvm-cov-gcov>`
|
||||
* :ref:`show <llvm-cov-show>`
|
||||
* :ref:`report <llvm-cov-report>`
|
||||
|
||||
.. program:: llvm-cov gcov
|
||||
|
||||
.. _llvm-cov-gcov:
|
||||
|
||||
GCOV COMMAND
|
||||
------------
|
||||
|
||||
SYNOPSIS
|
||||
^^^^^^^^
|
||||
|
||||
:program:`llvm-cov gcov` [*options*] *SOURCEFILE*
|
||||
|
||||
DESCRIPTION
|
||||
^^^^^^^^^^^
|
||||
|
||||
The :program:`llvm-cov gcov` tool reads code coverage data files and displays
|
||||
the coverage information for a specified source file. It is compatible with the
|
||||
``gcov`` tool from version 4.2 of ``GCC`` and may also be compatible with some
|
||||
later versions of ``gcov``.
|
||||
|
||||
To use :program:`llvm-cov gcov`, you must first build an instrumented version
|
||||
of your application that collects coverage data as it runs. Compile with the
|
||||
``-fprofile-arcs`` and ``-ftest-coverage`` options to add the
|
||||
instrumentation. (Alternatively, you can use the ``--coverage`` option, which
|
||||
includes both of those other options.) You should compile with debugging
|
||||
@ -39,24 +70,23 @@ directories, the prefix from the ``GCOV_PREFIX`` variable is added. These
|
||||
environment variables allow you to run the instrumented program on a machine
|
||||
where the original object file directories are not accessible, but you will
|
||||
then need to copy the ``.gcda`` files back to the object file directories
|
||||
where llvm-cov expects to find them.
|
||||
where :program:`llvm-cov gcov` expects to find them.
|
||||
|
||||
Once you have generated the coverage data files, run llvm-cov for each main
|
||||
source file where you want to examine the coverage results. This should be run
|
||||
from the same directory where you previously ran the compiler. The results for
|
||||
the specified source file are written to a file named by appending a ``.gcov``
|
||||
suffix. A separate output file is also created for each file included by the
|
||||
main source file, also with a ``.gcov`` suffix added.
|
||||
Once you have generated the coverage data files, run :program:`llvm-cov gcov`
|
||||
for each main source file where you want to examine the coverage results. This
|
||||
should be run from the same directory where you previously ran the
|
||||
compiler. The results for the specified source file are written to a file named
|
||||
by appending a ``.gcov`` suffix. A separate output file is also created for
|
||||
each file included by the main source file, also with a ``.gcov`` suffix added.
|
||||
|
||||
The basic content of an llvm-cov output file is a copy of the source file with
|
||||
The basic content of an ``.gcov`` output file is a copy of the source file with
|
||||
an execution count and line number prepended to every line. The execution
|
||||
count is shown as ``-`` if a line does not contain any executable code. If
|
||||
a line contains code but that code was never executed, the count is displayed
|
||||
as ``#####``.
|
||||
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
^^^^^^^
|
||||
|
||||
.. option:: -a, --all-blocks
|
||||
|
||||
@ -66,7 +96,7 @@ OPTIONS
|
||||
|
||||
.. option:: -b, --branch-probabilities
|
||||
|
||||
Display conditional branch probabilities and a summary of branch information.
|
||||
Display conditional branch probabilities and a summary of branch information.
|
||||
|
||||
.. option:: -c, --branch-counts
|
||||
|
||||
@ -120,8 +150,148 @@ OPTIONS
|
||||
Display the version of llvm-cov.
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
^^^^^^^^^^^
|
||||
|
||||
:program:`llvm-cov` returns 1 if it cannot read input files. Otherwise, it
|
||||
exits with zero.
|
||||
:program:`llvm-cov gcov` returns 1 if it cannot read input files. Otherwise,
|
||||
it exits with zero.
|
||||
|
||||
|
||||
.. program:: llvm-cov show
|
||||
|
||||
.. _llvm-cov-show:
|
||||
|
||||
SHOW COMMAND
|
||||
------------
|
||||
|
||||
SYNOPSIS
|
||||
^^^^^^^^
|
||||
|
||||
:program:`llvm-cov show` [*options*] -instr-profile *PROFILE* *BIN* [*SOURCES*]
|
||||
|
||||
DESCRIPTION
|
||||
^^^^^^^^^^^
|
||||
|
||||
The :program:`llvm-cov show` command shows line by line coverage of a binary
|
||||
*BIN* using the profile data *PROFILE*. It can optionally be filtered to only
|
||||
show the coverage for the files listed in *SOURCES*.
|
||||
|
||||
To use :program:`llvm-cov show`, you need a program that is compiled with
|
||||
instrumentation to emit profile and coverage data. To build such a program with
|
||||
``clang`` use the ``-fprofile-instr-generate`` and ``-fcoverage-mapping``
|
||||
flags. If linking with the ``clang`` driver, pass ``-fprofile-instr-generate``
|
||||
to the link stage to make sure the necessary runtime libraries are linked in.
|
||||
|
||||
The coverage information is stored in the built executable or library itself,
|
||||
and this is what you should pass to :program:`llvm-cov show` as the *BIN*
|
||||
argument. The profile data is generated by running this instrumented program
|
||||
normally. When the program exits it will write out a raw profile file,
|
||||
typically called ``default.profraw``, which can be converted to a format that
|
||||
is suitable for the *PROFILE* argument using the :program:`llvm-profdata merge`
|
||||
tool.
|
||||
|
||||
OPTIONS
|
||||
^^^^^^^
|
||||
|
||||
.. option:: -show-line-counts
|
||||
|
||||
Show the execution counts for each line. This is enabled by default, unless
|
||||
another ``-show`` option is used.
|
||||
|
||||
.. option:: -show-expansions
|
||||
|
||||
Expand inclusions, such as preprocessor macros or textual inclusions, inline
|
||||
in the display of the source file.
|
||||
|
||||
.. option:: -show-instantiations
|
||||
|
||||
For source regions that are instantiated multiple times, such as templates in
|
||||
``C++``, show each instantiation separately as well as the combined summary.
|
||||
|
||||
.. option:: -show-regions
|
||||
|
||||
Show the execution counts for each region by displaying a caret that points to
|
||||
the character where the region starts.
|
||||
|
||||
.. option:: -show-line-counts-or-regions
|
||||
|
||||
Show the execution counts for each line if there is only one region on the
|
||||
line, but show the individual regions if there are multiple on the line.
|
||||
|
||||
.. option:: -use-color[=VALUE]
|
||||
|
||||
Enable or disable color output. By default this is autodetected.
|
||||
|
||||
.. option:: -arch=<name>
|
||||
|
||||
If the covered binary is a universal binary, select the architecture to use.
|
||||
It is an error to specify an architecture that is not included in the
|
||||
universal binary or to use an architecture that does not match a
|
||||
non-universal binary.
|
||||
|
||||
.. option:: -name=<NAME>
|
||||
|
||||
Show code coverage only for functions with the given name.
|
||||
|
||||
.. option:: -name-regex=<PATTERN>
|
||||
|
||||
Show code coverage only for functions that match the given regular expression.
|
||||
|
||||
.. option:: -line-coverage-gt=<N>
|
||||
|
||||
Show code coverage only for functions with line coverage greater than the
|
||||
given threshold.
|
||||
|
||||
.. option:: -line-coverage-lt=<N>
|
||||
|
||||
Show code coverage only for functions with line coverage less than the given
|
||||
threshold.
|
||||
|
||||
.. option:: -region-coverage-gt=<N>
|
||||
|
||||
Show code coverage only for functions with region coverage greater than the
|
||||
given threshold.
|
||||
|
||||
.. option:: -region-coverage-lt=<N>
|
||||
|
||||
Show code coverage only for functions with region coverage less than the given
|
||||
threshold.
|
||||
|
||||
.. program:: llvm-cov report
|
||||
|
||||
.. _llvm-cov-report:
|
||||
|
||||
REPORT COMMAND
|
||||
--------------
|
||||
|
||||
SYNOPSIS
|
||||
^^^^^^^^
|
||||
|
||||
:program:`llvm-cov report` [*options*] -instr-profile *PROFILE* *BIN* [*SOURCES*]
|
||||
|
||||
DESCRIPTION
|
||||
^^^^^^^^^^^
|
||||
|
||||
The :program:`llvm-cov report` command displays a summary of the coverage of a
|
||||
binary *BIN* using the profile data *PROFILE*. It can optionally be filtered to
|
||||
only show the coverage for the files listed in *SOURCES*.
|
||||
|
||||
If no source files are provided, a summary line is printed for each file in the
|
||||
coverage data. If any files are provided, summaries are shown for each function
|
||||
in the listed files instead.
|
||||
|
||||
For information on compiling programs for coverage and generating profile data,
|
||||
see :ref:`llvm-cov-show`.
|
||||
|
||||
OPTIONS
|
||||
^^^^^^^
|
||||
|
||||
.. option:: -use-color[=VALUE]
|
||||
|
||||
Enable or disable color output. By default this is autodetected.
|
||||
|
||||
.. option:: -arch=<name>
|
||||
|
||||
If the covered binary is a universal binary, select the architecture to use.
|
||||
It is an error to specify an architecture that is not included in the
|
||||
universal binary or to use an architecture that does not match a
|
||||
non-universal binary.
|
||||
|
@ -15,12 +15,12 @@ data files.
|
||||
COMMANDS
|
||||
--------
|
||||
|
||||
* `merge <profdata_merge_>`_
|
||||
* `show <profdata_show_>`_
|
||||
* :ref:`merge <profdata-merge>`
|
||||
* :ref:`show <profdata-show>`
|
||||
|
||||
.. program:: llvm-profdata merge
|
||||
|
||||
.. _profdata_merge:
|
||||
.. _profdata-merge:
|
||||
|
||||
MERGE
|
||||
-----
|
||||
@ -51,7 +51,7 @@ OPTIONS
|
||||
|
||||
.. program:: llvm-profdata show
|
||||
|
||||
.. _profdata_show:
|
||||
.. _profdata-show:
|
||||
|
||||
SHOW
|
||||
----
|
||||
|
@ -41,6 +41,8 @@ MIPS
|
||||
|
||||
* `MIPS Processor Architecture <http://imgtec.com/mips/mips-architectures.asp>`_
|
||||
|
||||
* `MIPS 64-bit ELF Object File Specification <http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf>`_
|
||||
|
||||
PowerPC
|
||||
-------
|
||||
|
||||
|
@ -275,6 +275,64 @@ reverted. This is necessary when the change blocks other developers from making
|
||||
progress. The developer is welcome to re-commit the change after the problem has
|
||||
been fixed.
|
||||
|
||||
.. _commit messages:
|
||||
|
||||
Commit messages
|
||||
---------------
|
||||
|
||||
Although we don't enforce the format of commit messages, we prefer that
|
||||
you follow these guidelines to help review, search in logs, email formatting
|
||||
and so on. These guidelines are very similar to rules used by other open source
|
||||
projects.
|
||||
|
||||
Most importantly, the contents of the message should be carefully written to
|
||||
convey the rationale of the change (without delving too much in detail). It
|
||||
also should avoid being vague or overly specific. For example, "bits were not
|
||||
set right" will leave the reviewer wondering about which bits, and why they
|
||||
weren't right, while "Correctly set overflow bits in TargetInfo" conveys almost
|
||||
all there is to the change.
|
||||
|
||||
Below are some guidelines about the format of the message itself:
|
||||
|
||||
* Separate the commit message into title, body and, if you're not the original
|
||||
author, a "Patch by" attribution line (see below).
|
||||
|
||||
* The title should be concise. Because all commits are emailed to the list with
|
||||
the first line as the subject, long titles are frowned upon. Short titles
|
||||
also look better in `git log`.
|
||||
|
||||
* When the changes are restricted to a specific part of the code (e.g. a
|
||||
back-end or optimization pass), it is customary to add a tag to the
|
||||
beginning of the line in square brackets. For example, "[SCEV] ..."
|
||||
or "[OpenMP] ...". This helps email filters and searches for post-commit
|
||||
reviews.
|
||||
|
||||
* The body, if it exists, should be separated from the title by an empty line.
|
||||
|
||||
* The body should be concise, but explanatory, including a complete
|
||||
reasoning. Unless it is required to understand the change, examples,
|
||||
code snippets and gory details should be left to bug comments, web
|
||||
review or the mailing list.
|
||||
|
||||
* If the patch fixes a bug in bugzilla, please include the PR# in the message.
|
||||
|
||||
* `Attribution of Changes`_ should be in a separate line, after the end of
|
||||
the body, as simple as "Patch by John Doe.". This is how we officially
|
||||
handle attribution, and there are automated processes that rely on this
|
||||
format.
|
||||
|
||||
* Text formatting and spelling should follow the same rules as documentation
|
||||
and in-code comments, ex. capitalization, full stop, etc.
|
||||
|
||||
* If the commit is a bug fix on top of another recently committed patch, or a
|
||||
revert or reapply of a patch, include the svn revision number of the prior
|
||||
related commit. This could be as simple as "Revert rNNNN because it caused
|
||||
PR#".
|
||||
|
||||
For minor violations of these recommendations, the community normally favors
|
||||
reminding the contributor of this policy over reverting. Minor corrections and
|
||||
omissions can be handled by sending a reply to the commits mailing list.
|
||||
|
||||
Obtaining Commit Access
|
||||
-----------------------
|
||||
|
||||
@ -425,8 +483,9 @@ want the source code to be littered with random attributions "this code written
|
||||
by J. Random Hacker" (this is noisy and distracting). In practice, the revision
|
||||
control system keeps a perfect history of who changed what, and the CREDITS.txt
|
||||
file describes higher-level contributions. If you commit a patch for someone
|
||||
else, please say "patch contributed by J. Random Hacker!" in the commit
|
||||
message. Overall, please do not add contributor names to the source code.
|
||||
else, please follow the attribution of changes in the simple manner as outlined
|
||||
by the `commit messages`_ section. Overall, please do not add contributor names
|
||||
to the source code.
|
||||
|
||||
Also, don't commit patches authored by others unless they have submitted the
|
||||
patch to the project or you have been authorized to submit them on their behalf
|
||||
|
@ -64,6 +64,21 @@ handling at the expense of slower execution when no exceptions are thrown. As
|
||||
exceptions are, by their nature, intended for uncommon code paths, DWARF
|
||||
exception handling is generally preferred to SJLJ.
|
||||
|
||||
Windows Runtime Exception Handling
|
||||
-----------------------------------
|
||||
|
||||
Windows runtime based exception handling uses the same basic IR structure as
|
||||
Itanium ABI based exception handling, but it relies on the personality
|
||||
functions provided by the native Windows runtime library, ``__CxxFrameHandler3``
|
||||
for C++ exceptions: ``__C_specific_handler`` for 64-bit SEH or
|
||||
``_frame_handler3/4`` for 32-bit SEH. This results in a very different
|
||||
execution model and requires some minor modifications to the initial IR
|
||||
representation and a significant restructuring just before code generation.
|
||||
|
||||
General information about the Windows x64 exception handling mechanism can be
|
||||
found at `MSDN Exception Handling (x64)
|
||||
<https://msdn.microsoft.com/en-us/library/1eyas8tf(v=vs.80).aspx>`_.
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
@ -263,9 +278,9 @@ there are no catches or filters that require it to.
|
||||
exceptions and throws a third.
|
||||
|
||||
When all cleanups are finished, if the exception is not handled by the current
|
||||
function, resume unwinding by calling the `resume
|
||||
instruction <LangRef.html#i_resume>`_, passing in the result of the
|
||||
``landingpad`` instruction for the original landing pad.
|
||||
function, resume unwinding by calling the :ref:`resume instruction <i_resume>`,
|
||||
passing in the result of the ``landingpad`` instruction for the original
|
||||
landing pad.
|
||||
|
||||
Throw Filters
|
||||
-------------
|
||||
@ -306,6 +321,97 @@ the selector results they understand and then resume exception propagation with
|
||||
the `resume instruction <LangRef.html#i_resume>`_ if none of the conditions
|
||||
match.
|
||||
|
||||
C++ Exception Handling using the Windows Runtime
|
||||
=================================================
|
||||
|
||||
(Note: Windows C++ exception handling support is a work in progress and is
|
||||
not yet fully implemented. The text below describes how it will work
|
||||
when completed.)
|
||||
|
||||
The Windows runtime function for C++ exception handling uses a multi-phase
|
||||
approach. When an exception occurs it searches the current callstack for a
|
||||
frame that has a handler for the exception. If a handler is found, it then
|
||||
calls the cleanup handler for each frame above the handler which has a
|
||||
cleanup handler before calling the catch handler. These calls are all made
|
||||
from a stack context different from the original frame in which the handler
|
||||
is defined. Therefore, it is necessary to outline these handlers from their
|
||||
original context before code generation.
|
||||
|
||||
Catch handlers are called with a pointer to the handler itself as the first
|
||||
argument and a pointer to the parent function's stack frame as the second
|
||||
argument. The catch handler uses the `llvm.recoverframe
|
||||
<LangRef.html#llvm-frameallocate-and-llvm-framerecover-intrinsics>`_ to get a
|
||||
pointer to a frame allocation block that is created in the parent frame using
|
||||
the `llvm.allocateframe
|
||||
<LangRef.html#llvm-frameallocate-and-llvm-framerecover-intrinsics>`_ intrinsic.
|
||||
The ``WinEHPrepare`` pass will have created a structure definition for the
|
||||
contents of this block. The first two members of the structure will always be
|
||||
(1) a 32-bit integer that the runtime uses to track the exception state of the
|
||||
parent frame for the purposes of handling chained exceptions and (2) a pointer
|
||||
to the object associated with the exception (roughly, the parameter of the
|
||||
catch clause). These two members will be followed by any frame variables from
|
||||
the parent function which must be accessed in any of the functions unwind or
|
||||
catch handlers. The catch handler returns the address at which execution
|
||||
should continue.
|
||||
|
||||
Cleanup handlers perform any cleanup necessary as the frame goes out of scope,
|
||||
such as calling object destructors. The runtime handles the actual unwinding
|
||||
of the stack. If an exception occurs in a cleanup handler the runtime manages
|
||||
termination of the process. Cleanup handlers are called with the same arguments
|
||||
as catch handlers (a pointer to the handler and a pointer to the parent stack
|
||||
frame) and use the same mechanism described above to access frame variables
|
||||
in the parent function. Cleanup handlers do not return a value.
|
||||
|
||||
The IR generated for Windows runtime based C++ exception handling is initially
|
||||
very similar to the ``landingpad`` mechanism described above. Calls to
|
||||
libc++abi functions (such as ``__cxa_begin_catch``/``__cxa_end_catch`` and
|
||||
``__cxa_throw_exception`` are replaced with calls to intrinsics or Windows
|
||||
runtime functions (such as ``llvm.eh.begincatch``/``llvm.eh.endcatch`` and
|
||||
``__CxxThrowException``).
|
||||
|
||||
During the WinEHPrepare pass, the handler functions are outlined into handler
|
||||
functions and the original landing pad code is replaced with a call to the
|
||||
``llvm.eh.actions`` intrinsic that describes the order in which handlers will
|
||||
be processed from the logical location of the landing pad and an indirect
|
||||
branch to the return value of the ``llvm.eh.actions`` intrinsic. The
|
||||
``llvm.eh.actions`` intrinsic is defined as returning the address at which
|
||||
execution will continue. This is a temporary construct which will be removed
|
||||
before code generation, but it allows for the accurate tracking of control
|
||||
flow until then.
|
||||
|
||||
A typical landing pad will look like this after outlining:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
lpad:
|
||||
%vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
|
||||
cleanup
|
||||
catch i8* bitcast (i8** @_ZTIi to i8*)
|
||||
catch i8* bitcast (i8** @_ZTIf to i8*)
|
||||
%recover = call i8* (...)* @llvm.eh.actions(
|
||||
i32 3, i8* bitcast (i8** @_ZTIi to i8*), i8* (i8*, i8*)* @_Z4testb.catch.1)
|
||||
i32 2, i8* null, void (i8*, i8*)* @_Z4testb.cleanup.1)
|
||||
i32 1, i8* bitcast (i8** @_ZTIf to i8*), i8* (i8*, i8*)* @_Z4testb.catch.0)
|
||||
i32 0, i8* null, void (i8*, i8*)* @_Z4testb.cleanup.0)
|
||||
indirectbr i8* %recover, [label %try.cont1, label %try.cont2]
|
||||
|
||||
In this example, the landing pad represents an exception handling context with
|
||||
two catch handlers and a cleanup handler that have been outlined. If an
|
||||
exception is thrown with a type that matches ``_ZTIi``, the ``_Z4testb.catch.1``
|
||||
handler will be called an no clean-up is needed. If an exception is thrown
|
||||
with a type that matches ``_ZTIf``, first the ``_Z4testb.cleanup.1`` handler
|
||||
will be called to perform unwind-related cleanup, then the ``_Z4testb.catch.1``
|
||||
handler will be called. If an exception is throw which does not match either
|
||||
of these types and the exception is handled by another frame further up the
|
||||
call stack, first the ``_Z4testb.cleanup.1`` handler will be called, then the
|
||||
``_Z4testb.cleanup.0`` handler (which corresponds to a different scope) will be
|
||||
called, and exception handling will continue at the next frame in the call
|
||||
stack will be called. One of the catch handlers will return the address of
|
||||
``%try.cont1`` in the parent function and the other will return the address of
|
||||
``%try.cont2``, meaning that execution continues at one of those blocks after
|
||||
an exception is caught.
|
||||
|
||||
|
||||
Exception Handling Intrinsics
|
||||
=============================
|
||||
|
||||
@ -329,6 +435,115 @@ function. This value can be used to compare against the result of
|
||||
|
||||
Uses of this intrinsic are generated by the C++ front-end.
|
||||
|
||||
.. _llvm.eh.begincatch:
|
||||
|
||||
``llvm.eh.begincatch``
|
||||
----------------------
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
void @llvm.eh.begincatch(i8* %ehptr, i8* %ehobj)
|
||||
|
||||
|
||||
This intrinsic marks the beginning of catch handling code within the blocks
|
||||
following a ``landingpad`` instruction. The exact behavior of this function
|
||||
depends on the compilation target and the personality function associated
|
||||
with the ``landingpad`` instruction.
|
||||
|
||||
The first argument to this intrinsic is a pointer that was previously extracted
|
||||
from the aggregate return value of the ``landingpad`` instruction. The second
|
||||
argument to the intrinsic is a pointer to stack space where the exception object
|
||||
should be stored. The runtime handles the details of copying the exception
|
||||
object into the slot. If the second parameter is null, no copy occurs.
|
||||
|
||||
Uses of this intrinsic are generated by the C++ front-end. Many targets will
|
||||
use implementation-specific functions (such as ``__cxa_begin_catch``) instead
|
||||
of this intrinsic. The intrinsic is provided for targets that require a more
|
||||
abstract interface.
|
||||
|
||||
When used in the native Windows C++ exception handling implementation, this
|
||||
intrinsic serves as a placeholder to delimit code before a catch handler is
|
||||
outlined. When the handler is is outlined, this intrinsic will be replaced
|
||||
by instructions that retrieve the exception object pointer from the frame
|
||||
allocation block.
|
||||
|
||||
|
||||
.. _llvm.eh.endcatch:
|
||||
|
||||
``llvm.eh.endcatch``
|
||||
----------------------
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
void @llvm.eh.endcatch()
|
||||
|
||||
|
||||
This intrinsic marks the end of catch handling code within the current block,
|
||||
which will be a successor of a block which called ``llvm.eh.begincatch''.
|
||||
The exact behavior of this function depends on the compilation target and the
|
||||
personality function associated with the corresponding ``landingpad``
|
||||
instruction.
|
||||
|
||||
There may be more than one call to ``llvm.eh.endcatch`` for any given call to
|
||||
``llvm.eh.begincatch`` with each ``llvm.eh.endcatch`` call corresponding to the
|
||||
end of a different control path. All control paths following a call to
|
||||
``llvm.eh.begincatch`` must reach a call to ``llvm.eh.endcatch``.
|
||||
|
||||
Uses of this intrinsic are generated by the C++ front-end. Many targets will
|
||||
use implementation-specific functions (such as ``__cxa_begin_catch``) instead
|
||||
of this intrinsic. The intrinsic is provided for targets that require a more
|
||||
abstract interface.
|
||||
|
||||
When used in the native Windows C++ exception handling implementation, this
|
||||
intrinsic serves as a placeholder to delimit code before a catch handler is
|
||||
outlined. After the handler is outlined, this intrinsic is simply removed.
|
||||
|
||||
.. _llvm.eh.actions:
|
||||
|
||||
``llvm.eh.actions``
|
||||
----------------------
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
void @llvm.eh.actions()
|
||||
|
||||
This intrinsic represents the list of actions to take when an exception is
|
||||
thrown. It is typically used by Windows exception handling schemes where cleanup
|
||||
outlining is required by the runtime. The arguments are a sequence of ``i32``
|
||||
sentinels indicating the action type followed by some pre-determined number of
|
||||
arguments required to implement that action.
|
||||
|
||||
A code of ``i32 0`` indicates a cleanup action, which expects one additional
|
||||
argument. The argument is a pointer to a function that implements the cleanup
|
||||
action.
|
||||
|
||||
A code of ``i32 1`` indicates a catch action, which expects three additional
|
||||
arguments. Different EH schemes give different meanings to the three arguments,
|
||||
but the first argument indicates whether the catch should fire, the second is
|
||||
the frameescape index of the exception object, and the third is the code to run
|
||||
to catch the exception.
|
||||
|
||||
For Windows C++ exception handling, the first argument for a catch handler is a
|
||||
pointer to the RTTI type descriptor for the object to catch. The second
|
||||
argument is an index into the argument list of the ``llvm.frameescape`` call in
|
||||
the main function. The exception object will be copied into the provided stack
|
||||
object. If the exception object is not required, this argument should be -1.
|
||||
The third argument is a pointer to a function implementing the catch. This
|
||||
function returns the address of the basic block where execution should resume
|
||||
after handling the exception.
|
||||
|
||||
For Windows SEH, the first argument is a pointer to the filter function, which
|
||||
indicates if the exception should be caught or not. The second argument is
|
||||
typically negative one. The third argument is the address of a basic block
|
||||
where the exception will be handled. In other words, catch handlers are not
|
||||
outlined in SEH. After running cleanups, execution immediately resumes at this
|
||||
PC.
|
||||
|
||||
In order to preserve the structure of the CFG, a call to '``llvm.eh.actions``'
|
||||
must be followed by an ':ref:`indirectbr <i_indirectbr>`' instruction that
|
||||
jumps to the result of the intrinsic call.
|
||||
|
||||
|
||||
SJLJ Intrinsics
|
||||
---------------
|
||||
|
||||
|
@ -178,42 +178,46 @@ Adding a new instruction
|
||||
to maintain compatibility with the previous version. Only add an instruction
|
||||
if it is absolutely necessary.
|
||||
|
||||
#. ``llvm/include/llvm/Instruction.def``:
|
||||
#. ``llvm/include/llvm/IR/Instruction.def``:
|
||||
|
||||
add a number for your instruction and an enum name
|
||||
|
||||
#. ``llvm/include/llvm/Instructions.h``:
|
||||
#. ``llvm/include/llvm/IR/Instructions.h``:
|
||||
|
||||
add a definition for the class that will represent your instruction
|
||||
|
||||
#. ``llvm/include/llvm/Support/InstVisitor.h``:
|
||||
#. ``llvm/include/llvm/IR/InstVisitor.h``:
|
||||
|
||||
add a prototype for a visitor to your new instruction type
|
||||
|
||||
#. ``llvm/lib/AsmParser/Lexer.l``:
|
||||
#. ``llvm/lib/AsmParser/LLLexer.cpp``:
|
||||
|
||||
add a new token to parse your instruction from assembly text file
|
||||
|
||||
#. ``llvm/lib/AsmParser/llvmAsmParser.y``:
|
||||
#. ``llvm/lib/AsmParser/LLParser.cpp``:
|
||||
|
||||
add the grammar on how your instruction can be read and what it will
|
||||
construct as a result
|
||||
|
||||
#. ``llvm/lib/Bitcode/Reader/Reader.cpp``:
|
||||
#. ``llvm/lib/Bitcode/Reader/BitcodeReader.cpp``:
|
||||
|
||||
add a case for your instruction and how it will be parsed from bitcode
|
||||
|
||||
#. ``llvm/lib/VMCore/Instruction.cpp``:
|
||||
#. ``llvm/lib/Bitcode/Writer/BitcodeWriter.cpp``:
|
||||
|
||||
add a case for your instruction and how it will be parsed from bitcode
|
||||
|
||||
#. ``llvm/lib/IR/Instruction.cpp``:
|
||||
|
||||
add a case for how your instruction will be printed out to assembly
|
||||
|
||||
#. ``llvm/lib/VMCore/Instructions.cpp``:
|
||||
#. ``llvm/lib/IR/Instructions.cpp``:
|
||||
|
||||
implement the class you defined in ``llvm/include/llvm/Instructions.h``
|
||||
|
||||
#. Test your instruction
|
||||
|
||||
#. ``llvm/lib/Target/*``:
|
||||
#. ``llvm/lib/Target/*``:
|
||||
|
||||
add support for your instruction to code generators, or add a lowering pass.
|
||||
|
||||
@ -236,69 +240,88 @@ Adding a new type
|
||||
Adding a fundamental type
|
||||
-------------------------
|
||||
|
||||
#. ``llvm/include/llvm/Type.h``:
|
||||
#. ``llvm/include/llvm/IR/Type.h``:
|
||||
|
||||
add enum for the new type; add static ``Type*`` for this type
|
||||
|
||||
#. ``llvm/lib/VMCore/Type.cpp``:
|
||||
#. ``llvm/lib/IR/Type.cpp`` and ``llvm/lib/IR/ValueTypes.cpp``:
|
||||
|
||||
add mapping from ``TypeID`` => ``Type*``; initialize the static ``Type*``
|
||||
|
||||
#. ``llvm/lib/AsmReader/Lexer.l``:
|
||||
#. ``llvm/llvm/llvm-c/Core.cpp``:
|
||||
|
||||
add enum ``LLVMTypeKind`` and modify
|
||||
``LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty)`` for the new type
|
||||
|
||||
#. ``llvm/include/llvm/IR/TypeBuilder.h``:
|
||||
|
||||
add new class to represent new type in the hierarchy
|
||||
|
||||
#. ``llvm/lib/AsmParser/LLLexer.cpp``:
|
||||
|
||||
add ability to parse in the type from text assembly
|
||||
|
||||
#. ``llvm/lib/AsmReader/llvmAsmParser.y``:
|
||||
#. ``llvm/lib/AsmParser/LLParser.cpp``:
|
||||
|
||||
add a token for that type
|
||||
|
||||
#. ``llvm/lib/Bitcode/Writer/BitcodeWriter.cpp``:
|
||||
|
||||
modify ``static void WriteTypeTable(const ValueEnumerator &VE,
|
||||
BitstreamWriter &Stream)`` to serialize your type
|
||||
|
||||
#. ``llvm/lib/Bitcode/Reader/BitcodeReader.cpp``:
|
||||
|
||||
modify ``bool BitcodeReader::ParseTypeType()`` to read your data type
|
||||
|
||||
#. ``include/llvm/Bitcode/LLVMBitCodes.h``:
|
||||
|
||||
add enum ``TypeCodes`` for the new type
|
||||
|
||||
Adding a derived type
|
||||
---------------------
|
||||
|
||||
#. ``llvm/include/llvm/Type.h``:
|
||||
#. ``llvm/include/llvm/IR/Type.h``:
|
||||
|
||||
add enum for the new type; add a forward declaration of the type also
|
||||
|
||||
#. ``llvm/include/llvm/DerivedTypes.h``:
|
||||
#. ``llvm/include/llvm/IR/DerivedTypes.h``:
|
||||
|
||||
add new class to represent new class in the hierarchy; add forward
|
||||
declaration to the TypeMap value type
|
||||
|
||||
#. ``llvm/lib/VMCore/Type.cpp``:
|
||||
#. ``llvm/lib/IR/Type.cpp`` and ``llvm/lib/IR/ValueTypes.cpp``:
|
||||
|
||||
add support for derived type to:
|
||||
add support for derived type, notably `enum TypeID` and `is`, `get` methods.
|
||||
|
||||
.. code-block:: c++
|
||||
#. ``llvm/llvm/llvm-c/Core.cpp``:
|
||||
|
||||
std::string getTypeDescription(const Type &Ty,
|
||||
std::vector<const Type*> &TypeStack)
|
||||
bool TypesEqual(const Type *Ty, const Type *Ty2,
|
||||
std::map<const Type*, const Type*> &EqTypes)
|
||||
add enum ``LLVMTypeKind`` and modify
|
||||
`LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty)` for the new type
|
||||
|
||||
add necessary member functions for type, and factory methods
|
||||
#. ``llvm/include/llvm/IR/TypeBuilder.h``:
|
||||
|
||||
#. ``llvm/lib/AsmReader/Lexer.l``:
|
||||
add new class to represent new class in the hierarchy
|
||||
|
||||
add ability to parse in the type from text assembly
|
||||
#. ``llvm/lib/AsmParser/LLLexer.cpp``:
|
||||
|
||||
#. ``llvm/lib/Bitcode/Writer/Writer.cpp``:
|
||||
modify ``lltok::Kind LLLexer::LexIdentifier()`` to add ability to
|
||||
parse in the type from text assembly
|
||||
|
||||
modify ``void BitcodeWriter::outputType(const Type *T)`` to serialize your
|
||||
type
|
||||
#. ``llvm/lib/Bitcode/Writer/BitcodeWriter.cpp``:
|
||||
|
||||
#. ``llvm/lib/Bitcode/Reader/Reader.cpp``:
|
||||
modify ``static void WriteTypeTable(const ValueEnumerator &VE,
|
||||
BitstreamWriter &Stream)`` to serialize your type
|
||||
|
||||
modify ``const Type *BitcodeReader::ParseType()`` to read your data type
|
||||
#. ``llvm/lib/Bitcode/Reader/BitcodeReader.cpp``:
|
||||
|
||||
#. ``llvm/lib/VMCore/AsmWriter.cpp``:
|
||||
modify ``bool BitcodeReader::ParseTypeType()`` to read your data type
|
||||
|
||||
modify
|
||||
#. ``include/llvm/Bitcode/LLVMBitCodes.h``:
|
||||
|
||||
.. code-block:: c++
|
||||
add enum ``TypeCodes`` for the new type
|
||||
|
||||
void calcTypeName(const Type *Ty,
|
||||
std::vector<const Type*> &TypeStack,
|
||||
std::map<const Type*,std::string> &TypeNames,
|
||||
std::string &Result)
|
||||
#. ``llvm/lib/IR/AsmWriter.cpp``:
|
||||
|
||||
modify ``void TypePrinting::print(Type *Ty, raw_ostream &OS)``
|
||||
to output the new derived type
|
||||
|
@ -165,6 +165,29 @@ and ``.bar`` is associated to ``.foo``.
|
||||
.section .foo,"bw",discard, "sym"
|
||||
.section .bar,"rd",associative, "sym"
|
||||
|
||||
|
||||
ELF-Dependent
|
||||
-------------
|
||||
|
||||
``.section`` Directive
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In order to support creating multiple sections with the same name and comdat,
|
||||
it is possible to add an unique number at the end of the ``.seciton`` directive.
|
||||
For example, the following code creates two sections named ``.text``.
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
.section .text,"ax",@progbits,unique,1
|
||||
nop
|
||||
|
||||
.section .text,"ax",@progbits,unique,2
|
||||
nop
|
||||
|
||||
|
||||
The unique number is not present in the resulting object at all. It is just used
|
||||
in the assembler to differentiate the sections.
|
||||
|
||||
Target Specific Behaviour
|
||||
=========================
|
||||
|
||||
|
@ -102,7 +102,7 @@ grabbing the wrong linker/assembler/etc, there are two ways to fix it:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% PATH=[the path without the bad program] ./configure ...
|
||||
% PATH=[the path without the bad program] $LLVM_SRC_DIR/configure ...
|
||||
|
||||
This is still somewhat inconvenient, but it allows ``configure`` to do its
|
||||
work without having to adjust your ``PATH`` permanently.
|
||||
|
183
docs/Frontend/PerformanceTips.rst
Normal file
183
docs/Frontend/PerformanceTips.rst
Normal file
@ -0,0 +1,183 @@
|
||||
=====================================
|
||||
Performance Tips for Frontend Authors
|
||||
=====================================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 2
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
||||
The intended audience of this document is developers of language frontends
|
||||
targeting LLVM IR. This document is home to a collection of tips on how to
|
||||
generate IR that optimizes well. As with any optimizer, LLVM has its strengths
|
||||
and weaknesses. In some cases, surprisingly small changes in the source IR
|
||||
can have a large effect on the generated code.
|
||||
|
||||
Avoid loads and stores of large aggregate type
|
||||
================================================
|
||||
|
||||
LLVM currently does not optimize well loads and stores of large :ref:`aggregate
|
||||
types <t_aggregate>` (i.e. structs and arrays). As an alternative, consider
|
||||
loading individual fields from memory.
|
||||
|
||||
Aggregates that are smaller than the largest (performant) load or store
|
||||
instruction supported by the targeted hardware are well supported. These can
|
||||
be an effective way to represent collections of small packed fields.
|
||||
|
||||
Prefer zext over sext when legal
|
||||
==================================
|
||||
|
||||
On some architectures (X86_64 is one), sign extension can involve an extra
|
||||
instruction whereas zero extension can be folded into a load. LLVM will try to
|
||||
replace a sext with a zext when it can be proven safe, but if you have
|
||||
information in your source language about the range of a integer value, it can
|
||||
be profitable to use a zext rather than a sext.
|
||||
|
||||
Alternatively, you can :ref:`specify the range of the value using metadata
|
||||
<range-metadata>` and LLVM can do the sext to zext conversion for you.
|
||||
|
||||
Zext GEP indices to machine register width
|
||||
============================================
|
||||
|
||||
Internally, LLVM often promotes the width of GEP indices to machine register
|
||||
width. When it does so, it will default to using sign extension (sext)
|
||||
operations for safety. If your source language provides information about
|
||||
the range of the index, you may wish to manually extend indices to machine
|
||||
register width using a zext instruction.
|
||||
|
||||
Other things to consider
|
||||
=========================
|
||||
|
||||
#. Make sure that a DataLayout is provided (this will likely become required in
|
||||
the near future, but is certainly important for optimization).
|
||||
|
||||
#. Add nsw/nuw flags as appropriate. Reasoning about overflow is
|
||||
generally hard for an optimizer so providing these facts from the frontend
|
||||
can be very impactful.
|
||||
|
||||
#. Use fast-math flags on floating point operations if legal. If you don't
|
||||
need strict IEEE floating point semantics, there are a number of additional
|
||||
optimizations that can be performed. This can be highly impactful for
|
||||
floating point intensive computations.
|
||||
|
||||
#. Use inbounds on geps. This can help to disambiguate some aliasing queries.
|
||||
|
||||
#. Add noalias/align/dereferenceable/nonnull to function arguments and return
|
||||
values as appropriate
|
||||
|
||||
#. Mark functions as readnone/readonly or noreturn/nounwind when known. The
|
||||
optimizer will try to infer these flags, but may not always be able to.
|
||||
Manual annotations are particularly important for external functions that
|
||||
the optimizer can not analyze.
|
||||
|
||||
#. Use ptrtoint/inttoptr sparingly (they interfere with pointer aliasing
|
||||
analysis), prefer GEPs
|
||||
|
||||
#. Use the lifetime.start/lifetime.end and invariant.start/invariant.end
|
||||
intrinsics where possible. Common profitable uses are for stack like data
|
||||
structures (thus allowing dead store elimination) and for describing
|
||||
life times of allocas (thus allowing smaller stack sizes).
|
||||
|
||||
#. Use pointer aliasing metadata, especially tbaa metadata, to communicate
|
||||
otherwise-non-deducible pointer aliasing facts
|
||||
|
||||
#. Use the "most-private" possible linkage types for the functions being defined
|
||||
(private, internal or linkonce_odr preferably)
|
||||
|
||||
#. Mark invariant locations using !invariant.load and TBAA's constant flags
|
||||
|
||||
#. Prefer globals over inttoptr of a constant address - this gives you
|
||||
dereferencability information. In MCJIT, use getSymbolAddress to provide
|
||||
actual address.
|
||||
|
||||
#. Be wary of ordered and atomic memory operations. They are hard to optimize
|
||||
and may not be well optimized by the current optimizer. Depending on your
|
||||
source language, you may consider using fences instead.
|
||||
|
||||
#. If calling a function which is known to throw an exception (unwind), use
|
||||
an invoke with a normal destination which contains an unreachable
|
||||
instruction. This form conveys to the optimizer that the call returns
|
||||
abnormally. For an invoke which neither returns normally or requires unwind
|
||||
code in the current function, you can use a noreturn call instruction if
|
||||
desired. This is generally not required because the optimizer will convert
|
||||
an invoke with an unreachable unwind destination to a call instruction.
|
||||
|
||||
#. If you language uses range checks, consider using the IRCE pass. It is not
|
||||
currently part of the standard pass order.
|
||||
|
||||
#. For languages with numerous rarely executed guard conditions (e.g. null
|
||||
checks, type checks, range checks) consider adding an extra execution or
|
||||
two of LoopUnswith and LICM to your pass order. The standard pass order,
|
||||
which is tuned for C and C++ applications, may not be sufficient to remove
|
||||
all dischargeable checks from loops.
|
||||
|
||||
#. Use profile metadata to indicate statically known cold paths, even if
|
||||
dynamic profiling information is not available. This can make a large
|
||||
difference in code placement and thus the performance of tight loops.
|
||||
|
||||
#. When generating code for loops, try to avoid terminating the header block of
|
||||
the loop earlier than necessary. If the terminator of the loop header
|
||||
block is a loop exiting conditional branch, the effectiveness of LICM will
|
||||
be limited for loads not in the header. (This is due to the fact that LLVM
|
||||
may not know such a load is safe to speculatively execute and thus can't
|
||||
lift an otherwise loop invariant load unless it can prove the exiting
|
||||
condition is not taken.) It can be profitable, in some cases, to emit such
|
||||
instructions into the header even if they are not used along a rarely
|
||||
executed path that exits the loop. This guidance specifically does not
|
||||
apply if the condition which terminates the loop header is itself invariant,
|
||||
or can be easily discharged by inspecting the loop index variables.
|
||||
|
||||
#. In hot loops, consider duplicating instructions from small basic blocks
|
||||
which end in highly predictable terminators into their successor blocks.
|
||||
If a hot successor block contains instructions which can be vectorized
|
||||
with the duplicated ones, this can provide a noticeable throughput
|
||||
improvement. Note that this is not always profitable and does involve a
|
||||
potentially large increase in code size.
|
||||
|
||||
#. Avoid high in-degree basic blocks (e.g. basic blocks with dozens or hundreds
|
||||
of predecessors). Among other issues, the register allocator is known to
|
||||
perform badly with confronted with such structures. The only exception to
|
||||
this guidance is that a unified return block with high in-degree is fine.
|
||||
|
||||
#. When checking a value against a constant, emit the check using a consistent
|
||||
comparison type. The GVN pass *will* optimize redundant equalities even if
|
||||
the type of comparison is inverted, but GVN only runs late in the pipeline.
|
||||
As a result, you may miss the opportunity to run other important
|
||||
optimizations. Improvements to EarlyCSE to remove this issue are tracked in
|
||||
Bug 23333.
|
||||
|
||||
#. Avoid using arithmetic intrinsics unless you are *required* by your source
|
||||
language specification to emit a particular code sequence. The optimizer
|
||||
is quite good at reasoning about general control flow and arithmetic, it is
|
||||
not anywhere near as strong at reasoning about the various intrinsics. If
|
||||
profitable for code generation purposes, the optimizer will likely form the
|
||||
intrinsics itself late in the optimization pipeline. It is *very* rarely
|
||||
profitable to emit these directly in the language frontend. This item
|
||||
explicitly includes the use of the :ref:`overflow intrinsics <int_overflow>`.
|
||||
|
||||
#. Avoid using the :ref:`assume intrinsic <int_assume>` until you've
|
||||
established that a) there's no other way to express the given fact and b)
|
||||
that fact is critical for optimization purposes. Assumes are a great
|
||||
prototyping mechanism, but they can have negative effects on both compile
|
||||
time and optimization effectiveness. The former is fixable with enough
|
||||
effort, but the later is fairly fundamental to their designed purpose.
|
||||
|
||||
p.s. If you want to help improve this document, patches expanding any of the
|
||||
above items into standalone sections of their own with a more complete
|
||||
discussion would be very welcome.
|
||||
|
||||
|
||||
Adding to this document
|
||||
=======================
|
||||
|
||||
If you run across a case that you feel deserves to be covered here, please send
|
||||
a patch to `llvm-commits
|
||||
<http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits>`_ for review.
|
||||
|
||||
If you have questions on these items, please direct them to `llvmdev
|
||||
<http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev>`_. The more relevant
|
||||
context you are able to give to your question, the more likely it is to be
|
||||
answered.
|
||||
|
@ -1,13 +1,82 @@
|
||||
=====================================
|
||||
Accurate Garbage Collection with LLVM
|
||||
Garbage Collection with LLVM
|
||||
=====================================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
||||
This document covers how to integrate LLVM into a compiler for a language which
|
||||
supports garbage collection. **Note that LLVM itself does not provide a
|
||||
garbage collector.** You must provide your own.
|
||||
|
||||
Quick Start
|
||||
============
|
||||
|
||||
First, you should pick a collector strategy. LLVM includes a number of built
|
||||
in ones, but you can also implement a loadable plugin with a custom definition.
|
||||
Note that the collector strategy is a description of how LLVM should generate
|
||||
code such that it interacts with your collector and runtime, not a description
|
||||
of the collector itself.
|
||||
|
||||
Next, mark your generated functions as using your chosen collector strategy.
|
||||
From c++, you can call:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
F.setGC(<collector description name>);
|
||||
|
||||
|
||||
This will produce IR like the following fragment:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define void @foo() gc "<collector description name>" { ... }
|
||||
|
||||
|
||||
When generating LLVM IR for your functions, you will need to:
|
||||
|
||||
* Use ``@llvm.gcread`` and/or ``@llvm.gcwrite`` in place of standard load and
|
||||
store instructions. These intrinsics are used to represent load and store
|
||||
barriers. If you collector does not require such barriers, you can skip
|
||||
this step.
|
||||
|
||||
* Use the memory allocation routines provided by your garbage collector's
|
||||
runtime library.
|
||||
|
||||
* If your collector requires them, generate type maps according to your
|
||||
runtime's binary interface. LLVM is not involved in the process. In
|
||||
particular, the LLVM type system is not suitable for conveying such
|
||||
information though the compiler.
|
||||
|
||||
* Insert any coordination code required for interacting with your collector.
|
||||
Many collectors require running application code to periodically check a
|
||||
flag and conditionally call a runtime function. This is often referred to
|
||||
as a safepoint poll.
|
||||
|
||||
You will need to identify roots (i.e. references to heap objects your collector
|
||||
needs to know about) in your generated IR, so that LLVM can encode them into
|
||||
your final stack maps. Depending on the collector strategy chosen, this is
|
||||
accomplished by using either the ``@llvm.gcroot`` intrinsics or an
|
||||
``gc.statepoint`` relocation sequence.
|
||||
|
||||
Don't forget to create a root for each intermediate value that is generated when
|
||||
evaluating an expression. In ``h(f(), g())``, the result of ``f()`` could
|
||||
easily be collected if evaluating ``g()`` triggers a collection.
|
||||
|
||||
Finally, you need to link your runtime library with the generated program
|
||||
executable (for a static compiler) or ensure the appropriate symbols are
|
||||
available for the runtime linker (for a JIT compiler).
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
What is Garbage Collection?
|
||||
---------------------------
|
||||
|
||||
Garbage collection is a widely used technique that frees the programmer from
|
||||
having to know the lifetimes of heap objects, making software easier to produce
|
||||
and maintain. Many programming languages rely on garbage collection for
|
||||
@ -59,31 +128,34 @@ instance, the intrinsics permit:
|
||||
|
||||
* generational collectors
|
||||
|
||||
* reference counting
|
||||
|
||||
* incremental collectors
|
||||
|
||||
* concurrent collectors
|
||||
|
||||
* cooperative collectors
|
||||
|
||||
We hope that the primitive support built into the LLVM IR is sufficient to
|
||||
support a broad class of garbage collected languages including Scheme, ML, Java,
|
||||
C#, Perl, Python, Lua, Ruby, other scripting languages, and more.
|
||||
* reference counting
|
||||
|
||||
However, LLVM does not itself provide a garbage collector --- this should be
|
||||
part of your language's runtime library. LLVM provides a framework for compile
|
||||
time :ref:`code generation plugins <plugin>`. The role of these plugins is to
|
||||
We hope that the support built into the LLVM IR is sufficient to support a
|
||||
broad class of garbage collected languages including Scheme, ML, Java, C#,
|
||||
Perl, Python, Lua, Ruby, other scripting languages, and more.
|
||||
|
||||
Note that LLVM **does not itself provide a garbage collector** --- this should
|
||||
be part of your language's runtime library. LLVM provides a framework for
|
||||
describing the garbage collectors requirements to the compiler. In particular,
|
||||
LLVM provides support for generating stack maps at call sites, polling for a
|
||||
safepoint, and emitting load and store barriers. You can also extend LLVM -
|
||||
possibly through a loadable :ref:`code generation plugins <plugin>` - to
|
||||
generate code and data structures which conforms to the *binary interface*
|
||||
specified by the *runtime library*. This is similar to the relationship between
|
||||
LLVM and DWARF debugging info, for example. The difference primarily lies in
|
||||
the lack of an established standard in the domain of garbage collection --- thus
|
||||
the plugins.
|
||||
the need for a flexible extension mechanism.
|
||||
|
||||
The aspects of the binary interface with which LLVM's GC support is
|
||||
concerned are:
|
||||
|
||||
* Creation of GC-safe points within code where collection is allowed to execute
|
||||
* Creation of GC safepoints within code where collection is allowed to execute
|
||||
safely.
|
||||
|
||||
* Computation of the stack map. For each safe point in the code, object
|
||||
@ -111,205 +183,63 @@ There are additional areas that LLVM does not directly address:
|
||||
In general, LLVM's support for GC does not include features which can be
|
||||
adequately addressed with other features of the IR and does not specify a
|
||||
particular binary interface. On the plus side, this means that you should be
|
||||
able to integrate LLVM with an existing runtime. On the other hand, it leaves a
|
||||
lot of work for the developer of a novel language. However, it's easy to get
|
||||
started quickly and scale up to a more sophisticated implementation as your
|
||||
compiler matures.
|
||||
|
||||
Getting started
|
||||
===============
|
||||
|
||||
Using a GC with LLVM implies many things, for example:
|
||||
|
||||
* Write a runtime library or find an existing one which implements a GC heap.
|
||||
|
||||
#. Implement a memory allocator.
|
||||
|
||||
#. Design a binary interface for the stack map, used to identify references
|
||||
within a stack frame on the machine stack.\*
|
||||
|
||||
#. Implement a stack crawler to discover functions on the call stack.\*
|
||||
|
||||
#. Implement a registry for global roots.
|
||||
|
||||
#. Design a binary interface for type maps, used to identify references
|
||||
within heap objects.
|
||||
|
||||
#. Implement a collection routine bringing together all of the above.
|
||||
|
||||
* Emit compatible code from your compiler.
|
||||
|
||||
* Initialization in the main function.
|
||||
|
||||
* Use the ``gc "..."`` attribute to enable GC code generation (or
|
||||
``F.setGC("...")``).
|
||||
|
||||
* Use ``@llvm.gcroot`` to mark stack roots.
|
||||
|
||||
* Use ``@llvm.gcread`` and/or ``@llvm.gcwrite`` to manipulate GC references,
|
||||
if necessary.
|
||||
|
||||
* Allocate memory using the GC allocation routine provided by the runtime
|
||||
library.
|
||||
|
||||
* Generate type maps according to your runtime's binary interface.
|
||||
|
||||
* Write a compiler plugin to interface LLVM with the runtime library.\*
|
||||
|
||||
* Lower ``@llvm.gcread`` and ``@llvm.gcwrite`` to appropriate code
|
||||
sequences.\*
|
||||
|
||||
* Compile LLVM's stack map to the binary form expected by the runtime.
|
||||
|
||||
* Load the plugin into the compiler. Use ``llc -load`` or link the plugin
|
||||
statically with your language's compiler.\*
|
||||
|
||||
* Link program executables with the runtime.
|
||||
|
||||
To help with several of these tasks (those indicated with a \*), LLVM includes a
|
||||
highly portable, built-in ShadowStack code generator. It is compiled into
|
||||
``llc`` and works even with the interpreter and C backends.
|
||||
|
||||
In your compiler
|
||||
----------------
|
||||
|
||||
To turn the shadow stack on for your functions, first call:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
F.setGC("shadow-stack");
|
||||
|
||||
for each function your compiler emits. Since the shadow stack is built into
|
||||
LLVM, you do not need to load a plugin.
|
||||
|
||||
Your compiler must also use ``@llvm.gcroot`` as documented. Don't forget to
|
||||
create a root for each intermediate value that is generated when evaluating an
|
||||
expression. In ``h(f(), g())``, the result of ``f()`` could easily be collected
|
||||
if evaluating ``g()`` triggers a collection.
|
||||
|
||||
There's no need to use ``@llvm.gcread`` and ``@llvm.gcwrite`` over plain
|
||||
``load`` and ``store`` for now. You will need them when switching to a more
|
||||
advanced GC.
|
||||
|
||||
In your runtime
|
||||
---------------
|
||||
|
||||
The shadow stack doesn't imply a memory allocation algorithm. A semispace
|
||||
collector or building atop ``malloc`` are great places to start, and can be
|
||||
implemented with very little code.
|
||||
|
||||
When it comes time to collect, however, your runtime needs to traverse the stack
|
||||
roots, and for this it needs to integrate with the shadow stack. Luckily, doing
|
||||
so is very simple. (This code is heavily commented to help you understand the
|
||||
data structure, but there are only 20 lines of meaningful code.)
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
/// @brief The map for a single function's stack frame. One of these is
|
||||
/// compiled as constant data into the executable for each function.
|
||||
///
|
||||
/// Storage of metadata values is elided if the %metadata parameter to
|
||||
/// @llvm.gcroot is null.
|
||||
struct FrameMap {
|
||||
int32_t NumRoots; //< Number of roots in stack frame.
|
||||
int32_t NumMeta; //< Number of metadata entries. May be < NumRoots.
|
||||
const void *Meta[0]; //< Metadata for each root.
|
||||
};
|
||||
|
||||
/// @brief A link in the dynamic shadow stack. One of these is embedded in
|
||||
/// the stack frame of each function on the call stack.
|
||||
struct StackEntry {
|
||||
StackEntry *Next; //< Link to next stack entry (the caller's).
|
||||
const FrameMap *Map; //< Pointer to constant FrameMap.
|
||||
void *Roots[0]; //< Stack roots (in-place array).
|
||||
};
|
||||
|
||||
/// @brief The head of the singly-linked list of StackEntries. Functions push
|
||||
/// and pop onto this in their prologue and epilogue.
|
||||
///
|
||||
/// Since there is only a global list, this technique is not threadsafe.
|
||||
StackEntry *llvm_gc_root_chain;
|
||||
|
||||
/// @brief Calls Visitor(root, meta) for each GC root on the stack.
|
||||
/// root and meta are exactly the values passed to
|
||||
/// @llvm.gcroot.
|
||||
///
|
||||
/// Visitor could be a function to recursively mark live objects. Or it
|
||||
/// might copy them to another heap or generation.
|
||||
///
|
||||
/// @param Visitor A function to invoke for every GC root on the stack.
|
||||
void visitGCRoots(void (*Visitor)(void **Root, const void *Meta)) {
|
||||
for (StackEntry *R = llvm_gc_root_chain; R; R = R->Next) {
|
||||
unsigned i = 0;
|
||||
|
||||
// For roots [0, NumMeta), the metadata pointer is in the FrameMap.
|
||||
for (unsigned e = R->Map->NumMeta; i != e; ++i)
|
||||
Visitor(&R->Roots[i], R->Map->Meta[i]);
|
||||
|
||||
// For roots [NumMeta, NumRoots), the metadata pointer is null.
|
||||
for (unsigned e = R->Map->NumRoots; i != e; ++i)
|
||||
Visitor(&R->Roots[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
About the shadow stack
|
||||
----------------------
|
||||
|
||||
Unlike many GC algorithms which rely on a cooperative code generator to compile
|
||||
stack maps, this algorithm carefully maintains a linked list of stack roots
|
||||
[:ref:`Henderson2002 <henderson02>`]. This so-called "shadow stack" mirrors the
|
||||
machine stack. Maintaining this data structure is slower than using a stack map
|
||||
compiled into the executable as constant data, but has a significant portability
|
||||
advantage because it requires no special support from the target code generator,
|
||||
and does not require tricky platform-specific code to crawl the machine stack.
|
||||
|
||||
The tradeoff for this simplicity and portability is:
|
||||
|
||||
* High overhead per function call.
|
||||
|
||||
* Not thread-safe.
|
||||
|
||||
Still, it's an easy way to get started. After your compiler and runtime are up
|
||||
and running, writing a :ref:`plugin <plugin>` will allow you to take advantage
|
||||
of :ref:`more advanced GC features <collector-algos>` of LLVM in order to
|
||||
improve performance.
|
||||
able to integrate LLVM with an existing runtime. On the other hand, it can
|
||||
have the effect of leaving a lot of work for the developer of a novel
|
||||
language. We try to mitigate this by providing built in collector strategy
|
||||
descriptions that can work with many common collector designs and easy
|
||||
extension points. If you don't already have a specific binary interface
|
||||
you need to support, we recommend trying to use one of these built in collector
|
||||
strategies.
|
||||
|
||||
.. _gc_intrinsics:
|
||||
|
||||
IR features
|
||||
===========
|
||||
LLVM IR Features
|
||||
================
|
||||
|
||||
This section describes the garbage collection facilities provided by the
|
||||
:doc:`LLVM intermediate representation <LangRef>`. The exact behavior of these
|
||||
IR features is specified by the binary interface implemented by a :ref:`code
|
||||
generation plugin <plugin>`, not by this document.
|
||||
|
||||
These facilities are limited to those strictly necessary; they are not intended
|
||||
to be a complete interface to any garbage collector. A program will need to
|
||||
interface with the GC library using the facilities provided by that program.
|
||||
IR features is specified by the selected :ref:`GC strategy description
|
||||
<plugin>`.
|
||||
|
||||
Specifying GC code generation: ``gc "..."``
|
||||
-------------------------------------------
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define ty @name(...) gc "name" { ...
|
||||
define <returntype> @name(...) gc "name" { ... }
|
||||
|
||||
The ``gc`` function attribute is used to specify the desired GC style to the
|
||||
The ``gc`` function attribute is used to specify the desired GC strategy to the
|
||||
compiler. Its programmatic equivalent is the ``setGC`` method of ``Function``.
|
||||
|
||||
Setting ``gc "name"`` on a function triggers a search for a matching code
|
||||
generation plugin "*name*"; it is that plugin which defines the exact nature of
|
||||
the code generated to support GC. If none is found, the compiler will raise an
|
||||
error.
|
||||
Setting ``gc "name"`` on a function triggers a search for a matching subclass
|
||||
of GCStrategy. Some collector strategies are built in. You can add others
|
||||
using either the loadable plugin mechanism, or by patching your copy of LLVM.
|
||||
It is the selected GC strategy which defines the exact nature of the code
|
||||
generated to support GC. If none is found, the compiler will raise an error.
|
||||
|
||||
Specifying the GC style on a per-function basis allows LLVM to link together
|
||||
programs that use different garbage collection algorithms (or none at all).
|
||||
|
||||
.. _gcroot:
|
||||
|
||||
Identifying GC roots on the stack: ``llvm.gcroot``
|
||||
--------------------------------------------------
|
||||
Identifying GC roots on the stack
|
||||
----------------------------------
|
||||
|
||||
LLVM currently supports two different mechanisms for describing references in
|
||||
compiled code at safepoints. ``llvm.gcroot`` is the older mechanism;
|
||||
``gc.statepoint`` has been added more recently. At the moment, you can choose
|
||||
either implementation (on a per :ref:`GC strategy <plugin>` basis). Longer
|
||||
term, we will probably either migrate away from ``llvm.gcroot`` entirely, or
|
||||
substantially merge their implementations. Note that most new development
|
||||
work is focused on ``gc.statepoint``.
|
||||
|
||||
Using ``gc.statepoint``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
:doc:`This page <Statepoints>` contains detailed documentation for
|
||||
``gc.statepoint``.
|
||||
|
||||
Using ``llvm.gcwrite``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
@ -317,24 +247,27 @@ Identifying GC roots on the stack: ``llvm.gcroot``
|
||||
|
||||
The ``llvm.gcroot`` intrinsic is used to inform LLVM that a stack variable
|
||||
references an object on the heap and is to be tracked for garbage collection.
|
||||
The exact impact on generated code is specified by a :ref:`compiler plugin
|
||||
<plugin>`. All calls to ``llvm.gcroot`` **must** reside inside the first basic
|
||||
block.
|
||||
|
||||
A compiler which uses mem2reg to raise imperative code using ``alloca`` into SSA
|
||||
form need only add a call to ``@llvm.gcroot`` for those variables which a
|
||||
pointers into the GC heap.
|
||||
|
||||
It is also important to mark intermediate values with ``llvm.gcroot``. For
|
||||
example, consider ``h(f(), g())``. Beware leaking the result of ``f()`` in the
|
||||
case that ``g()`` triggers a collection. Note, that stack variables must be
|
||||
initialized and marked with ``llvm.gcroot`` in function's prologue.
|
||||
The exact impact on generated code is specified by the Function's selected
|
||||
:ref:`GC strategy <plugin>`. All calls to ``llvm.gcroot`` **must** reside
|
||||
inside the first basic block.
|
||||
|
||||
The first argument **must** be a value referring to an alloca instruction or a
|
||||
bitcast of an alloca. The second contains a pointer to metadata that should be
|
||||
associated with the pointer, and **must** be a constant or global value
|
||||
address. If your target collector uses tags, use a null pointer for metadata.
|
||||
|
||||
A compiler which performs manual SSA construction **must** ensure that SSA
|
||||
values representing GC references are stored in to the alloca passed to the
|
||||
respective ``gcroot`` before every call site and reloaded after every call.
|
||||
A compiler which uses mem2reg to raise imperative code using ``alloca`` into
|
||||
SSA form need only add a call to ``@llvm.gcroot`` for those variables which
|
||||
are pointers into the GC heap.
|
||||
|
||||
It is also important to mark intermediate values with ``llvm.gcroot``. For
|
||||
example, consider ``h(f(), g())``. Beware leaking the result of ``f()`` in the
|
||||
case that ``g()`` triggers a collection. Note, that stack variables must be
|
||||
initialized and marked with ``llvm.gcroot`` in function's prologue.
|
||||
|
||||
The ``%metadata`` argument can be used to avoid requiring heap objects to have
|
||||
'isa' pointers or tag bits. [Appel89_, Goldberg91_, Tolmach94_] If specified,
|
||||
its value will be tracked along with the location of the pointer in the stack
|
||||
@ -407,12 +340,18 @@ pointer:
|
||||
%derived = getelementptr %object, i32 0, i32 2, i32 %n
|
||||
|
||||
LLVM does not enforce this relationship between the object and derived pointer
|
||||
(although a :ref:`plugin <plugin>` might). However, it would be an unusual
|
||||
collector that violated it.
|
||||
(although a particular :ref:`collector strategy <plugin>` might). However, it
|
||||
would be an unusual collector that violated it.
|
||||
|
||||
The use of these intrinsics is naturally optional if the target GC does require
|
||||
the corresponding barrier. Such a GC plugin will replace the intrinsic calls
|
||||
with the corresponding ``load`` or ``store`` instruction if they are used.
|
||||
The use of these intrinsics is naturally optional if the target GC does not
|
||||
require the corresponding barrier. The GC strategy used with such a collector
|
||||
should replace the intrinsic calls with the corresponding ``load`` or
|
||||
``store`` instruction if they are used.
|
||||
|
||||
One known deficiency with the current design is that the barrier intrinsics do
|
||||
not include the size or alignment of the underlying operation performed. It is
|
||||
currently assumed that the operation is of pointer size and the alignment is
|
||||
assumed to be the target machine's default alignment.
|
||||
|
||||
Write barrier: ``llvm.gcwrite``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -423,8 +362,8 @@ Write barrier: ``llvm.gcwrite``
|
||||
|
||||
For write barriers, LLVM provides the ``llvm.gcwrite`` intrinsic function. It
|
||||
has exactly the same semantics as a non-volatile ``store`` to the derived
|
||||
pointer (the third argument). The exact code generated is specified by a
|
||||
compiler :ref:`plugin <plugin>`.
|
||||
pointer (the third argument). The exact code generated is specified by the
|
||||
Function's selected :ref:`GC strategy <plugin>`.
|
||||
|
||||
Many important algorithms require write barriers, including generational and
|
||||
concurrent collectors. Additionally, write barriers could be used to implement
|
||||
@ -439,16 +378,212 @@ Read barrier: ``llvm.gcread``
|
||||
|
||||
For read barriers, LLVM provides the ``llvm.gcread`` intrinsic function. It has
|
||||
exactly the same semantics as a non-volatile ``load`` from the derived pointer
|
||||
(the second argument). The exact code generated is specified by a
|
||||
:ref:`compiler plugin <plugin>`.
|
||||
(the second argument). The exact code generated is specified by the Function's
|
||||
selected :ref:`GC strategy <plugin>`.
|
||||
|
||||
Read barriers are needed by fewer algorithms than write barriers, and may have a
|
||||
greater performance impact since pointer reads are more frequent than writes.
|
||||
|
||||
.. _plugin:
|
||||
|
||||
.. _builtin-gc-strategies:
|
||||
|
||||
Built In GC Strategies
|
||||
======================
|
||||
|
||||
LLVM includes built in support for several varieties of garbage collectors.
|
||||
|
||||
The Shadow Stack GC
|
||||
----------------------
|
||||
|
||||
To use this collector strategy, mark your functions with:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
F.setGC("shadow-stack");
|
||||
|
||||
Unlike many GC algorithms which rely on a cooperative code generator to compile
|
||||
stack maps, this algorithm carefully maintains a linked list of stack roots
|
||||
[:ref:`Henderson2002 <henderson02>`]. This so-called "shadow stack" mirrors the
|
||||
machine stack. Maintaining this data structure is slower than using a stack map
|
||||
compiled into the executable as constant data, but has a significant portability
|
||||
advantage because it requires no special support from the target code generator,
|
||||
and does not require tricky platform-specific code to crawl the machine stack.
|
||||
|
||||
The tradeoff for this simplicity and portability is:
|
||||
|
||||
* High overhead per function call.
|
||||
|
||||
* Not thread-safe.
|
||||
|
||||
Still, it's an easy way to get started. After your compiler and runtime are up
|
||||
and running, writing a :ref:`plugin <plugin>` will allow you to take advantage
|
||||
of :ref:`more advanced GC features <collector-algos>` of LLVM in order to
|
||||
improve performance.
|
||||
|
||||
|
||||
The shadow stack doesn't imply a memory allocation algorithm. A semispace
|
||||
collector or building atop ``malloc`` are great places to start, and can be
|
||||
implemented with very little code.
|
||||
|
||||
When it comes time to collect, however, your runtime needs to traverse the stack
|
||||
roots, and for this it needs to integrate with the shadow stack. Luckily, doing
|
||||
so is very simple. (This code is heavily commented to help you understand the
|
||||
data structure, but there are only 20 lines of meaningful code.)
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
/// @brief The map for a single function's stack frame. One of these is
|
||||
/// compiled as constant data into the executable for each function.
|
||||
///
|
||||
/// Storage of metadata values is elided if the %metadata parameter to
|
||||
/// @llvm.gcroot is null.
|
||||
struct FrameMap {
|
||||
int32_t NumRoots; //< Number of roots in stack frame.
|
||||
int32_t NumMeta; //< Number of metadata entries. May be < NumRoots.
|
||||
const void *Meta[0]; //< Metadata for each root.
|
||||
};
|
||||
|
||||
/// @brief A link in the dynamic shadow stack. One of these is embedded in
|
||||
/// the stack frame of each function on the call stack.
|
||||
struct StackEntry {
|
||||
StackEntry *Next; //< Link to next stack entry (the caller's).
|
||||
const FrameMap *Map; //< Pointer to constant FrameMap.
|
||||
void *Roots[0]; //< Stack roots (in-place array).
|
||||
};
|
||||
|
||||
/// @brief The head of the singly-linked list of StackEntries. Functions push
|
||||
/// and pop onto this in their prologue and epilogue.
|
||||
///
|
||||
/// Since there is only a global list, this technique is not threadsafe.
|
||||
StackEntry *llvm_gc_root_chain;
|
||||
|
||||
/// @brief Calls Visitor(root, meta) for each GC root on the stack.
|
||||
/// root and meta are exactly the values passed to
|
||||
/// @llvm.gcroot.
|
||||
///
|
||||
/// Visitor could be a function to recursively mark live objects. Or it
|
||||
/// might copy them to another heap or generation.
|
||||
///
|
||||
/// @param Visitor A function to invoke for every GC root on the stack.
|
||||
void visitGCRoots(void (*Visitor)(void **Root, const void *Meta)) {
|
||||
for (StackEntry *R = llvm_gc_root_chain; R; R = R->Next) {
|
||||
unsigned i = 0;
|
||||
|
||||
// For roots [0, NumMeta), the metadata pointer is in the FrameMap.
|
||||
for (unsigned e = R->Map->NumMeta; i != e; ++i)
|
||||
Visitor(&R->Roots[i], R->Map->Meta[i]);
|
||||
|
||||
// For roots [NumMeta, NumRoots), the metadata pointer is null.
|
||||
for (unsigned e = R->Map->NumRoots; i != e; ++i)
|
||||
Visitor(&R->Roots[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
The 'Erlang' and 'Ocaml' GCs
|
||||
-----------------------------
|
||||
|
||||
LLVM ships with two example collectors which leverage the ``gcroot``
|
||||
mechanisms. To our knowledge, these are not actually used by any language
|
||||
runtime, but they do provide a reasonable starting point for someone interested
|
||||
in writing an ``gcroot`` compatible GC plugin. In particular, these are the
|
||||
only in tree examples of how to produce a custom binary stack map format using
|
||||
a ``gcroot`` strategy.
|
||||
|
||||
As there names imply, the binary format produced is intended to model that
|
||||
used by the Erlang and OCaml compilers respectively.
|
||||
|
||||
.. _statepoint_example_gc:
|
||||
|
||||
The Statepoint Example GC
|
||||
-------------------------
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
F.setGC("statepoint-example");
|
||||
|
||||
This GC provides an example of how one might use the infrastructure provided
|
||||
by ``gc.statepoint``. This example GC is compatible with the
|
||||
:ref:`PlaceSafepoints` and :ref:`RewriteStatepointsForGC` utility passes
|
||||
which simplify ``gc.statepoint`` sequence insertion. If you need to build a
|
||||
custom GC strategy around the ``gc.statepoints`` mechanisms, it is recommended
|
||||
that you use this one as a starting point.
|
||||
|
||||
This GC strategy does not support read or write barriers. As a result, these
|
||||
intrinsics are lowered to normal loads and stores.
|
||||
|
||||
The stack map format generated by this GC strategy can be found in the
|
||||
:ref:`stackmap-section` using a format documented :ref:`here
|
||||
<statepoint-stackmap-format>`. This format is intended to be the standard
|
||||
format supported by LLVM going forward.
|
||||
|
||||
The CoreCLR GC
|
||||
-------------------------
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
F.setGC("coreclr");
|
||||
|
||||
This GC leverages the ``gc.statepoint`` mechanism to support the
|
||||
`CoreCLR <https://github.com/dotnet/coreclr>`__ runtime.
|
||||
|
||||
Support for this GC strategy is a work in progress. This strategy will
|
||||
differ from
|
||||
:ref:`statepoint-example GC<statepoint_example_gc>` strategy in
|
||||
certain aspects like:
|
||||
|
||||
* Base-pointers of interior pointers are not explicitly
|
||||
tracked and reported.
|
||||
|
||||
* A different format is used for encoding stack maps.
|
||||
|
||||
* Safe-point polls are only needed before loop-back edges
|
||||
and before tail-calls (not needed at function-entry).
|
||||
|
||||
Custom GC Strategies
|
||||
====================
|
||||
|
||||
If none of the built in GC strategy descriptions met your needs above, you will
|
||||
need to define a custom GCStrategy and possibly, a custom LLVM pass to perform
|
||||
lowering. Your best example of where to start defining a custom GCStrategy
|
||||
would be to look at one of the built in strategies.
|
||||
|
||||
You may be able to structure this additional code as a loadable plugin library.
|
||||
Loadable plugins are sufficient if all you need is to enable a different
|
||||
combination of built in functionality, but if you need to provide a custom
|
||||
lowering pass, you will need to build a patched version of LLVM. If you think
|
||||
you need a patched build, please ask for advice on llvm-dev. There may be an
|
||||
easy way we can extend the support to make it work for your use case without
|
||||
requiring a custom build.
|
||||
|
||||
Collector Requirements
|
||||
----------------------
|
||||
|
||||
You should be able to leverage any existing collector library that includes the following elements:
|
||||
|
||||
#. A memory allocator which exposes an allocation function your compiled
|
||||
code can call.
|
||||
|
||||
#. A binary format for the stack map. A stack map describes the location
|
||||
of references at a safepoint and is used by precise collectors to identify
|
||||
references within a stack frame on the machine stack. Note that collectors
|
||||
which conservatively scan the stack don't require such a structure.
|
||||
|
||||
#. A stack crawler to discover functions on the call stack, and enumerate the
|
||||
references listed in the stack map for each call site.
|
||||
|
||||
#. A mechanism for identifying references in global locations (e.g. global
|
||||
variables).
|
||||
|
||||
#. If you collector requires them, an LLVM IR implementation of your collectors
|
||||
load and store barriers. Note that since many collectors don't require
|
||||
barriers at all, LLVM defaults to lowering such barriers to normal loads
|
||||
and stores unless you arrange otherwise.
|
||||
|
||||
|
||||
Implementing a collector plugin
|
||||
===============================
|
||||
-------------------------------
|
||||
|
||||
User code specifies which GC code generation to use with the ``gc`` function
|
||||
attribute or, equivalently, with the ``setGC`` method of ``Function``.
|
||||
@ -721,8 +856,9 @@ this feature should be used by all GC plugins. It is enabled by default.
|
||||
Custom lowering of intrinsics: ``CustomRoots``, ``CustomReadBarriers``, and ``CustomWriteBarriers``
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
For GCs which use barriers or unusual treatment of stack roots, these flags
|
||||
allow the collector to perform arbitrary transformations of the LLVM IR:
|
||||
For GCs which use barriers or unusual treatment of stack roots, these
|
||||
flags allow the collector to perform arbitrary transformations of the
|
||||
LLVM IR:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@ -733,70 +869,18 @@ allow the collector to perform arbitrary transformations of the LLVM IR:
|
||||
CustomReadBarriers = true;
|
||||
CustomWriteBarriers = true;
|
||||
}
|
||||
|
||||
virtual bool initializeCustomLowering(Module &M);
|
||||
virtual bool performCustomLowering(Function &F);
|
||||
};
|
||||
|
||||
If any of these flags are set, then LLVM suppresses its default lowering for the
|
||||
corresponding intrinsics and instead calls ``performCustomLowering``.
|
||||
If any of these flags are set, LLVM suppresses its default lowering for
|
||||
the corresponding intrinsics. Instead, you must provide a custom Pass
|
||||
which lowers the intrinsics as desired. If you have opted in to custom
|
||||
lowering of a particular intrinsic your pass **must** eliminate all
|
||||
instances of the corresponding intrinsic in functions which opt in to
|
||||
your GC. The best example of such a pass is the ShadowStackGC and it's
|
||||
ShadowStackGCLowering pass.
|
||||
|
||||
LLVM's default action for each intrinsic is as follows:
|
||||
|
||||
* ``llvm.gcroot``: Leave it alone. The code generator must see it or the stack
|
||||
map will not be computed.
|
||||
|
||||
* ``llvm.gcread``: Substitute a ``load`` instruction.
|
||||
|
||||
* ``llvm.gcwrite``: Substitute a ``store`` instruction.
|
||||
|
||||
If ``CustomReadBarriers`` or ``CustomWriteBarriers`` are specified, then
|
||||
``performCustomLowering`` **must** eliminate the corresponding barriers.
|
||||
|
||||
``performCustomLowering`` must comply with the same restrictions as
|
||||
:ref:`FunctionPass::runOnFunction <writing-an-llvm-pass-runOnFunction>`
|
||||
Likewise, ``initializeCustomLowering`` has the same semantics as
|
||||
:ref:`Pass::doInitialization(Module&)
|
||||
<writing-an-llvm-pass-doInitialization-mod>`
|
||||
|
||||
The following can be used as a template:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
|
||||
bool MyGC::initializeCustomLowering(Module &M) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MyGC::performCustomLowering(Function &F) {
|
||||
bool MadeChange = false;
|
||||
|
||||
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
||||
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; )
|
||||
if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++))
|
||||
if (Function *F = CI->getCalledFunction())
|
||||
switch (F->getIntrinsicID()) {
|
||||
case Intrinsic::gcwrite:
|
||||
// Handle llvm.gcwrite.
|
||||
CI->eraseFromParent();
|
||||
MadeChange = true;
|
||||
break;
|
||||
case Intrinsic::gcread:
|
||||
// Handle llvm.gcread.
|
||||
CI->eraseFromParent();
|
||||
MadeChange = true;
|
||||
break;
|
||||
case Intrinsic::gcroot:
|
||||
// Handle llvm.gcroot.
|
||||
CI->eraseFromParent();
|
||||
MadeChange = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return MadeChange;
|
||||
}
|
||||
There is currently no way to register such a custom lowering pass
|
||||
without building a custom copy of LLVM.
|
||||
|
||||
.. _safe-points:
|
||||
|
||||
|
@ -89,12 +89,12 @@ looks like:
|
||||
|
||||
void %munge(%struct.munger_struct* %P) {
|
||||
entry:
|
||||
%tmp = getelementptr %struct.munger_struct* %P, i32 1, i32 0
|
||||
%tmp = getelementptr %struct.munger_struct, %struct.munger_struct* %P, i32 1, i32 0
|
||||
%tmp = load i32* %tmp
|
||||
%tmp6 = getelementptr %struct.munger_struct* %P, i32 2, i32 1
|
||||
%tmp6 = getelementptr %struct.munger_struct, %struct.munger_struct* %P, i32 2, i32 1
|
||||
%tmp7 = load i32* %tmp6
|
||||
%tmp8 = add i32 %tmp7, %tmp
|
||||
%tmp9 = getelementptr %struct.munger_struct* %P, i32 0, i32 0
|
||||
%tmp9 = getelementptr %struct.munger_struct, %struct.munger_struct* %P, i32 0, i32 0
|
||||
store i32 %tmp8, i32* %tmp9
|
||||
ret void
|
||||
}
|
||||
@ -109,9 +109,9 @@ To make this clear, let's consider a more obtuse example:
|
||||
|
||||
%MyVar = uninitialized global i32
|
||||
...
|
||||
%idx1 = getelementptr i32* %MyVar, i64 0
|
||||
%idx2 = getelementptr i32* %MyVar, i64 1
|
||||
%idx3 = getelementptr i32* %MyVar, i64 2
|
||||
%idx1 = getelementptr i32, i32* %MyVar, i64 0
|
||||
%idx2 = getelementptr i32, i32* %MyVar, i64 1
|
||||
%idx3 = getelementptr i32, i32* %MyVar, i64 2
|
||||
|
||||
These GEP instructions are simply making address computations from the base
|
||||
address of ``MyVar``. They compute, as follows (using C syntax):
|
||||
@ -146,7 +146,7 @@ variable which is always a pointer type. For example, consider this:
|
||||
|
||||
%MyStruct = uninitialized global { float*, i32 }
|
||||
...
|
||||
%idx = getelementptr { float*, i32 }* %MyStruct, i64 0, i32 1
|
||||
%idx = getelementptr { float*, i32 }, { float*, i32 }* %MyStruct, i64 0, i32 1
|
||||
|
||||
The GEP above yields an ``i32*`` by indexing the ``i32`` typed field of the
|
||||
structure ``%MyStruct``. When people first look at it, they wonder why the ``i64
|
||||
@ -182,7 +182,7 @@ only involved in the computation of addresses. For example, consider this:
|
||||
|
||||
%MyVar = uninitialized global { [40 x i32 ]* }
|
||||
...
|
||||
%idx = getelementptr { [40 x i32]* }* %MyVar, i64 0, i32 0, i64 0, i64 17
|
||||
%idx = getelementptr { [40 x i32]* }, { [40 x i32]* }* %MyVar, i64 0, i32 0, i64 0, i64 17
|
||||
|
||||
In this example, we have a global variable, ``%MyVar`` that is a pointer to a
|
||||
structure containing a pointer to an array of 40 ints. The GEP instruction seems
|
||||
@ -197,9 +197,9 @@ following:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
%idx = getelementptr { [40 x i32]* }* %, i64 0, i32 0
|
||||
%idx = getelementptr { [40 x i32]* }, { [40 x i32]* }* %, i64 0, i32 0
|
||||
%arr = load [40 x i32]** %idx
|
||||
%idx = getelementptr [40 x i32]* %arr, i64 0, i64 17
|
||||
%idx = getelementptr [40 x i32], [40 x i32]* %arr, i64 0, i64 17
|
||||
|
||||
In this case, we have to load the pointer in the structure with a load
|
||||
instruction before we can index into the array. If the example was changed to:
|
||||
@ -208,7 +208,7 @@ instruction before we can index into the array. If the example was changed to:
|
||||
|
||||
%MyVar = uninitialized global { [40 x i32 ] }
|
||||
...
|
||||
%idx = getelementptr { [40 x i32] }*, i64 0, i32 0, i64 17
|
||||
%idx = getelementptr { [40 x i32] }, { [40 x i32] }*, i64 0, i32 0, i64 17
|
||||
|
||||
then everything works fine. In this case, the structure does not contain a
|
||||
pointer and the GEP instruction can index through the global variable, into the
|
||||
@ -225,9 +225,9 @@ index. Consider this example:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
%MyVar = global { [10 x i32 ] }
|
||||
%idx1 = getelementptr { [10 x i32 ] }* %MyVar, i64 0, i32 0, i64 1
|
||||
%idx2 = getelementptr { [10 x i32 ] }* %MyVar, i64 1
|
||||
%MyVar = global { [10 x i32] }
|
||||
%idx1 = getelementptr { [10 x i32] }, { [10 x i32] }* %MyVar, i64 0, i32 0, i64 1
|
||||
%idx2 = getelementptr { [10 x i32] }, { [10 x i32] }* %MyVar, i64 1
|
||||
|
||||
In this example, ``idx1`` computes the address of the second integer in the
|
||||
array that is in the structure in ``%MyVar``, that is ``MyVar+4``. The type of
|
||||
@ -248,9 +248,9 @@ type. Consider this example:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
%MyVar = global { [10 x i32 ] }
|
||||
%idx1 = getelementptr { [10 x i32 ] }* %MyVar, i64 1, i32 0, i64 0
|
||||
%idx2 = getelementptr { [10 x i32 ] }* %MyVar, i64 1
|
||||
%MyVar = global { [10 x i32] }
|
||||
%idx1 = getelementptr { [10 x i32] }, { [10 x i32] }* %MyVar, i64 1, i32 0, i64 0
|
||||
%idx2 = getelementptr { [10 x i32] }, { [10 x i32] }* %MyVar, i64 1
|
||||
|
||||
In this example, the value of ``%idx1`` is ``%MyVar+40`` and its type is
|
||||
``i32*``. The value of ``%idx2`` is also ``MyVar+40`` but its type is ``{ [10 x
|
||||
|
@ -62,38 +62,50 @@ Here's the short story for getting up and running quickly with LLVM:
|
||||
* ``svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite``
|
||||
|
||||
#. Configure and build LLVM and Clang:
|
||||
|
||||
The usual build uses `CMake <CMake.html>`_. If you would rather use
|
||||
autotools, see `Building LLVM with autotools <BuildingLLVMWithAutotools.html>`_.
|
||||
|
||||
* ``cd where-you-want-to-build-llvm``
|
||||
* ``mkdir build`` (for building without polluting the source dir)
|
||||
* ``cd where you want to build llvm``
|
||||
* ``mkdir build``
|
||||
* ``cd build``
|
||||
* ``../llvm/configure [options]``
|
||||
Some common options:
|
||||
* ``cmake -G <generator> [options] <path to llvm sources>``
|
||||
|
||||
Some common generators are:
|
||||
|
||||
* ``--prefix=directory`` --- Specify for *directory* the full pathname of
|
||||
where you want the LLVM tools and libraries to be installed (default
|
||||
``/usr/local``).
|
||||
* ``Unix Makefiles`` --- for generating make-compatible parallel makefiles.
|
||||
* ``Ninja`` --- for generating `Ninja <http://martine.github.io/ninja/>`
|
||||
build files.
|
||||
* ``Visual Studio`` --- for generating Visual Studio projects and
|
||||
solutions.
|
||||
* ``Xcode`` --- for generating Xcode projects.
|
||||
|
||||
Some Common options:
|
||||
|
||||
* ``--enable-optimized`` --- Compile with optimizations enabled (default
|
||||
is NO).
|
||||
* ``-DCMAKE_INSTALL_PREFIX=directory`` --- Specify for *directory* the full
|
||||
pathname of where you want the LLVM tools and libraries to be installed
|
||||
(default ``/usr/local``).
|
||||
|
||||
* ``--enable-assertions`` --- Compile with assertion checks enabled
|
||||
(default is YES).
|
||||
* ``-DCMAKE_BUILD_TYPE=type`` --- Valid options for *type* are Debug,
|
||||
Release, RelWithDebInfo, and MinSizeRel. Default is Debug.
|
||||
|
||||
* ``make [-j]`` --- The ``-j`` specifies the number of jobs (commands) to run
|
||||
simultaneously. This builds both LLVM and Clang for Debug+Asserts mode.
|
||||
The ``--enable-optimized`` configure option is used to specify a Release
|
||||
build.
|
||||
* ``-DLLVM_ENABLE_ASSERTIONS=On`` --- Compile with assertion checks enabled
|
||||
(default is Yes for Debug builds, No for all other build types).
|
||||
|
||||
* ``make check-all`` --- This run the regression tests to ensure everything
|
||||
is in working order.
|
||||
* Run your build tool of choice!
|
||||
|
||||
* It is also possible to use `CMake <CMake.html>`_ instead of the makefiles.
|
||||
With CMake it is possible to generate project files for several IDEs:
|
||||
Xcode, Eclipse CDT4, CodeBlocks, Qt-Creator (use the CodeBlocks
|
||||
generator), KDevelop3.
|
||||
* The default target (i.e. ``make``) will build all of LLVM
|
||||
|
||||
* The ``check-all`` target (i.e. ``make check-all``) will run the
|
||||
regression tests to ensure everything is in working order.
|
||||
|
||||
* CMake will generate build targets for each tool and library, and most
|
||||
LLVM sub-projects generate their own ``check-<project>`` target.
|
||||
|
||||
* For more information see `CMake <CMake.html>`_
|
||||
|
||||
* If you get an "internal compiler error (ICE)" or test failures, see
|
||||
`below`.
|
||||
`below`_.
|
||||
|
||||
Consult the `Getting Started with LLVM`_ section for detailed information on
|
||||
configuring and compiling LLVM. See `Setting Up Your Environment`_ for tips
|
||||
@ -134,7 +146,8 @@ Windows x64 x86-64 Visual Studio
|
||||
#. Code generation supported for Pentium processors and up
|
||||
#. Code generation supported for 32-bit ABI only
|
||||
#. To use LLVM modules on Win32-based system, you may configure LLVM
|
||||
with ``--enable-shared``.
|
||||
with ``-DBUILD_SHARED_LIBS=On`` for CMake builds or ``--enable-shared``
|
||||
for configure builds.
|
||||
#. MCJIT not working well pre-v7, old JIT engine not supported any more.
|
||||
|
||||
Note that you will need about 1-3 GB of space for a full LLVM build in Debug
|
||||
@ -230,7 +243,7 @@ our build systems:
|
||||
|
||||
* Clang 3.1
|
||||
* GCC 4.7
|
||||
* Visual Studio 2012
|
||||
* Visual Studio 2013
|
||||
|
||||
Anything older than these toolchains *may* work, but will require forcing the
|
||||
build system with a special option and is not really a supported host platform.
|
||||
@ -280,7 +293,7 @@ Getting a Modern Host C++ Toolchain
|
||||
|
||||
This section mostly applies to Linux and older BSDs. On Mac OS X, you should
|
||||
have a sufficiently modern Xcode, or you will likely need to upgrade until you
|
||||
do. On Windows, just use Visual Studio 2012 as the host compiler, it is
|
||||
do. On Windows, just use Visual Studio 2013 as the host compiler, it is
|
||||
explicitly supported and widely available. FreeBSD 10.0 and newer have a modern
|
||||
Clang as the system compiler.
|
||||
|
||||
@ -435,7 +448,7 @@ follows:
|
||||
|
||||
* ``cd where-you-want-llvm-to-live``
|
||||
* Read-Only: ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm``
|
||||
* Read-Write:``svn co https://user@llvm.org/svn/llvm-project/llvm/trunk llvm``
|
||||
* Read-Write: ``svn co https://user@llvm.org/svn/llvm-project/llvm/trunk llvm``
|
||||
|
||||
This will create an '``llvm``' directory in the current directory and fully
|
||||
populate it with the LLVM source code, Makefiles, test directories, and local
|
||||
@ -664,66 +677,61 @@ Local LLVM Configuration
|
||||
------------------------
|
||||
|
||||
Once checked out from the Subversion repository, the LLVM suite source code must
|
||||
be configured via the ``configure`` script. This script sets variables in the
|
||||
various ``*.in`` files, most notably ``llvm/Makefile.config`` and
|
||||
``llvm/include/Config/config.h``. It also populates *OBJ_ROOT* with the
|
||||
Makefiles needed to begin building LLVM.
|
||||
be configured before being built. For instructions using autotools please see
|
||||
`Building LLVM With Autotools <BuildingLLVMWithAutotools.html>`_. The
|
||||
recommended process uses CMake. Unlinke the normal ``configure`` script, CMake
|
||||
generates the build files in whatever format you request as well as various
|
||||
``*.inc`` files, and ``llvm/include/Config/config.h``.
|
||||
|
||||
The following environment variables are used by the ``configure`` script to
|
||||
configure the build system:
|
||||
Variables are passed to ``cmake`` on the command line using the format
|
||||
``-D<variable name>=<value>``. The following variables are some common options
|
||||
used by people developing LLVM.
|
||||
|
||||
+------------+-----------------------------------------------------------+
|
||||
| Variable | Purpose |
|
||||
+============+===========================================================+
|
||||
| CC | Tells ``configure`` which C compiler to use. By default, |
|
||||
| | ``configure`` will check ``PATH`` for ``clang`` and GCC C |
|
||||
| | compilers (in this order). Use this variable to override |
|
||||
| | ``configure``\'s default behavior. |
|
||||
+------------+-----------------------------------------------------------+
|
||||
| CXX | Tells ``configure`` which C++ compiler to use. By |
|
||||
| | default, ``configure`` will check ``PATH`` for |
|
||||
| | ``clang++`` and GCC C++ compilers (in this order). Use |
|
||||
| | this variable to override ``configure``'s default |
|
||||
| | behavior. |
|
||||
+------------+-----------------------------------------------------------+
|
||||
|
||||
The following options can be used to set or enable LLVM specific options:
|
||||
|
||||
``--enable-optimized``
|
||||
|
||||
Enables optimized compilation (debugging symbols are removed and GCC
|
||||
optimization flags are enabled). Note that this is the default setting if you
|
||||
are using the LLVM distribution. The default behavior of a Subversion
|
||||
checkout is to use an unoptimized build (also known as a debug build).
|
||||
|
||||
``--enable-debug-runtime``
|
||||
|
||||
Enables debug symbols in the runtime libraries. The default is to strip debug
|
||||
symbols from the runtime libraries.
|
||||
|
||||
``--enable-jit``
|
||||
|
||||
Compile the Just In Time (JIT) compiler functionality. This is not available
|
||||
on all platforms. The default is dependent on platform, so it is best to
|
||||
explicitly enable it if you want it.
|
||||
|
||||
``--enable-targets=target-option``
|
||||
|
||||
Controls which targets will be built and linked into llc. The default value
|
||||
for ``target_options`` is "all" which builds and links all available targets.
|
||||
The "host" target is selected as the target of the build host. You can also
|
||||
specify a comma separated list of target names that you want available in llc.
|
||||
The target names use all lower case. The current set of targets is:
|
||||
|
||||
``aarch64, arm, arm64, cpp, hexagon, mips, mipsel, mips64, mips64el, msp430,
|
||||
powerpc, nvptx, r600, sparc, systemz, x86, x86_64, xcore``.
|
||||
|
||||
``--enable-doxygen``
|
||||
|
||||
Look for the doxygen program and enable construction of doxygen based
|
||||
documentation from the source code. This is disabled by default because
|
||||
generating the documentation can take a long time and producess 100s of
|
||||
megabytes of output.
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| Variable | Purpose |
|
||||
+=========================+====================================================+
|
||||
| CMAKE_C_COMPILER | Tells ``cmake`` which C compiler to use. By |
|
||||
| | default, this will be /usr/bin/cc. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| CMAKE_CXX_COMPILER | Tells ``cmake`` which C++ compiler to use. By |
|
||||
| | default, this will be /usr/bin/c++. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| CMAKE_BUILD_TYPE | Tells ``cmake`` what type of build you are trying |
|
||||
| | to generate files for. Valid options are Debug, |
|
||||
| | Release, RelWithDebInfo, and MinSizeRel. Default |
|
||||
| | is Debug. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| CMAKE_INSTALL_PREFIX | Specifies the install directory to target when |
|
||||
| | running the install action of the build files. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| LLVM_TARGETS_TO_BUILD | A semicolon delimited list controlling which |
|
||||
| | targets will be built and linked into llc. This is |
|
||||
| | equivalent to the ``--enable-targets`` option in |
|
||||
| | the configure script. The default list is defined |
|
||||
| | as ``LLVM_ALL_TARGETS``, and can be set to include |
|
||||
| | out-of-tree targets. The default value includes: |
|
||||
| | ``AArch64, ARM, CppBackend, Hexagon, |
|
||||
| | Mips, MSP430, NVPTX, PowerPC, R600, Sparc, |
|
||||
| | SystemZ, X86, XCore``. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| LLVM_ENABLE_DOXYGEN | Build doxygen-based documentation from the source |
|
||||
| | code This is disabled by default because it is |
|
||||
| | slow and generates a lot of output. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| LLVM_ENABLE_SPHINX | Build sphinx-based documentation from the source |
|
||||
| | code. This is disabled by default because it is |
|
||||
| | slow and generates a lot of output. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| LLVM_BUILD_LLVM_DYLIB | Generate libLLVM.so. This library contains a |
|
||||
| | default set of LLVM components that can be |
|
||||
| | overridden with ``LLVM_DYLIB_COMPONENTS``. The |
|
||||
| | default contains most of LLVM and is defined in |
|
||||
| | ``tools/llvm-shlib/CMakelists.txt``. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
| LLVM_OPTIMIZED_TABLEGEN | Builds a release tablegen that gets used during |
|
||||
| | the LLVM build. This can dramatically speed up |
|
||||
| | debug builds. |
|
||||
+-------------------------+----------------------------------------------------+
|
||||
|
||||
To configure LLVM, follow these steps:
|
||||
|
||||
@ -733,47 +741,52 @@ To configure LLVM, follow these steps:
|
||||
|
||||
% cd OBJ_ROOT
|
||||
|
||||
#. Run the ``configure`` script located in the LLVM source tree:
|
||||
#. Run the ``cmake``:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% SRC_ROOT/configure --prefix=/install/path [other options]
|
||||
% cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=prefix=/install/path
|
||||
[other options] SRC_ROOT
|
||||
|
||||
Compiling the LLVM Suite Source Code
|
||||
------------------------------------
|
||||
|
||||
Once you have configured LLVM, you can build it. There are three types of
|
||||
builds:
|
||||
Unlike with autotools, with CMake your build type is defined at configuration.
|
||||
If you want to change your build type, you can re-run cmake with the following
|
||||
invocation:
|
||||
|
||||
Debug Builds
|
||||
.. code-block:: console
|
||||
|
||||
These builds are the default when one is using a Subversion checkout and
|
||||
types ``gmake`` (unless the ``--enable-optimized`` option was used during
|
||||
configuration). The build system will compile the tools and libraries with
|
||||
debugging information. To get a Debug Build using the LLVM distribution the
|
||||
``--disable-optimized`` option must be passed to ``configure``.
|
||||
% cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=type SRC_ROOT
|
||||
|
||||
Release (Optimized) Builds
|
||||
Between runs, CMake preserves the values set for all options. CMake has the
|
||||
following build types defined:
|
||||
|
||||
These builds are enabled with the ``--enable-optimized`` option to
|
||||
``configure`` or by specifying ``ENABLE_OPTIMIZED=1`` on the ``gmake`` command
|
||||
line. For these builds, the build system will compile the tools and libraries
|
||||
with GCC optimizations enabled and strip debugging information from the
|
||||
libraries and executables it generates. Note that Release Builds are default
|
||||
when using an LLVM distribution.
|
||||
Debug
|
||||
|
||||
Profile Builds
|
||||
These builds are the default. The build system will compile the tools and
|
||||
libraries unoptimized, with debugging information, and asserts enabled.
|
||||
|
||||
These builds are for use with profiling. They compile profiling information
|
||||
into the code for use with programs like ``gprof``. Profile builds must be
|
||||
started by specifying ``ENABLE_PROFILING=1`` on the ``gmake`` command line.
|
||||
Release
|
||||
|
||||
For these builds, the build system will compile the tools and libraries
|
||||
with optimizations enabled and not generate debug info. CMakes default
|
||||
optimization level is -O3. This can be configured by setting the
|
||||
``CMAKE_CXX_FLAGS_RELEASE`` variable on the CMake command line.
|
||||
|
||||
RelWithDebInfo
|
||||
|
||||
These builds are useful when debugging. They generate optimized binaries with
|
||||
debug information. CMakes default optimization level is -O2. This can be
|
||||
configured by setting the ``CMAKE_CXX_FLAGS_RELWITHDEBINFO`` variable on the
|
||||
CMake command line.
|
||||
|
||||
Once you have LLVM configured, you can build it by entering the *OBJ_ROOT*
|
||||
directory and issuing the following command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% gmake
|
||||
% make
|
||||
|
||||
If the build fails, please `check here`_ to see if you are using a version of
|
||||
GCC that is known not to compile LLVM.
|
||||
@ -784,110 +797,51 @@ command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% gmake -j2
|
||||
% make -j2
|
||||
|
||||
There are several special targets which are useful when working with the LLVM
|
||||
source code:
|
||||
|
||||
``gmake clean``
|
||||
``make clean``
|
||||
|
||||
Removes all files generated by the build. This includes object files,
|
||||
generated C/C++ files, libraries, and executables.
|
||||
|
||||
``gmake dist-clean``
|
||||
|
||||
Removes everything that ``gmake clean`` does, but also removes files generated
|
||||
by ``configure``. It attempts to return the source tree to the original state
|
||||
in which it was shipped.
|
||||
|
||||
``gmake install``
|
||||
``make install``
|
||||
|
||||
Installs LLVM header files, libraries, tools, and documentation in a hierarchy
|
||||
under ``$PREFIX``, specified with ``./configure --prefix=[dir]``, which
|
||||
under ``$PREFIX``, specified with ``CMAKE_INSTALL_PREFIX``, which
|
||||
defaults to ``/usr/local``.
|
||||
|
||||
``gmake -C runtime install-bytecode``
|
||||
``make docs-llvm-html``
|
||||
|
||||
Assuming you built LLVM into $OBJDIR, when this command is run, it will
|
||||
install bitcode libraries into the GCC front end's bitcode library directory.
|
||||
If you need to update your bitcode libraries, this is the target to use once
|
||||
you've built them.
|
||||
|
||||
Please see the `Makefile Guide <MakefileGuide.html>`_ for further details on
|
||||
these ``make`` targets and descriptions of other targets available.
|
||||
|
||||
It is also possible to override default values from ``configure`` by declaring
|
||||
variables on the command line. The following are some examples:
|
||||
|
||||
``gmake ENABLE_OPTIMIZED=1``
|
||||
|
||||
Perform a Release (Optimized) build.
|
||||
|
||||
``gmake ENABLE_OPTIMIZED=1 DISABLE_ASSERTIONS=1``
|
||||
|
||||
Perform a Release (Optimized) build without assertions enabled.
|
||||
|
||||
``gmake ENABLE_OPTIMIZED=0``
|
||||
|
||||
Perform a Debug build.
|
||||
|
||||
``gmake ENABLE_PROFILING=1``
|
||||
|
||||
Perform a Profiling build.
|
||||
|
||||
``gmake VERBOSE=1``
|
||||
|
||||
Print what ``gmake`` is doing on standard output.
|
||||
|
||||
``gmake TOOL_VERBOSE=1``
|
||||
|
||||
Ask each tool invoked by the makefiles to print out what it is doing on
|
||||
the standard output. This also implies ``VERBOSE=1``.
|
||||
|
||||
Every directory in the LLVM object tree includes a ``Makefile`` to build it and
|
||||
any subdirectories that it contains. Entering any directory inside the LLVM
|
||||
object tree and typing ``gmake`` should rebuild anything in or below that
|
||||
directory that is out of date.
|
||||
|
||||
This does not apply to building the documentation.
|
||||
LLVM's (non-Doxygen) documentation is produced with the
|
||||
`Sphinx <http://sphinx-doc.org/>`_ documentation generation system.
|
||||
There are some HTML documents that have not yet been converted to the new
|
||||
system (which uses the easy-to-read and easy-to-write
|
||||
`reStructuredText <http://sphinx-doc.org/rest.html>`_ plaintext markup
|
||||
language).
|
||||
The generated documentation is built in the ``SRC_ROOT/docs`` directory using
|
||||
a special makefile.
|
||||
For instructions on how to install Sphinx, see
|
||||
`Sphinx Introduction for LLVM Developers
|
||||
<http://lld.llvm.org/sphinx_intro.html>`_.
|
||||
After following the instructions there for installing Sphinx, build the LLVM
|
||||
HTML documentation by doing the following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd SRC_ROOT/docs
|
||||
$ make -f Makefile.sphinx
|
||||
|
||||
This creates a ``_build/html`` sub-directory with all of the HTML files, not
|
||||
just the generated ones.
|
||||
This directory corresponds to ``llvm.org/docs``.
|
||||
For example, ``_build/html/SphinxQuickstartTemplate.html`` corresponds to
|
||||
``llvm.org/docs/SphinxQuickstartTemplate.html``.
|
||||
The :doc:`SphinxQuickstartTemplate` is useful when creating a new document.
|
||||
If configured with ``-DLLVM_ENABLE_SPHINX=On``, this will generate a directory
|
||||
at ``OBJ_ROOT/docs/html`` which contains the HTML formatted documentation.
|
||||
|
||||
Cross-Compiling LLVM
|
||||
--------------------
|
||||
|
||||
It is possible to cross-compile LLVM itself. That is, you can create LLVM
|
||||
executables and libraries to be hosted on a platform different from the platform
|
||||
where they are built (a Canadian Cross build). To configure a cross-compile,
|
||||
supply the configure script with ``--build`` and ``--host`` options that are
|
||||
different. The values of these options must be legal target triples that your
|
||||
GCC compiler supports.
|
||||
where they are built (a Canadian Cross build). To generate build files for
|
||||
cross-compiling CMake provides a variable ``CMAKE_TOOLCHAIN_FILE`` which can
|
||||
define compiler flags and variables used during the CMake test operations.
|
||||
|
||||
The result of such a build is executables that are not runnable on on the build
|
||||
host (--build option) but can be executed on the compile host (--host option).
|
||||
host but can be executed on the target. As an example the following CMake
|
||||
invocation can generate build files targeting iOS. This will work on Mac OS X
|
||||
with the latest Xcode:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% cmake -G "Ninja" -DCMAKE_OSX_ARCHITECTURES=“armv7;armv7s;arm64"
|
||||
-DCMAKE_TOOLCHAIN_FILE=<PATH_TO_LLVM>/cmake/platforms/iOS.cmake
|
||||
-DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_RUNTIME=Off -DLLVM_INCLUDE_TESTS=Off
|
||||
-DLLVM_INCLUDE_EXAMPLES=Off -DLLVM_ENABLE_BACKTRACES=Off [options]
|
||||
<PATH_TO_LLVM>
|
||||
|
||||
Note: There are some additional flags that need to be passed when building for
|
||||
iOS due to limitations in the iOS SDK.
|
||||
|
||||
Check :doc:`HowToCrossCompileLLVM` and `Clang docs on how to cross-compile in general
|
||||
<http://clang.llvm.org/docs/CrossCompilation.html>`_ for more information
|
||||
@ -908,44 +862,25 @@ This is accomplished in the typical autoconf manner:
|
||||
|
||||
% cd OBJ_ROOT
|
||||
|
||||
* Run the ``configure`` script found in the LLVM source directory:
|
||||
* Run ``cmake``:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% SRC_ROOT/configure
|
||||
% cmake -G "Unix Makefiles" SRC_ROOT
|
||||
|
||||
The LLVM build will place files underneath *OBJ_ROOT* in directories named after
|
||||
the build type:
|
||||
The LLVM build will create a structure underneath *OBJ_ROOT* that matches the
|
||||
LLVM source tree. At each level where source files are present in the source
|
||||
tree there will be a corresponding ``CMakeFiles`` directory in the *OBJ_ROOT*.
|
||||
Underneath that directory there is another directory with a name ending in
|
||||
``.dir`` under which you'll find object files for each source.
|
||||
|
||||
Debug Builds with assertions enabled (the default)
|
||||
For example:
|
||||
|
||||
Tools
|
||||
|
||||
``OBJ_ROOT/Debug+Asserts/bin``
|
||||
|
||||
Libraries
|
||||
|
||||
``OBJ_ROOT/Debug+Asserts/lib``
|
||||
|
||||
Release Builds
|
||||
|
||||
Tools
|
||||
|
||||
``OBJ_ROOT/Release/bin``
|
||||
|
||||
Libraries
|
||||
|
||||
``OBJ_ROOT/Release/lib``
|
||||
|
||||
Profile Builds
|
||||
|
||||
Tools
|
||||
|
||||
``OBJ_ROOT/Profile/bin``
|
||||
|
||||
Libraries
|
||||
|
||||
``OBJ_ROOT/Profile/lib``
|
||||
.. code-block:: console
|
||||
|
||||
% cd llvm_build_dir
|
||||
% find lib/Support/ -name APFloat*
|
||||
lib/Support/CMakeFiles/LLVMSupport.dir/APFloat.cpp.o
|
||||
|
||||
Optional Configuration Items
|
||||
----------------------------
|
||||
|
@ -45,13 +45,13 @@ and software you will need.
|
||||
|
||||
Hardware
|
||||
--------
|
||||
Any system that can adequately run Visual Studio 2012 is fine. The LLVM
|
||||
Any system that can adequately run Visual Studio 2013 is fine. The LLVM
|
||||
source tree and object files, libraries and executables will consume
|
||||
approximately 3GB.
|
||||
|
||||
Software
|
||||
--------
|
||||
You will need Visual Studio 2012 or higher.
|
||||
You will need Visual Studio 2013 or higher.
|
||||
|
||||
You will also need the `CMake <http://www.cmake.org/>`_ build system since it
|
||||
generates the project files you will use to build with.
|
||||
|
@ -40,7 +40,7 @@ on the ARMv6 and ARMv7 architectures and may be inapplicable to older chips.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./configure --build=armv7l-unknown-linux-gnueabihf \
|
||||
../$LLVM_SRC_DIR/configure --build=armv7l-unknown-linux-gnueabihf \
|
||||
--host=armv7l-unknown-linux-gnueabihf \
|
||||
--target=armv7l-unknown-linux-gnueabihf --with-cpu=cortex-a9 \
|
||||
--with-float=hard --with-abi=aapcs-vfp --with-fpu=neon \
|
||||
|
@ -40,14 +40,14 @@ RTTI for this class hierarchy:
|
||||
double SideLength;
|
||||
public:
|
||||
Square(double S) : SideLength(S) {}
|
||||
double computeArea() /* override */;
|
||||
double computeArea() override;
|
||||
};
|
||||
|
||||
class Circle : public Shape {
|
||||
double Radius;
|
||||
public:
|
||||
Circle(double R) : Radius(R) {}
|
||||
double computeArea() /* override */;
|
||||
double computeArea() override;
|
||||
};
|
||||
|
||||
The most basic working setup for LLVM-style RTTI requires the following
|
||||
@ -135,7 +135,7 @@ steps:
|
||||
public:
|
||||
- Square(double S) : SideLength(S) {}
|
||||
+ Square(double S) : Shape(SK_Square), SideLength(S) {}
|
||||
double computeArea() /* override */;
|
||||
double computeArea() override;
|
||||
};
|
||||
|
||||
class Circle : public Shape {
|
||||
@ -143,7 +143,7 @@ steps:
|
||||
public:
|
||||
- Circle(double R) : Radius(R) {}
|
||||
+ Circle(double R) : Shape(SK_Circle), Radius(R) {}
|
||||
double computeArea() /* override */;
|
||||
double computeArea() override;
|
||||
};
|
||||
|
||||
#. Finally, you need to inform LLVM's RTTI templates how to dynamically
|
||||
@ -175,7 +175,7 @@ steps:
|
||||
double SideLength;
|
||||
public:
|
||||
Square(double S) : Shape(SK_Square), SideLength(S) {}
|
||||
double computeArea() /* override */;
|
||||
double computeArea() override;
|
||||
+
|
||||
+ static bool classof(const Shape *S) {
|
||||
+ return S->getKind() == SK_Square;
|
||||
@ -186,7 +186,7 @@ steps:
|
||||
double Radius;
|
||||
public:
|
||||
Circle(double R) : Shape(SK_Circle), Radius(R) {}
|
||||
double computeArea() /* override */;
|
||||
double computeArea() override;
|
||||
+
|
||||
+ static bool classof(const Shape *S) {
|
||||
+ return S->getKind() == SK_Circle;
|
||||
@ -377,6 +377,20 @@ contract for ``classof`` is "return ``true`` if the dynamic type of the
|
||||
argument is-a ``C``". As long as your implementation fulfills this
|
||||
contract, you can tweak and optimize it as much as you want.
|
||||
|
||||
For example, LLVM-style RTTI can work fine in the presence of
|
||||
multiple-inheritance by defining an appropriate ``classof``.
|
||||
An example of this in practice is
|
||||
`Decl <http://clang.llvm.org/doxygen/classclang_1_1Decl.html>`_ vs.
|
||||
`DeclContext <http://clang.llvm.org/doxygen/classclang_1_1DeclContext.html>`_
|
||||
inside Clang.
|
||||
The ``Decl`` hierarchy is done very similarly to the example setup
|
||||
demonstrated in this tutorial.
|
||||
The key part is how to then incorporate ``DeclContext``: all that is needed
|
||||
is in ``bool DeclContext::classof(const Decl *)``, which asks the question
|
||||
"Given a ``Decl``, how can I determine if it is-a ``DeclContext``?".
|
||||
It answers this with a simple switch over the set of ``Decl`` "kinds", and
|
||||
returning true for ones that are known to be ``DeclContext``'s.
|
||||
|
||||
.. TODO::
|
||||
|
||||
Touch on some of the more advanced features, like ``isa_impl`` and
|
||||
|
853
docs/LangRef.rst
853
docs/LangRef.rst
File diff suppressed because it is too large
Load Diff
@ -46,6 +46,15 @@ B
|
||||
C
|
||||
-
|
||||
|
||||
**CFI**
|
||||
Call Frame Information. Used in DWARF debug info and in C++ unwind info
|
||||
to show how the function prolog lays out the stack frame.
|
||||
|
||||
**CIE**
|
||||
Common Information Entry. A kind of CFI used to reduce the size of FDEs.
|
||||
The compiler creates a CIE which contains the information common across all
|
||||
the FDEs. Each FDE then points to its CIE.
|
||||
|
||||
**CSE**
|
||||
Common Subexpression Elimination. An optimization that removes common
|
||||
subexpression compuation. For example ``(a+b)*(a+b)`` has two subexpressions
|
||||
@ -82,6 +91,10 @@ F
|
||||
**FCA**
|
||||
First Class Aggregate
|
||||
|
||||
**FDE**
|
||||
Frame Description Entry. A kind of CFI used to describe the stack frame of
|
||||
one function.
|
||||
|
||||
G
|
||||
-
|
||||
|
||||
@ -121,6 +134,14 @@ L
|
||||
**LICM**
|
||||
Loop Invariant Code Motion
|
||||
|
||||
**LSDA**
|
||||
Language Specific Data Area. C++ "zero cost" unwinding is built on top a
|
||||
generic unwinding mechanism. As the unwinder walks each frame, it calls
|
||||
a "personality" function to do language specific analysis. Each function's
|
||||
FDE points to an optional LSDA which is passed to the personality function.
|
||||
For C++, the LSDA contain info about the type and location of catch
|
||||
statements in that function.
|
||||
|
||||
**Load-VN**
|
||||
Load Value Numbering
|
||||
|
||||
|
418
docs/LibFuzzer.rst
Normal file
418
docs/LibFuzzer.rst
Normal file
@ -0,0 +1,418 @@
|
||||
========================================================
|
||||
LibFuzzer -- a library for coverage-guided fuzz testing.
|
||||
========================================================
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 4
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This library is intended primarily for in-process coverage-guided fuzz testing
|
||||
(fuzzing) of other libraries. The typical workflow looks like this:
|
||||
|
||||
* Build the Fuzzer library as a static archive (or just a set of .o files).
|
||||
Note that the Fuzzer contains the main() function.
|
||||
Preferably do *not* use sanitizers while building the Fuzzer.
|
||||
* Build the library you are going to test with
|
||||
`-fsanitize-coverage={bb,edge}[,indirect-calls,8bit-counters]`
|
||||
and one of the sanitizers. We recommend to build the library in several
|
||||
different modes (e.g. asan, msan, lsan, ubsan, etc) and even using different
|
||||
optimizations options (e.g. -O0, -O1, -O2) to diversify testing.
|
||||
* Build a test driver using the same options as the library.
|
||||
The test driver is a C/C++ file containing interesting calls to the library
|
||||
inside a single function ``extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);``
|
||||
* Link the Fuzzer, the library and the driver together into an executable
|
||||
using the same sanitizer options as for the library.
|
||||
* Collect the initial corpus of inputs for the
|
||||
fuzzer (a directory with test inputs, one file per input).
|
||||
The better your inputs are the faster you will find something interesting.
|
||||
Also try to keep your inputs small, otherwise the Fuzzer will run too slow.
|
||||
By default, the Fuzzer limits the size of every input to 64 bytes
|
||||
(use ``-max_len=N`` to override).
|
||||
* Run the fuzzer with the test corpus. As new interesting test cases are
|
||||
discovered they will be added to the corpus. If a bug is discovered by
|
||||
the sanitizer (asan, etc) it will be reported as usual and the reproducer
|
||||
will be written to disk.
|
||||
Each Fuzzer process is single-threaded (unless the library starts its own
|
||||
threads). You can run the Fuzzer on the same corpus in multiple processes
|
||||
in parallel.
|
||||
|
||||
|
||||
The Fuzzer is similar in concept to AFL_,
|
||||
but uses in-process Fuzzing, which is more fragile, more restrictive, but
|
||||
potentially much faster as it has no overhead for process start-up.
|
||||
It uses LLVM's SanitizerCoverage_ instrumentation to get in-process
|
||||
coverage-feedback
|
||||
|
||||
The code resides in the LLVM repository, requires the fresh Clang compiler to build
|
||||
and is used to fuzz various parts of LLVM,
|
||||
but the Fuzzer itself does not (and should not) depend on any
|
||||
part of LLVM and can be used for other projects w/o requiring the rest of LLVM.
|
||||
|
||||
Flags
|
||||
=====
|
||||
The most important flags are::
|
||||
|
||||
seed 0 Random seed. If 0, seed is generated.
|
||||
runs -1 Number of individual test runs (-1 for infinite runs).
|
||||
max_len 64 Maximum length of the test input.
|
||||
cross_over 1 If 1, cross over inputs.
|
||||
mutate_depth 5 Apply this number of consecutive mutations to each input.
|
||||
timeout 1200 Timeout in seconds (if positive). If one unit runs more than this number of seconds the process will abort.
|
||||
help 0 Print help.
|
||||
save_minimized_corpus 0 If 1, the minimized corpus is saved into the first input directory
|
||||
jobs 0 Number of jobs to run. If jobs >= 1 we spawn this number of jobs in separate worker processes with stdout/stderr redirected to fuzz-JOB.log.
|
||||
workers 0 Number of simultaneous worker processes to run the jobs. If zero, "min(jobs,NumberOfCpuCores()/2)" is used.
|
||||
tokens 0 Use the file with tokens (one token per line) to fuzz a token based input language.
|
||||
apply_tokens 0 Read the given input file, substitute bytes with tokens and write the result to stdout.
|
||||
sync_command 0 Execute an external command "<sync_command> <test_corpus>" to synchronize the test corpus.
|
||||
sync_timeout 600 Minimum timeout between syncs.
|
||||
|
||||
For the full list of flags run the fuzzer binary with ``-help=1``.
|
||||
|
||||
Usage examples
|
||||
==============
|
||||
|
||||
Toy example
|
||||
-----------
|
||||
|
||||
A simple function that does something interesting if it receives the input "HI!"::
|
||||
|
||||
cat << EOF >> test_fuzzer.cc
|
||||
extern "C" void LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) {
|
||||
if (size > 0 && data[0] == 'H')
|
||||
if (size > 1 && data[1] == 'I')
|
||||
if (size > 2 && data[2] == '!')
|
||||
__builtin_trap();
|
||||
}
|
||||
EOF
|
||||
# Get lib/Fuzzer. Assuming that you already have fresh clang in PATH.
|
||||
svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
|
||||
# Build lib/Fuzzer files.
|
||||
clang -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
|
||||
# Build test_fuzzer.cc with asan and link against lib/Fuzzer.
|
||||
clang++ -fsanitize=address -fsanitize-coverage=edge test_fuzzer.cc Fuzzer*.o
|
||||
# Run the fuzzer with no corpus.
|
||||
./a.out
|
||||
|
||||
You should get ``Illegal instruction (core dumped)`` pretty quickly.
|
||||
|
||||
PCRE2
|
||||
-----
|
||||
|
||||
Here we show how to use lib/Fuzzer on something real, yet simple: pcre2_::
|
||||
|
||||
COV_FLAGS=" -fsanitize-coverage=edge,indirect-calls,8bit-counters"
|
||||
# Get PCRE2
|
||||
svn co svn://vcs.exim.org/pcre2/code/trunk pcre
|
||||
# Get lib/Fuzzer. Assuming that you already have fresh clang in PATH.
|
||||
svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
|
||||
# Build PCRE2 with AddressSanitizer and coverage.
|
||||
(cd pcre; ./autogen.sh; CC="clang -fsanitize=address $COV_FLAGS" ./configure --prefix=`pwd`/../inst && make -j && make install)
|
||||
# Build lib/Fuzzer files.
|
||||
clang -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
|
||||
# Build the the actual function that does something interesting with PCRE2.
|
||||
cat << EOF > pcre_fuzzer.cc
|
||||
#include <string.h>
|
||||
#include "pcre2posix.h"
|
||||
extern "C" void LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) {
|
||||
if (size < 1) return;
|
||||
char *str = new char[size+1];
|
||||
memcpy(str, data, size);
|
||||
str[size] = 0;
|
||||
regex_t preg;
|
||||
if (0 == regcomp(&preg, str, 0)) {
|
||||
regexec(&preg, str, 0, 0, 0);
|
||||
regfree(&preg);
|
||||
}
|
||||
delete [] str;
|
||||
}
|
||||
EOF
|
||||
clang++ -g -fsanitize=address $COV_FLAGS -c -std=c++11 -I inst/include/ pcre_fuzzer.cc
|
||||
# Link.
|
||||
clang++ -g -fsanitize=address -Wl,--whole-archive inst/lib/*.a -Wl,-no-whole-archive Fuzzer*.o pcre_fuzzer.o -o pcre_fuzzer
|
||||
|
||||
This will give you a binary of the fuzzer, called ``pcre_fuzzer``.
|
||||
Now, create a directory that will hold the test corpus::
|
||||
|
||||
mkdir -p CORPUS
|
||||
|
||||
For simple input languages like regular expressions this is all you need.
|
||||
For more complicated inputs populate the directory with some input samples.
|
||||
Now run the fuzzer with the corpus dir as the only parameter::
|
||||
|
||||
./pcre_fuzzer ./CORPUS
|
||||
|
||||
You will see output like this::
|
||||
|
||||
Seed: 1876794929
|
||||
#0 READ cov 0 bits 0 units 1 exec/s 0
|
||||
#1 pulse cov 3 bits 0 units 1 exec/s 0
|
||||
#1 INITED cov 3 bits 0 units 1 exec/s 0
|
||||
#2 pulse cov 208 bits 0 units 1 exec/s 0
|
||||
#2 NEW cov 208 bits 0 units 2 exec/s 0 L: 64
|
||||
#3 NEW cov 217 bits 0 units 3 exec/s 0 L: 63
|
||||
#4 pulse cov 217 bits 0 units 3 exec/s 0
|
||||
|
||||
* The ``Seed:`` line shows you the current random seed (you can change it with ``-seed=N`` flag).
|
||||
* The ``READ`` line shows you how many input files were read (since you passed an empty dir there were inputs, but one dummy input was synthesised).
|
||||
* The ``INITED`` line shows you that how many inputs will be fuzzed.
|
||||
* The ``NEW`` lines appear with the fuzzer finds a new interesting input, which is saved to the CORPUS dir. If multiple corpus dirs are given, the first one is used.
|
||||
* The ``pulse`` lines appear periodically to show the current status.
|
||||
|
||||
Now, interrupt the fuzzer and run it again the same way. You will see::
|
||||
|
||||
Seed: 1879995378
|
||||
#0 READ cov 0 bits 0 units 564 exec/s 0
|
||||
#1 pulse cov 502 bits 0 units 564 exec/s 0
|
||||
...
|
||||
#512 pulse cov 2933 bits 0 units 564 exec/s 512
|
||||
#564 INITED cov 2991 bits 0 units 344 exec/s 564
|
||||
#1024 pulse cov 2991 bits 0 units 344 exec/s 1024
|
||||
#1455 NEW cov 2995 bits 0 units 345 exec/s 1455 L: 49
|
||||
|
||||
This time you were running the fuzzer with a non-empty input corpus (564 items).
|
||||
As the first step, the fuzzer minimized the set to produce 344 interesting items (the ``INITED`` line)
|
||||
|
||||
It is quite convenient to store test corpuses in git.
|
||||
As an example, here is a git repository with test inputs for the above PCRE2 fuzzer::
|
||||
|
||||
git clone https://github.com/kcc/fuzzing-with-sanitizers.git
|
||||
./pcre_fuzzer ./fuzzing-with-sanitizers/pcre2/C1/
|
||||
|
||||
You may run ``N`` independent fuzzer jobs in parallel on ``M`` CPUs::
|
||||
|
||||
N=100; M=4; ./pcre_fuzzer ./CORPUS -jobs=$N -workers=$M
|
||||
|
||||
By default (``-reload=1``) the fuzzer processes will periodically scan the CORPUS directory
|
||||
and reload any new tests. This way the test inputs found by one process will be picked up
|
||||
by all others.
|
||||
|
||||
If ``-workers=$M`` is not supplied, ``min($N,NumberOfCpuCore/2)`` will be used.
|
||||
|
||||
Heartbleed
|
||||
----------
|
||||
Remember Heartbleed_?
|
||||
As it was recently `shown <https://blog.hboeck.de/archives/868-How-Heartbleed-couldve-been-found.html>`_,
|
||||
fuzzing with AddressSanitizer can find Heartbleed. Indeed, here are the step-by-step instructions
|
||||
to find Heartbleed with LibFuzzer::
|
||||
|
||||
wget https://www.openssl.org/source/openssl-1.0.1f.tar.gz
|
||||
tar xf openssl-1.0.1f.tar.gz
|
||||
COV_FLAGS="-fsanitize-coverage=edge,indirect-calls" # -fsanitize-coverage=8bit-counters
|
||||
(cd openssl-1.0.1f/ && ./config &&
|
||||
make -j 32 CC="clang -g -fsanitize=address $COV_FLAGS")
|
||||
# Get and build LibFuzzer
|
||||
svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
|
||||
clang -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
|
||||
# Get examples of key/pem files.
|
||||
git clone https://github.com/hannob/selftls
|
||||
cp selftls/server* . -v
|
||||
cat << EOF > handshake-fuzz.cc
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <assert.h>
|
||||
SSL_CTX *sctx;
|
||||
int Init() {
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
ERR_load_BIO_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
assert (sctx = SSL_CTX_new(TLSv1_method()));
|
||||
assert (SSL_CTX_use_certificate_file(sctx, "server.pem", SSL_FILETYPE_PEM));
|
||||
assert (SSL_CTX_use_PrivateKey_file(sctx, "server.key", SSL_FILETYPE_PEM));
|
||||
return 0;
|
||||
}
|
||||
extern "C" void LLVMFuzzerTestOneInput(unsigned char *Data, size_t Size) {
|
||||
static int unused = Init();
|
||||
SSL *server = SSL_new(sctx);
|
||||
BIO *sinbio = BIO_new(BIO_s_mem());
|
||||
BIO *soutbio = BIO_new(BIO_s_mem());
|
||||
SSL_set_bio(server, sinbio, soutbio);
|
||||
SSL_set_accept_state(server);
|
||||
BIO_write(sinbio, Data, Size);
|
||||
SSL_do_handshake(server);
|
||||
SSL_free(server);
|
||||
}
|
||||
EOF
|
||||
# Build the fuzzer.
|
||||
clang++ -g handshake-fuzz.cc -fsanitize=address \
|
||||
openssl-1.0.1f/libssl.a openssl-1.0.1f/libcrypto.a Fuzzer*.o
|
||||
# Run 20 independent fuzzer jobs.
|
||||
./a.out -jobs=20 -workers=20
|
||||
|
||||
Voila::
|
||||
|
||||
#1048576 pulse cov 3424 bits 0 units 9 exec/s 24385
|
||||
=================================================================
|
||||
==17488==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x629000004748 at pc 0x00000048c979 bp 0x7fffe3e864f0 sp 0x7fffe3e85ca8
|
||||
READ of size 60731 at 0x629000004748 thread T0
|
||||
#0 0x48c978 in __asan_memcpy
|
||||
#1 0x4db504 in tls1_process_heartbeat openssl-1.0.1f/ssl/t1_lib.c:2586:3
|
||||
#2 0x580be3 in ssl3_read_bytes openssl-1.0.1f/ssl/s3_pkt.c:1092:4
|
||||
|
||||
Advanced features
|
||||
=================
|
||||
|
||||
Tokens
|
||||
------
|
||||
|
||||
By default, the fuzzer is not aware of complexities of the input language
|
||||
and when fuzzing e.g. a C++ parser it will mostly stress the lexer.
|
||||
It is very hard for the fuzzer to come up with something like ``reinterpret_cast<int>``
|
||||
from a test corpus that doesn't have it.
|
||||
See a detailed discussion of this topic at
|
||||
http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html.
|
||||
|
||||
lib/Fuzzer implements a simple technique that allows to fuzz input languages with
|
||||
long tokens. All you need is to prepare a text file containing up to 253 tokens, one token per line,
|
||||
and pass it to the fuzzer as ``-tokens=TOKENS_FILE.txt``.
|
||||
Three implicit tokens are added: ``" "``, ``"\t"``, and ``"\n"``.
|
||||
The fuzzer itself will still be mutating a string of bytes
|
||||
but before passing this input to the target library it will replace every byte ``b`` with the ``b``-th token.
|
||||
If there are less than ``b`` tokens, a space will be added instead.
|
||||
|
||||
AFL compatibility
|
||||
-----------------
|
||||
LibFuzzer can be used in parallel with AFL_ on the same test corpus.
|
||||
Both fuzzers expect the test corpus to reside in a directory, one file per input.
|
||||
You can run both fuzzers on the same corpus in parallel::
|
||||
|
||||
./afl-fuzz -i testcase_dir -o findings_dir /path/to/program -r @@
|
||||
./llvm-fuzz testcase_dir findings_dir # Will write new tests to testcase_dir
|
||||
|
||||
Periodically restart both fuzzers so that they can use each other's findings.
|
||||
|
||||
How good is my fuzzer?
|
||||
----------------------
|
||||
|
||||
Once you implement your target function ``LLVMFuzzerTestOneInput`` and fuzz it to death,
|
||||
you will want to know whether the function or the corpus can be improved further.
|
||||
One easy to use metric is, of course, code coverage.
|
||||
You can get the coverage for your corpus like this::
|
||||
|
||||
ASAN_OPTIONS=coverage_pcs=1 ./fuzzer CORPUS_DIR -runs=0
|
||||
|
||||
This will run all the tests in the CORPUS_DIR but will not generate any new tests
|
||||
and dump covered PCs to disk before exiting.
|
||||
Then you can subtract the set of covered PCs from the set of all instrumented PCs in the binary,
|
||||
see SanitizerCoverage_ for details.
|
||||
|
||||
User-supplied mutators
|
||||
----------------------
|
||||
|
||||
LibFuzzer allows to use custom (user-supplied) mutators,
|
||||
see FuzzerInterface.h_
|
||||
|
||||
Fuzzing components of LLVM
|
||||
==========================
|
||||
|
||||
clang-format-fuzzer
|
||||
-------------------
|
||||
The inputs are random pieces of C++-like text.
|
||||
|
||||
Build (make sure to use fresh clang as the host compiler)::
|
||||
|
||||
cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_USE_SANITIZER=Address -DLLVM_USE_SANITIZE_COVERAGE=YES -DCMAKE_BUILD_TYPE=Release /path/to/llvm
|
||||
ninja clang-format-fuzzer
|
||||
mkdir CORPUS_DIR
|
||||
./bin/clang-format-fuzzer CORPUS_DIR
|
||||
|
||||
Optionally build other kinds of binaries (asan+Debug, msan, ubsan, etc).
|
||||
|
||||
TODO: commit the pre-fuzzed corpus to svn (?).
|
||||
|
||||
Tracking bug: https://llvm.org/bugs/show_bug.cgi?id=23052
|
||||
|
||||
clang-fuzzer
|
||||
------------
|
||||
|
||||
The default behavior is very similar to ``clang-format-fuzzer``.
|
||||
Clang can also be fuzzed with Tokens_ using ``-tokens=$LLVM/lib/Fuzzer/cxx_fuzzer_tokens.txt`` option.
|
||||
|
||||
Tracking bug: https://llvm.org/bugs/show_bug.cgi?id=23057
|
||||
|
||||
Buildbot
|
||||
--------
|
||||
|
||||
We have a buildbot that runs the above fuzzers for LLVM components
|
||||
24/7/365 at http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fuzzer .
|
||||
|
||||
Pre-fuzzed test inputs in git
|
||||
-----------------------------
|
||||
|
||||
The buildbot occumulates large test corpuses over time.
|
||||
The corpuses are stored in git on github and can be used like this::
|
||||
|
||||
git clone https://github.com/kcc/fuzzing-with-sanitizers.git
|
||||
bin/clang-format-fuzzer fuzzing-with-sanitizers/llvm/clang-format/C1
|
||||
bin/clang-fuzzer fuzzing-with-sanitizers/llvm/clang/C1/
|
||||
bin/clang-fuzzer fuzzing-with-sanitizers/llvm/clang/TOK1 -tokens=$LLVM/llvm/lib/Fuzzer/cxx_fuzzer_tokens.txt
|
||||
|
||||
|
||||
FAQ
|
||||
=========================
|
||||
|
||||
Q. Why Fuzzer does not use any of the LLVM support?
|
||||
---------------------------------------------------
|
||||
|
||||
There are two reasons.
|
||||
|
||||
First, we want this library to be used outside of the LLVM w/o users having to
|
||||
build the rest of LLVM. This may sound unconvincing for many LLVM folks,
|
||||
but in practice the need for building the whole LLVM frightens many potential
|
||||
users -- and we want more users to use this code.
|
||||
|
||||
Second, there is a subtle technical reason not to rely on the rest of LLVM, or
|
||||
any other large body of code (maybe not even STL). When coverage instrumentation
|
||||
is enabled, it will also instrument the LLVM support code which will blow up the
|
||||
coverage set of the process (since the fuzzer is in-process). In other words, by
|
||||
using more external dependencies we will slow down the fuzzer while the main
|
||||
reason for it to exist is extreme speed.
|
||||
|
||||
Q. What about Windows then? The Fuzzer contains code that does not build on Windows.
|
||||
------------------------------------------------------------------------------------
|
||||
|
||||
The sanitizer coverage support does not work on Windows either as of 01/2015.
|
||||
Once it's there, we'll need to re-implement OS-specific parts (I/O, signals).
|
||||
|
||||
Q. When this Fuzzer is not a good solution for a problem?
|
||||
---------------------------------------------------------
|
||||
|
||||
* If the test inputs are validated by the target library and the validator
|
||||
asserts/crashes on invalid inputs, the in-process fuzzer is not applicable
|
||||
(we could use fork() w/o exec, but it comes with extra overhead).
|
||||
* Bugs in the target library may accumulate w/o being detected. E.g. a memory
|
||||
corruption that goes undetected at first and then leads to a crash while
|
||||
testing another input. This is why it is highly recommended to run this
|
||||
in-process fuzzer with all sanitizers to detect most bugs on the spot.
|
||||
* It is harder to protect the in-process fuzzer from excessive memory
|
||||
consumption and infinite loops in the target library (still possible).
|
||||
* The target library should not have significant global state that is not
|
||||
reset between the runs.
|
||||
* Many interesting target libs are not designed in a way that supports
|
||||
the in-process fuzzer interface (e.g. require a file path instead of a
|
||||
byte array).
|
||||
* If a single test run takes a considerable fraction of a second (or
|
||||
more) the speed benefit from the in-process fuzzer is negligible.
|
||||
* If the target library runs persistent threads (that outlive
|
||||
execution of one test) the fuzzing results will be unreliable.
|
||||
|
||||
Q. So, what exactly this Fuzzer is good for?
|
||||
--------------------------------------------
|
||||
|
||||
This Fuzzer might be a good choice for testing libraries that have relatively
|
||||
small inputs, each input takes < 1ms to run, and the library code is not expected
|
||||
to crash on invalid inputs.
|
||||
Examples: regular expression matchers, text or binary format parsers.
|
||||
|
||||
.. _pcre2: http://www.pcre.org/
|
||||
|
||||
.. _AFL: http://lcamtuf.coredump.cx/afl/
|
||||
|
||||
.. _SanitizerCoverage: http://clang.llvm.org/docs/SanitizerCoverage.html
|
||||
|
||||
.. _Heartbleed: http://en.wikipedia.org/wiki/Heartbleed
|
||||
|
||||
.. _FuzzerInterface.h: https://github.com/llvm-mirror/llvm/blob/master/lib/Fuzzer/FuzzerInterface.h
|
@ -16,24 +16,29 @@ DOXYGEN = doxygen
|
||||
|
||||
$(PROJ_OBJ_DIR)/doxygen.cfg: doxygen.cfg.in
|
||||
cat $< | sed \
|
||||
-e 's/@abs_top_srcdir@/../g' \
|
||||
-e 's/@DOT@/dot/g' \
|
||||
-e 's/@PACKAGE_VERSION@/mainline/' \
|
||||
-e 's/@abs_top_builddir@/../g' \
|
||||
-e 's/@enable_searchengine@/NO/g' \
|
||||
-e 's/@searchengine_url@//g' \
|
||||
-e 's/@enable_server_based_search@/NO/g' \
|
||||
-e 's/@abs_top_srcdir@/../g' \
|
||||
-e 's/@enable_external_search@/NO/g' \
|
||||
-e 's/@extra_search_mappings@//g' > $@
|
||||
-e 's/@enable_searchengine@/NO/g' \
|
||||
-e 's/@enable_server_based_search@/NO/g' \
|
||||
-e 's/@extra_search_mappings@//g' \
|
||||
-e 's/@llvm_doxygen_generate_qhp@//g' \
|
||||
-e 's/@llvm_doxygen_qch_filename@//g' \
|
||||
-e 's/@llvm_doxygen_qhelpgenerator_path@//g' \
|
||||
-e 's/@llvm_doxygen_qhp_cust_filter_attrs@//g' \
|
||||
-e 's/@llvm_doxygen_qhp_cust_filter_name@//g' \
|
||||
-e 's/@llvm_doxygen_qhp_namespace@//g' \
|
||||
-e 's/@searchengine_url@//g' \
|
||||
> $@
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
HTML := $(wildcard $(PROJ_SRC_DIR)/*.html) \
|
||||
$(wildcard $(PROJ_SRC_DIR)/*.css)
|
||||
DOXYFILES := doxygen.cfg.in doxygen.css doxygen.footer doxygen.header \
|
||||
doxygen.intro
|
||||
EXTRA_DIST := $(HTML) $(DOXYFILES) llvm.css CommandGuide
|
||||
DOXYFILES := doxygen.cfg.in doxygen.intro
|
||||
|
||||
.PHONY: install-html install-doxygen doxygen install-ocamldoc ocamldoc generated
|
||||
|
||||
@ -41,7 +46,7 @@ install_targets := install-html
|
||||
ifeq ($(ENABLE_DOXYGEN),1)
|
||||
install_targets += install-doxygen
|
||||
endif
|
||||
ifdef OCAMLDOC
|
||||
ifdef OCAMLFIND
|
||||
ifneq (,$(filter ocaml,$(BINDINGS_TO_BUILD)))
|
||||
install_targets += install-ocamldoc
|
||||
endif
|
||||
@ -49,7 +54,7 @@ endif
|
||||
install-local:: $(install_targets)
|
||||
|
||||
generated_targets := doxygen
|
||||
ifdef OCAMLDOC
|
||||
ifdef OCAMLFIND
|
||||
generated_targets += ocamldoc
|
||||
endif
|
||||
|
||||
@ -72,11 +77,14 @@ $(PROJ_OBJ_DIR)/html.tar.gz: $(HTML)
|
||||
|
||||
install-doxygen: doxygen
|
||||
$(Echo) Installing doxygen documentation
|
||||
$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/doxygen
|
||||
$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(DESTDIR)$(PROJ_docsdir)
|
||||
$(Verb) cd $(PROJ_OBJ_DIR)/doxygen && \
|
||||
$(FIND) . -type f -exec \
|
||||
$(DataInstall) {} $(DESTDIR)$(PROJ_docsdir)/html/doxygen \;
|
||||
$(Verb) cd $(PROJ_OBJ_DIR)/doxygen/html && \
|
||||
for DIR in $$($(FIND) . -type d); do \
|
||||
DESTSUB="$(DESTDIR)$(PROJ_docsdir)/html/doxygen/$$(echo $$DIR | cut -c 3-)"; \
|
||||
$(MKDIR) $$DESTSUB && \
|
||||
$(FIND) $$DIR -maxdepth 1 -type f -exec $(DataInstall) {} $$DESTSUB \; ; \
|
||||
if [ $$? != 0 ]; then exit 1; fi \
|
||||
done
|
||||
|
||||
doxygen: regendoc $(PROJ_OBJ_DIR)/doxygen.tar.gz
|
||||
|
||||
@ -120,7 +128,7 @@ regen-ocamldoc:
|
||||
$(Verb) $(MAKE) -C $(LEVEL)/bindings/ocaml ocamldoc
|
||||
$(Verb) $(MKDIR) $(PROJ_OBJ_DIR)/ocamldoc/html
|
||||
$(Verb) \
|
||||
$(OCAMLDOC) -d $(PROJ_OBJ_DIR)/ocamldoc/html -sort -colorize-code -html \
|
||||
$(OCAMLFIND) ocamldoc -d $(PROJ_OBJ_DIR)/ocamldoc/html -sort -colorize-code -html \
|
||||
`$(FIND) $(LEVEL)/bindings/ocaml -name "*.odoc" \
|
||||
-path "*/$(BuildMode)/*.odoc" -exec echo -load '{}' ';'`
|
||||
|
||||
|
@ -58,8 +58,8 @@ Especially it's important to understand chapter 3 of tutorial:
|
||||
|
||||
:doc:`tutorial/LangImpl3`
|
||||
|
||||
Reader also should know how passes work in LLVM, he could use next article as a
|
||||
reference and start point here:
|
||||
Reader also should know how passes work in LLVM, they could use next article as
|
||||
a reference and start point here:
|
||||
|
||||
:doc:`WritingAnLLVMPass`
|
||||
|
||||
@ -88,7 +88,7 @@ part describes the merging process.
|
||||
In every part author also tried to put the contents into the top-down form.
|
||||
First, the top-level methods will be described, while the terminal ones will be
|
||||
at the end, in the tail of each part. If reader will see the reference to the
|
||||
method that wasn't described yet, he will find its description a bit below.
|
||||
method that wasn't described yet, they will find its description a bit below.
|
||||
|
||||
Basics
|
||||
======
|
||||
|
@ -1119,13 +1119,6 @@ useful when diffing the effect of an optimization because deleting an unnamed
|
||||
instruction can change all other instruction numbering, making the diff very
|
||||
noisy.
|
||||
|
||||
``-preverify``: Preliminary module verification
|
||||
-----------------------------------------------
|
||||
|
||||
Ensures that the module is in the form required by the :ref:`Module Verifier
|
||||
<passes-verify>` pass. Running the verifier runs this pass automatically, so
|
||||
there should be no need to use it directly.
|
||||
|
||||
.. _passes-verify:
|
||||
|
||||
``-verify``: Module Verifier
|
||||
|
@ -64,7 +64,9 @@ To upload a new patch:
|
||||
* Paste the text diff or upload the patch file.
|
||||
Note that TODO
|
||||
* Leave the drop down on *Create a new Revision...* and click *Continue*.
|
||||
* Enter a descriptive title and summary; add reviewers and mailing
|
||||
* Enter a descriptive title and summary. The title and summary are usually
|
||||
in the form of a :ref:`commit message <commit messages>`.
|
||||
* Add reviewers and mailing
|
||||
lists that you want to be included in the review. If your patch is
|
||||
for LLVM, add llvm-commits as a subscriber; if your patch is for Clang,
|
||||
add cfe-commits.
|
||||
@ -85,8 +87,11 @@ Reviewing code with Phabricator
|
||||
Phabricator allows you to add inline comments as well as overall comments
|
||||
to a revision. To add an inline comment, select the lines of code you want
|
||||
to comment on by clicking and dragging the line numbers in the diff pane.
|
||||
When you have added all your comments, scroll to the bottom of the page and
|
||||
click the Submit button.
|
||||
|
||||
You can add overall comments or submit your comments at the bottom of the page.
|
||||
You can add overall comments in the text box at the bottom of the page.
|
||||
When you're done, click the Submit button.
|
||||
|
||||
Phabricator has many useful features, for example allowing you to select
|
||||
diffs between different versions of the patch as it was reviewed in the
|
||||
@ -128,13 +133,33 @@ This allows people reading the version history to see the review for
|
||||
context. This also allows Phabricator to detect the commit, close the
|
||||
review, and add a link from the review to the commit.
|
||||
|
||||
Abandoning a change
|
||||
-------------------
|
||||
|
||||
If you decide you should not commit the patch, you should explicitly abandon
|
||||
the review so that reviewers don't think it is still open. In the web UI,
|
||||
scroll to the bottom of the page where normally you would enter an overall
|
||||
comment. In the drop-down Action list, which defaults to "Comment," you should
|
||||
select "Abandon Revision" and then enter a comment explaining why. Click the
|
||||
Submit button to finish closing the review.
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
Please let us know whether you like it and what could be improved!
|
||||
Please let us know whether you like it and what could be improved! We're still
|
||||
working on setting up a bug tracker, but you can email klimek-at-google-dot-com
|
||||
and chandlerc-at-gmail-dot-com and CC the llvmdev mailing list with questions
|
||||
until then. We also could use help implementing improvements. This sadly is
|
||||
really painful and hard because the Phabricator codebase is in PHP and not as
|
||||
testable as you might like. However, we've put exactly what we're deploying up
|
||||
on an `llvm-reviews GitHub project`_ where folks can hack on it and post pull
|
||||
requests. We're looking into what the right long-term hosting for this is, but
|
||||
note that it is a derivative of an existing open source project, and so not
|
||||
trivially a good fit for an official LLVM project.
|
||||
|
||||
.. _LLVM's Phabricator: http://reviews.llvm.org
|
||||
.. _`http://reviews.llvm.org`: http://reviews.llvm.org
|
||||
.. _Code Repository Browser: http://reviews.llvm.org/diffusion/
|
||||
.. _Arcanist Quick Start: http://www.phabricator.com/docs/phabricator/article/Arcanist_Quick_Start.html
|
||||
.. _Arcanist User Guide: http://www.phabricator.com/docs/phabricator/article/Arcanist_User_Guide.html
|
||||
.. _llvm-reviews GitHub project: https://github.com/r4nt/llvm-reviews/
|
||||
|
@ -488,6 +488,9 @@ gathered, use the '``-stats``' option:
|
||||
$ opt -stats -mypassname < program.bc > /dev/null
|
||||
... statistics output ...
|
||||
|
||||
Note that in order to use the '``-stats``' option, LLVM must be
|
||||
compiled with assertions enabled.
|
||||
|
||||
When running ``opt`` on a C file from the SPEC benchmark suite, it gives a
|
||||
report that looks like this:
|
||||
|
||||
@ -937,7 +940,7 @@ There are a variety of ways to pass around and use strings in C and C++, and
|
||||
LLVM adds a few new options to choose from. Pick the first option on this list
|
||||
that will do what you need, they are ordered according to their relative cost.
|
||||
|
||||
Note that is is generally preferred to *not* pass strings around as ``const
|
||||
Note that it is generally preferred to *not* pass strings around as ``const
|
||||
char*``'s. These have a number of problems, including the fact that they
|
||||
cannot represent embedded nul ("\0") characters, and do not have a length
|
||||
available efficiently. The general replacement for '``const char*``' is
|
||||
@ -1102,10 +1105,10 @@ If you have a set-like data structure that is usually small and whose elements
|
||||
are reasonably small, a ``SmallSet<Type, N>`` is a good choice. This set has
|
||||
space for N elements in place (thus, if the set is dynamically smaller than N,
|
||||
no malloc traffic is required) and accesses them with a simple linear search.
|
||||
When the set grows beyond 'N' elements, it allocates a more expensive
|
||||
When the set grows beyond N elements, it allocates a more expensive
|
||||
representation that guarantees efficient access (for most types, it falls back
|
||||
to std::set, but for pointers it uses something far better, :ref:`SmallPtrSet
|
||||
<dss_smallptrset>`.
|
||||
to :ref:`std::set <dss_set>`, but for pointers it uses something far better,
|
||||
:ref:`SmallPtrSet <dss_smallptrset>`.
|
||||
|
||||
The magic of this class is that it handles small sets extremely efficiently, but
|
||||
gracefully handles extremely large sets without loss of efficiency. The
|
||||
@ -1117,16 +1120,31 @@ and erasing, but does not support iteration.
|
||||
llvm/ADT/SmallPtrSet.h
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
SmallPtrSet has all the advantages of ``SmallSet`` (and a ``SmallSet`` of
|
||||
``SmallPtrSet`` has all the advantages of ``SmallSet`` (and a ``SmallSet`` of
|
||||
pointers is transparently implemented with a ``SmallPtrSet``), but also supports
|
||||
iterators. If more than 'N' insertions are performed, a single quadratically
|
||||
iterators. If more than N insertions are performed, a single quadratically
|
||||
probed hash table is allocated and grows as needed, providing extremely
|
||||
efficient access (constant time insertion/deleting/queries with low constant
|
||||
factors) and is very stingy with malloc traffic.
|
||||
|
||||
Note that, unlike ``std::set``, the iterators of ``SmallPtrSet`` are invalidated
|
||||
whenever an insertion occurs. Also, the values visited by the iterators are not
|
||||
visited in sorted order.
|
||||
Note that, unlike :ref:`std::set <dss_set>`, the iterators of ``SmallPtrSet``
|
||||
are invalidated whenever an insertion occurs. Also, the values visited by the
|
||||
iterators are not visited in sorted order.
|
||||
|
||||
.. _dss_stringset:
|
||||
|
||||
llvm/ADT/StringSet.h
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``StringSet`` is a thin wrapper around :ref:`StringMap\<char\> <dss_stringmap>`,
|
||||
and it allows efficient storage and retrieval of unique strings.
|
||||
|
||||
Functionally analogous to ``SmallSet<StringRef>``, ``StringSet`` also suports
|
||||
iteration. (The iterator dereferences to a ``StringMapEntry<char>``, so you
|
||||
need to call ``i->getKey()`` to access the item of the StringSet.) On the
|
||||
other hand, ``StringSet`` doesn't support range-insertion and
|
||||
copy-construction, which :ref:`SmallSet <dss_smallset>` and :ref:`SmallPtrSet
|
||||
<dss_smallptrset>` do support.
|
||||
|
||||
.. _dss_denseset:
|
||||
|
||||
@ -1294,8 +1312,9 @@ never use hash_set and unordered_set because they are generally very expensive
|
||||
(each insertion requires a malloc) and very non-portable.
|
||||
|
||||
std::multiset is useful if you're not interested in elimination of duplicates,
|
||||
but has all the drawbacks of std::set. A sorted vector (where you don't delete
|
||||
duplicate entries) or some other approach is almost always better.
|
||||
but has all the drawbacks of :ref:`std::set <dss_set>`. A sorted vector
|
||||
(where you don't delete duplicate entries) or some other approach is almost
|
||||
always better.
|
||||
|
||||
.. _ds_map:
|
||||
|
||||
@ -1408,7 +1427,7 @@ llvm/ADT/IntervalMap.h
|
||||
|
||||
IntervalMap is a compact map for small keys and values. It maps key intervals
|
||||
instead of single keys, and it will automatically coalesce adjacent intervals.
|
||||
When then map only contains a few intervals, they are stored in the map object
|
||||
When the map only contains a few intervals, they are stored in the map object
|
||||
itself to avoid allocations.
|
||||
|
||||
The IntervalMap iterators are quite big, so they should not be passed around as
|
||||
@ -1684,8 +1703,8 @@ they will automatically convert to a ptr-to-instance type whenever they need to.
|
||||
Instead of derferencing the iterator and then taking the address of the result,
|
||||
you can simply assign the iterator to the proper pointer type and you get the
|
||||
dereference and address-of operation as a result of the assignment (behind the
|
||||
scenes, this is a result of overloading casting mechanisms). Thus the last line
|
||||
of the last example,
|
||||
scenes, this is a result of overloading casting mechanisms). Thus the second
|
||||
line of the last example,
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@ -1813,7 +1832,7 @@ chain of ``F``:
|
||||
|
||||
Function *F = ...;
|
||||
|
||||
for (User *U : GV->users()) {
|
||||
for (User *U : F->users()) {
|
||||
if (Instruction *Inst = dyn_cast<Instruction>(U)) {
|
||||
errs() << "F is used in instruction:\n";
|
||||
errs() << *Inst << "\n";
|
||||
@ -2480,6 +2499,92 @@ ensures that the first bytes of ``User`` (if interpreted as a pointer) never has
|
||||
the LSBit set. (Portability is relying on the fact that all known compilers
|
||||
place the ``vptr`` in the first word of the instances.)
|
||||
|
||||
.. _polymorphism:
|
||||
|
||||
Designing Type Hiercharies and Polymorphic Interfaces
|
||||
-----------------------------------------------------
|
||||
|
||||
There are two different design patterns that tend to result in the use of
|
||||
virtual dispatch for methods in a type hierarchy in C++ programs. The first is
|
||||
a genuine type hierarchy where different types in the hierarchy model
|
||||
a specific subset of the functionality and semantics, and these types nest
|
||||
strictly within each other. Good examples of this can be seen in the ``Value``
|
||||
or ``Type`` type hierarchies.
|
||||
|
||||
A second is the desire to dispatch dynamically across a collection of
|
||||
polymorphic interface implementations. This latter use case can be modeled with
|
||||
virtual dispatch and inheritance by defining an abstract interface base class
|
||||
which all implementations derive from and override. However, this
|
||||
implementation strategy forces an **"is-a"** relationship to exist that is not
|
||||
actually meaningful. There is often not some nested hierarchy of useful
|
||||
generalizations which code might interact with and move up and down. Instead,
|
||||
there is a singular interface which is dispatched across a range of
|
||||
implementations.
|
||||
|
||||
The preferred implementation strategy for the second use case is that of
|
||||
generic programming (sometimes called "compile-time duck typing" or "static
|
||||
polymorphism"). For example, a template over some type parameter ``T`` can be
|
||||
instantiated across any particular implementation that conforms to the
|
||||
interface or *concept*. A good example here is the highly generic properties of
|
||||
any type which models a node in a directed graph. LLVM models these primarily
|
||||
through templates and generic programming. Such templates include the
|
||||
``LoopInfoBase`` and ``DominatorTreeBase``. When this type of polymorphism
|
||||
truly needs **dynamic** dispatch you can generalize it using a technique
|
||||
called *concept-based polymorphism*. This pattern emulates the interfaces and
|
||||
behaviors of templates using a very limited form of virtual dispatch for type
|
||||
erasure inside its implementation. You can find examples of this technique in
|
||||
the ``PassManager.h`` system, and there is a more detailed introduction to it
|
||||
by Sean Parent in several of his talks and papers:
|
||||
|
||||
#. `Inheritance Is The Base Class of Evil
|
||||
<http://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil>`_
|
||||
- The GoingNative 2013 talk describing this technique, and probably the best
|
||||
place to start.
|
||||
#. `Value Semantics and Concepts-based Polymorphism
|
||||
<http://www.youtube.com/watch?v=_BpMYeUFXv8>`_ - The C++Now! 2012 talk
|
||||
describing this technique in more detail.
|
||||
#. `Sean Parent's Papers and Presentations
|
||||
<http://github.com/sean-parent/sean-parent.github.com/wiki/Papers-and-Presentations>`_
|
||||
- A Github project full of links to slides, video, and sometimes code.
|
||||
|
||||
When deciding between creating a type hierarchy (with either tagged or virtual
|
||||
dispatch) and using templates or concepts-based polymorphism, consider whether
|
||||
there is some refinement of an abstract base class which is a semantically
|
||||
meaningful type on an interface boundary. If anything more refined than the
|
||||
root abstract interface is meaningless to talk about as a partial extension of
|
||||
the semantic model, then your use case likely fits better with polymorphism and
|
||||
you should avoid using virtual dispatch. However, there may be some exigent
|
||||
circumstances that require one technique or the other to be used.
|
||||
|
||||
If you do need to introduce a type hierarchy, we prefer to use explicitly
|
||||
closed type hierarchies with manual tagged dispatch and/or RTTI rather than the
|
||||
open inheritance model and virtual dispatch that is more common in C++ code.
|
||||
This is because LLVM rarely encourages library consumers to extend its core
|
||||
types, and leverages the closed and tag-dispatched nature of its hierarchies to
|
||||
generate significantly more efficient code. We have also found that a large
|
||||
amount of our usage of type hierarchies fits better with tag-based pattern
|
||||
matching rather than dynamic dispatch across a common interface. Within LLVM we
|
||||
have built custom helpers to facilitate this design. See this document's
|
||||
section on :ref:`isa and dyn_cast <isa>` and our :doc:`detailed document
|
||||
<HowToSetUpLLVMStyleRTTI>` which describes how you can implement this
|
||||
pattern for use with the LLVM helpers.
|
||||
|
||||
.. _abi_breaking_checks:
|
||||
|
||||
ABI Breaking Checks
|
||||
-------------------
|
||||
|
||||
Checks and asserts that alter the LLVM C++ ABI are predicated on the
|
||||
preprocessor symbol `LLVM_ENABLE_ABI_BREAKING_CHECKS` -- LLVM
|
||||
libraries built with `LLVM_ENABLE_ABI_BREAKING_CHECKS` are not ABI
|
||||
compatible LLVM libraries built without it defined. By default,
|
||||
turning on assertions also turns on `LLVM_ENABLE_ABI_BREAKING_CHECKS`
|
||||
so a default +Asserts build is not ABI compatible with a
|
||||
default -Asserts build. Clients that want ABI compatibility
|
||||
between +Asserts and -Asserts builds should use the CMake or autoconf
|
||||
build systems to set `LLVM_ENABLE_ABI_BREAKING_CHECKS` independently
|
||||
of `LLVM_ENABLE_ASSERTIONS`.
|
||||
|
||||
.. _coreclasses:
|
||||
|
||||
The Core LLVM Class Hierarchy Reference
|
||||
@ -2493,8 +2598,9 @@ doxygen info: `Type Clases <http://llvm.org/doxygen/classllvm_1_1Type.html>`_
|
||||
|
||||
The Core LLVM classes are the primary means of representing the program being
|
||||
inspected or transformed. The core LLVM classes are defined in header files in
|
||||
the ``include/llvm/`` directory, and implemented in the ``lib/VMCore``
|
||||
directory.
|
||||
the ``include/llvm/IR`` directory, and implemented in the ``lib/IR``
|
||||
directory. It's worth noting that, for historical reasons, this library is
|
||||
called ``libLLVMCore.so``, not ``libLLVMIR.so`` as you might expect.
|
||||
|
||||
.. _Type:
|
||||
|
||||
@ -2562,7 +2668,7 @@ Important Derived Types
|
||||
Subclass of SequentialType for vector types. A vector type is similar to an
|
||||
ArrayType but is distinguished because it is a first class type whereas
|
||||
ArrayType is not. Vector types are used for vector operations and are usually
|
||||
small vectors of of an integer or floating point type.
|
||||
small vectors of an integer or floating point type.
|
||||
|
||||
``StructType``
|
||||
Subclass of DerivedTypes for struct types.
|
||||
|
@ -6,22 +6,51 @@ Introduction
|
||||
============
|
||||
|
||||
The R600 back-end provides ISA code generation for AMD GPUs, starting with
|
||||
the R600 family up until the current Sea Islands (GCN Gen 2).
|
||||
the R600 family up until the current Volcanic Islands (GCN Gen 3).
|
||||
|
||||
|
||||
Assembler
|
||||
=========
|
||||
|
||||
The assembler is currently a work in progress and not yet complete. Below
|
||||
are the currently supported features.
|
||||
The assembler is currently considered experimental.
|
||||
|
||||
For syntax examples look in test/MC/R600.
|
||||
|
||||
Below some of the currently supported features (modulo bugs). These
|
||||
all apply to the Southern Islands ISA, Sea Islands and Volcanic Islands
|
||||
are also supported but may be missing some instructions and have more bugs:
|
||||
|
||||
DS Instructions
|
||||
---------------
|
||||
All DS instructions are supported.
|
||||
|
||||
MUBUF Instructions
|
||||
------------------
|
||||
All non-atomic MUBUF instructions are supported.
|
||||
|
||||
SMRD Instructions
|
||||
-----------------
|
||||
Only the s_load_dword* SMRD instructions are supported.
|
||||
|
||||
SOP1 Instructions
|
||||
-----------------
|
||||
All SOP1 instructions are supported.
|
||||
|
||||
SOP2 Instructions
|
||||
-----------------
|
||||
All SOP2 instructions are supported.
|
||||
|
||||
SOPC Instructions
|
||||
-----------------
|
||||
All SOPC instructions are supported.
|
||||
|
||||
SOPP Instructions
|
||||
-----------------
|
||||
|
||||
Unless otherwise mentioned, all SOPP instructions that with an operand
|
||||
accept a integer operand(s) only. No verification is performed on the
|
||||
operands, so it is up to the programmer to be familiar with the range
|
||||
or acceptable values.
|
||||
Unless otherwise mentioned, all SOPP instructions that have one or more
|
||||
operands accept integer operands only. No verification is performed
|
||||
on the operands, so it is up to the programmer to be familiar with the
|
||||
range or acceptable values.
|
||||
|
||||
s_waitcnt
|
||||
^^^^^^^^^
|
||||
@ -41,3 +70,20 @@ wait for.
|
||||
// Wait for vmcnt counter to be 1.
|
||||
s_waitcnt vmcnt(1)
|
||||
|
||||
VOP1, VOP2, VOP3, VOPC Instructions
|
||||
-----------------------------------
|
||||
|
||||
All 32-bit and 64-bit encodings should work.
|
||||
|
||||
The assembler will automatically detect which encoding size to use for
|
||||
VOP1, VOP2, and VOPC instructions based on the operands. If you want to force
|
||||
a specific encoding size, you can add an _e32 (for 32-bit encoding) or
|
||||
_e64 (for 64-bit encoding) suffix to the instruction. Most, but not all
|
||||
instructions support an explicit suffix. These are all valid assembly
|
||||
strings:
|
||||
|
||||
.. code-block:: nasm
|
||||
|
||||
v_mul_i32_i24 v1, v2, v3
|
||||
v_mul_i32_i24_e32 v1, v2, v3
|
||||
v_mul_i32_i24_e64 v1, v2, v3
|
||||
|
@ -1,16 +1,21 @@
|
||||
======================
|
||||
LLVM 3.6 Release Notes
|
||||
LLVM 3.7 Release Notes
|
||||
======================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
.. warning::
|
||||
These are in-progress notes for the upcoming LLVM 3.7 release. You may
|
||||
prefer the `LLVM 3.6 Release Notes <http://llvm.org/releases/3.6.0/docs
|
||||
/ReleaseNotes.html>`_.
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document contains the release notes for the LLVM Compiler Infrastructure,
|
||||
release 3.6. Here we describe the status of LLVM, including major improvements
|
||||
release 3.7. Here we describe the status of LLVM, including major improvements
|
||||
from the previous release, improvements in various subprojects of LLVM, and
|
||||
some of the current users of the code. All LLVM releases may be downloaded
|
||||
from the `LLVM releases web site <http://llvm.org/releases/>`_.
|
||||
@ -21,35 +26,14 @@ have questions or comments, the `LLVM Developer's Mailing List
|
||||
<http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev>`_ is a good place to send
|
||||
them.
|
||||
|
||||
Note that if you are reading this file from a Subversion checkout or the main
|
||||
LLVM web page, this document applies to the *next* release, not the current
|
||||
one. To see the release notes for a specific release, please see the `releases
|
||||
page <http://llvm.org/releases/>`_.
|
||||
|
||||
Non-comprehensive list of changes in this release
|
||||
=================================================
|
||||
|
||||
Changes to the MIPS Target
|
||||
--------------------------
|
||||
|
||||
* Added support for 128-bit integers on 64-bit targets.
|
||||
|
||||
* Fixed some remaining N32/N64 calling convention bugs when using small
|
||||
structures on big-endian targets.
|
||||
|
||||
* Fixed missing sign-extensions that are required by the N32/N64 calling
|
||||
convention when generating calls to library functions with 32-bit parameters.
|
||||
|
||||
* ``-mno-odd-spreg`` is now honoured for vector insertion/extraction operations
|
||||
when using ``-mmsa``.
|
||||
|
||||
* Corrected the representation of member function pointers. This makes them
|
||||
usable on microMIPS targets.
|
||||
|
||||
* Fixed multiple segfaults and assertions in the disassembler when
|
||||
disassembling instructions that have memory operands.
|
||||
|
||||
* Fixed multiple cases of suboptimal code generation involving ``$zero``.
|
||||
|
||||
Non-comprehensive list of changes in 3.6.0
|
||||
==========================================
|
||||
|
||||
.. NOTE
|
||||
For small 1-3 sentence descriptions, just add an entry at the end of
|
||||
this list. If your description won't fit comfortably in one bullet
|
||||
@ -57,13 +41,19 @@ Non-comprehensive list of changes in 3.6.0
|
||||
functionality, or simply have a lot to talk about), see the `NOTE` below
|
||||
for adding a new subsection.
|
||||
|
||||
* Support for AuroraUX has been removed.
|
||||
* The minimum required Visual Studio version for building LLVM is now 2013
|
||||
Update 4.
|
||||
|
||||
* Added support for a `native object file-based bitcode wrapper format
|
||||
<BitCodeFormat.html#native-object-file>`_.
|
||||
* A new documentation page, :doc:`Frontend/PerformanceTips`, contains a
|
||||
collection of tips for frontend authors on how to generate IR which LLVM is
|
||||
able to effectively optimize.
|
||||
|
||||
* Added support for MSVC's ``__vectorcall`` calling convention as
|
||||
``x86_vectorcallcc``.
|
||||
* The DataLayout is no longer optional. All the IR level optimizations expects
|
||||
it to be present and the API has been changed to use a reference instead of
|
||||
a pointer to make it explicit. The Module owns the datalayout and it has to
|
||||
match the one attached to the TargetMachine for generating code.
|
||||
|
||||
* ... next change ...
|
||||
|
||||
.. NOTE
|
||||
If you would like to document a larger change, then you can add a
|
||||
@ -75,585 +65,38 @@ Non-comprehensive list of changes in 3.6.0
|
||||
|
||||
Makes programs 10x faster by doing Special New Thing.
|
||||
|
||||
Prefix data rework
|
||||
------------------
|
||||
|
||||
The semantics of the ``prefix`` attribute have been changed. Users
|
||||
that want the previous ``prefix`` semantics should instead use
|
||||
``prologue``. To motivate this change, let's examine the primary
|
||||
usecases that these attributes aim to serve,
|
||||
|
||||
1. Code sanitization metadata (e.g. Clang's undefined behavior
|
||||
sanitizer)
|
||||
|
||||
2. Function hot-patching: Enable the user to insert ``nop`` operations
|
||||
at the beginning of the function which can later be safely replaced
|
||||
with a call to some instrumentation facility.
|
||||
|
||||
3. Language runtime metadata: Allow a compiler to insert data for
|
||||
use by the runtime during execution. GHC is one example of a
|
||||
compiler that needs this functionality for its
|
||||
tables-next-to-code functionality.
|
||||
|
||||
Previously ``prefix`` served cases (1) and (2) quite well by allowing the user
|
||||
to introduce arbitrary data at the entrypoint but before the function
|
||||
body. Case (3), however, was poorly handled by this approach as it
|
||||
required that prefix data was valid executable code.
|
||||
|
||||
In this release the concept of prefix data has been redefined to be
|
||||
data which occurs immediately before the function entrypoint (i.e. the
|
||||
symbol address). Since prefix data now occurs before the function
|
||||
entrypoint, there is no need for the data to be valid code.
|
||||
|
||||
The previous notion of prefix data now goes under the name "prologue
|
||||
data" to emphasize its duality with the function epilogue.
|
||||
|
||||
The intention here is to handle cases (1) and (2) with prologue data and
|
||||
case (3) with prefix data. See the language reference for further details
|
||||
on the semantics of these attributes.
|
||||
|
||||
This refactoring arose out of discussions_ with Reid Kleckner in
|
||||
response to a proposal to introduce the notion of symbol offsets to
|
||||
enable handling of case (3).
|
||||
|
||||
.. _discussions: http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-May/073235.html
|
||||
|
||||
|
||||
Metadata is not a Value
|
||||
-----------------------
|
||||
|
||||
Metadata nodes (``!{...}``) and strings (``!"..."``) are no longer values.
|
||||
They have no use-lists, no type, cannot RAUW, and cannot be function-local.
|
||||
|
||||
Bridges between Value and Metadata
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
LLVM intrinsics can reference metadata using the ``metadata`` type, and
|
||||
metadata nodes can reference constant values.
|
||||
|
||||
Function-local metadata is limited to direct arguments to LLVM intrinsics.
|
||||
|
||||
Metadata is typeless
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The following old IR:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
@g = global i32 0
|
||||
|
||||
define void @foo(i32 %v) {
|
||||
entry:
|
||||
call void @llvm.md(metadata !{i32 %v})
|
||||
call void @llvm.md(metadata !{i32* @global})
|
||||
call void @llvm.md(metadata !0)
|
||||
call void @llvm.md(metadata !{metadata !"string"})
|
||||
call void @llvm.md(metadata !{metadata !{metadata !1, metadata !"string"}})
|
||||
ret void, !bar !1, !baz !2
|
||||
}
|
||||
|
||||
declare void @llvm.md(metadata)
|
||||
|
||||
!0 = metadata !{metadata !1, metadata !2, metadata !3, metadata !"some string"}
|
||||
!1 = metadata !{metadata !2, null, metadata !"other", i32* @global, i32 7}
|
||||
!2 = metadata !{}
|
||||
|
||||
should now be written as:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
@g = global i32 0
|
||||
|
||||
define void @foo(i32 %v) {
|
||||
entry:
|
||||
call void @llvm.md(metadata i32 %v) ; The only legal place for function-local
|
||||
; metadata.
|
||||
call void @llvm.md(metadata i32* @global)
|
||||
call void @llvm.md(metadata !0)
|
||||
call void @llvm.md(metadata !{!"string"})
|
||||
call void @llvm.md(metadata !{!{!1, !"string"}})
|
||||
ret void, !bar !1, !baz !2
|
||||
}
|
||||
|
||||
declare void @llvm.md(metadata)
|
||||
|
||||
!0 = !{!1, !2, !3, !"some string"}
|
||||
!1 = !{!2, null, !"other", i32* @global, i32 7}
|
||||
!2 = !{}
|
||||
|
||||
Distinct metadata nodes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Metadata nodes can opt-out of uniquing, using the keyword ``distinct``.
|
||||
Distinct nodes are still owned by the context, but are stored in a side table,
|
||||
and not uniqued.
|
||||
|
||||
In LLVM 3.5, metadata nodes would drop uniquing if an operand changed to
|
||||
``null`` during optimizations. This is no longer true. However, if an operand
|
||||
change causes a uniquing collision, they become ``distinct``. Unlike LLVM 3.5,
|
||||
where serializing to assembly or bitcode would re-unique the nodes, they now
|
||||
remain ``distinct``.
|
||||
|
||||
The following IR:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
|
||||
|
||||
!0 = !{}
|
||||
!1 = !{}
|
||||
!2 = distinct !{}
|
||||
!3 = distinct !{}
|
||||
!4 = !{!0}
|
||||
!5 = distinct !{!0}
|
||||
!6 = !{!4, !{}, !5}
|
||||
!7 = !{!{!0}, !0, !5}
|
||||
!8 = distinct !{!{!0}, !0, !5}
|
||||
|
||||
is equivalent to the following:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!named = !{!0, !0, !1, !2, !3, !4, !5, !5, !6}
|
||||
|
||||
!0 = !{}
|
||||
!1 = distinct !{}
|
||||
!2 = distinct !{}
|
||||
!3 = !{!0}
|
||||
!4 = distinct !{!0}
|
||||
!5 = !{!3, !0, !4}
|
||||
!6 = distinct !{!3, !0, !4}
|
||||
|
||||
Constructing cyclic graphs
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
During graph construction, if a metadata node transitively references a forward
|
||||
declaration, the node itself is considered "unresolved" until the forward
|
||||
declaration resolves. An unresolved node can RAUW itself to support uniquing.
|
||||
Nodes automatically resolve once all their operands have resolved.
|
||||
|
||||
However, cyclic graphs prevent the nodes from resolving. An API client that
|
||||
constructs a cyclic graph must call ``resolveCycles()`` to resolve nodes in the
|
||||
cycle.
|
||||
|
||||
To save self-references from that burden, self-referencing nodes are implicitly
|
||||
``distinct``. So the following IR:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!named = !{!0, !1, !2, !3, !4}
|
||||
|
||||
!0 = !{!0}
|
||||
!1 = !{!1}
|
||||
!2 = !{!2, !1}
|
||||
!3 = !{!2, !1}
|
||||
!4 = !{!2, !1}
|
||||
|
||||
is equivalent to:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!named = !{!0, !1, !2, !3, !3}
|
||||
|
||||
!0 = distinct !{!0}
|
||||
!1 = distinct !{!1}
|
||||
!2 = distinct !{!2, !1}
|
||||
!3 = !{!2, !1}
|
||||
|
||||
MDLocation (aka DebugLoc aka DILocation)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There's a new first-class metadata construct called ``MDLocation`` (to be
|
||||
followed in subsequent releases by others). It's used for the locations
|
||||
referenced by ``!dbg`` metadata attachments.
|
||||
|
||||
For example, if an old ``!dbg`` attachment looked like this:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%add = add i32 %a, %b, !dbg !0
|
||||
ret %add, !dbg !1
|
||||
}
|
||||
|
||||
!0 = metadata !{i32 10, i32 3, metadata !2, metadata !1)
|
||||
!1 = metadata !{i32 20, i32 7, metadata !3)
|
||||
!2 = metadata !{...}
|
||||
!3 = metadata !{...}
|
||||
|
||||
the new attachment looks like this:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%add = add i32 %a, %b, !dbg !0
|
||||
ret %add, !dbg !1
|
||||
}
|
||||
|
||||
!0 = !MDLocation(line: 10, column: 3, scope: !2, inlinedAt: !1)
|
||||
!1 = !MDLocation(line: 20, column: 7, scope: !3)
|
||||
!2 = !{...}
|
||||
!3 = !{...}
|
||||
|
||||
The fields are named, can be reordered, and have sane defaults if left out
|
||||
(although ``scope:`` is required).
|
||||
|
||||
|
||||
Alias syntax change
|
||||
-----------------------
|
||||
|
||||
The syntax for aliases is now closer to what is used for global variables
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
@a = weak global ...
|
||||
@b = weak alias ...
|
||||
|
||||
The order of the ``alias`` keyword and the linkage was swapped before.
|
||||
|
||||
The old JIT has been removed
|
||||
----------------------------
|
||||
|
||||
All users should transition to MCJIT.
|
||||
|
||||
|
||||
object::Binary doesn't own the file buffer
|
||||
-------------------------------------------
|
||||
|
||||
It is now just a wrapper, which simplifies using object::Binary with other
|
||||
users of the underlying file.
|
||||
|
||||
|
||||
IR in object files is now supported
|
||||
-----------------------------------
|
||||
|
||||
Regular object files can contain IR in a section named ``.llvmbc``.
|
||||
|
||||
|
||||
The gold plugin has been rewritten
|
||||
----------------------------------
|
||||
|
||||
It is now implemented directly on top of lib/Linker instead of ``lib/LTO``.
|
||||
The API of ``lib/LTO`` is sufficiently different from gold's view of the
|
||||
linking process that some cases could not be conveniently implemented.
|
||||
|
||||
The new implementation is also lazier and has a ``save-temps`` option.
|
||||
|
||||
|
||||
Change in the representation of lazy loaded funcs
|
||||
-------------------------------------------------
|
||||
|
||||
Lazy loaded functions are now represented in a way that ``isDeclaration``
|
||||
returns the correct answer even before reading the body.
|
||||
|
||||
|
||||
The opt option -std-compile-opts was removed
|
||||
--------------------------------------------
|
||||
|
||||
It was effectively an alias of -O3.
|
||||
|
||||
|
||||
Python 2.7 is now required
|
||||
Changes to the ARM Backend
|
||||
--------------------------
|
||||
|
||||
This was done to simplify compatibility with python 3.
|
||||
|
||||
|
||||
The leak detector has been removed
|
||||
----------------------------------
|
||||
|
||||
In practice, tools like asan and valgrind were finding way more bugs than
|
||||
the old leak detector, so it was removed.
|
||||
|
||||
|
||||
New comdat syntax
|
||||
-----------------
|
||||
|
||||
The syntax of comdats was changed to
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
$c = comdat any
|
||||
@g = global i32 0, comdat($c)
|
||||
@c = global i32 0, comdat
|
||||
|
||||
The version without the parentheses is a syntactic sugar for a comdat with
|
||||
the same name as the global.
|
||||
|
||||
|
||||
Added support for Win64 unwind information
|
||||
------------------------------------------
|
||||
|
||||
LLVM now obeys the `Win64 prologue and epilogue conventions
|
||||
<https://msdn.microsoft.com/en-us/library/tawsa7cb.aspx>`_ documented by
|
||||
Microsoft. Unwind information is also emitted into the .xdata section.
|
||||
|
||||
As a result of the ABI-required prologue changes, it is now no longer possible
|
||||
to unwind the stack using a standard frame pointer walk on Win64. Instead,
|
||||
users should call ``CaptureStackBackTrace``, or implement equivalent
|
||||
functionality by consulting the unwind tables present in the binary.
|
||||
|
||||
|
||||
Diagnostic infrastructure used by lib/Linker and lib/Bitcode
|
||||
------------------------------------------------------------
|
||||
|
||||
These libraries now use the diagnostic handler to print errors and warnings.
|
||||
This provides better error messages and simpler error handling.
|
||||
|
||||
|
||||
The PreserveSource linker mode was removed
|
||||
------------------------------------------
|
||||
|
||||
It was fairly broken and was removed.
|
||||
|
||||
The mode is currently still available in the C API for source
|
||||
compatibility, but it doesn't have any effect.
|
||||
|
||||
|
||||
Garbage Collection
|
||||
------------------
|
||||
A new experimental mechanism for describing a garbage collection safepoint was
|
||||
added to LLVM. The new mechanism was not complete at the point this release
|
||||
was branched so it is recommended that anyone interested in using this
|
||||
mechanism track the ongoing development work on tip of tree. The hope is that
|
||||
these intrinsics will be ready for general use by 3.7. Documentation can be
|
||||
found `here <http://llvm.org/docs/Statepoints.html>`_.
|
||||
|
||||
The existing gc.root implementation is still supported and as fully featured
|
||||
as it ever was. However, two features from GCStrategy will likely be removed
|
||||
in the 3.7 release (performCustomLowering and findCustomSafePoints). If you
|
||||
have a use case for either, please mention it on llvm-dev so that it can be
|
||||
considered for future development.
|
||||
|
||||
We are expecting to migrate away from gc.root in the 3.8 time frame,
|
||||
but both mechanisms will be supported in 3.7.
|
||||
During this release ...
|
||||
|
||||
|
||||
Changes to the MIPS Target
|
||||
--------------------------
|
||||
|
||||
During this release the MIPS target has reached a few major milestones. The
|
||||
compiler has gained support for MIPS-II and MIPS-III; become ABI-compatible
|
||||
with GCC for big and little endian O32, N32, and N64; and is now able to
|
||||
compile the Linux kernel for 32-bit targets. Additionally, LLD now supports
|
||||
microMIPS for the O32 ABI on little endian targets, and code generation for
|
||||
microMIPS is almost completely passing the test-suite.
|
||||
|
||||
|
||||
ABI
|
||||
^^^
|
||||
|
||||
A large number of bugs have been fixed for big-endian MIPS targets using the
|
||||
N32 and N64 ABI's as well as a small number of bugs affecting other ABI's.
|
||||
Please note that some of these bugs will still affect LLVM-IR generated by
|
||||
LLVM 3.5 since correct code generation depends on appropriate usage of the
|
||||
``inreg``, ``signext``, and ``zeroext`` attributes on all function arguments
|
||||
and returns.
|
||||
|
||||
There are far too many corrections to provide a complete list but here are a
|
||||
few notable ones:
|
||||
|
||||
* Big-endian N32 and N64 now interlinks successfully with GCC compiled code.
|
||||
Previously this didn't work for the majority of cases.
|
||||
|
||||
* The registers used to return a structure containing a single 128-bit floating
|
||||
point member on the N32/N64 ABI's have been changed from those specified by
|
||||
the ABI documentation to match those used by GCC. The documentation specifies
|
||||
that ``$f0`` and ``$f2`` should be used but GCC has used ``$f0`` and ``$f1``
|
||||
for many years.
|
||||
|
||||
* Returning a zero-byte struct no longer causes arguments to be read from the
|
||||
wrong registers when using the O32 ABI.
|
||||
|
||||
* The exception personality has been changed for 64-bit MIPS targets to
|
||||
eliminate warnings about relocations in a read-only section.
|
||||
|
||||
* Incorrect usage of odd-numbered single-precision floating point registers
|
||||
has been fixed when the fastcc calling convention is used with 64-bit FPU's
|
||||
and -mno-odd-spreg.
|
||||
|
||||
|
||||
LLVMLinux
|
||||
^^^^^^^^^
|
||||
|
||||
It is now possible to compile the Linux kernel. This currently requires a small
|
||||
number of kernel patches. See the `LLVMLinux project
|
||||
<http://llvm.linuxfoundation.org/index.php/Main_Page>`_ for details.
|
||||
|
||||
* Added -mabicalls and -mno-abicalls. The implementation may not be complete
|
||||
but works sufficiently well for the Linux kernel.
|
||||
|
||||
* Fixed multiple compatibility issues between LLVM's inline assembly support
|
||||
and GCC's.
|
||||
|
||||
* Added support for a number of directives used by Linux to the Integrated
|
||||
Assembler.
|
||||
|
||||
|
||||
Miscellaneous
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
* Attempting to disassemble l[wd]c[23], s[wd]c[23], cache, and pref no longer
|
||||
triggers an assertion.
|
||||
|
||||
* Added -muclibc and -mglibc to support toolchains that provide both uClibC and
|
||||
GLibC.
|
||||
|
||||
* __SIZEOF_INT128__ is no longer defined for 64-bit targets since 128-bit
|
||||
integers do not work at this time for this target.
|
||||
|
||||
* Using $t4-$t7 with the N32 and N64 ABI is deprecated when ``-fintegrated-as``
|
||||
is in use and will be removed in LLVM 3.7. These names have never been
|
||||
supported by the GNU Assembler for these ABI's.
|
||||
During this release ...
|
||||
|
||||
|
||||
Changes to the PowerPC Target
|
||||
-----------------------------
|
||||
|
||||
There are numerous improvements to the PowerPC target in this release:
|
||||
|
||||
* LLVM now generates the Vector-Scalar eXtension (VSX) instructions from
|
||||
version 2.06 of the Power ISA, for both big- and little-endian targets.
|
||||
|
||||
* LLVM now has a POWER8 instruction scheduling description.
|
||||
|
||||
* AddressSanitizer (ASan) support is now fully functional.
|
||||
|
||||
* Performance of simple atomic accesses has been greatly improved.
|
||||
|
||||
* Atomic fences now use light-weight syncs where possible, again providing
|
||||
significant performance benefit.
|
||||
|
||||
* The PowerPC target now supports PIC levels (-fPIC vs. -fpic).
|
||||
|
||||
* PPC32 SVR4 now supports small-model PIC.
|
||||
|
||||
* Experimental support for the stackmap/patchpoint intrinsics has been added.
|
||||
|
||||
* There have been many smaller bug fixes and performance improvements.
|
||||
During this release ...
|
||||
|
||||
|
||||
Changes to the OCaml bindings
|
||||
-----------------------------
|
||||
|
||||
* The bindings now require OCaml >=4.00.0, ocamlfind,
|
||||
ctypes >=0.3.0 <0.4 and OUnit 2 if tests are enabled.
|
||||
|
||||
* The bindings can now be built using cmake as well as autoconf.
|
||||
|
||||
* LLVM 3.5 has, unfortunately, shipped a broken Llvm_executionengine
|
||||
implementation. In LLVM 3.6, the bindings now fully support MCJIT,
|
||||
however the interface is reworked from scratch using ctypes
|
||||
and is not backwards compatible.
|
||||
|
||||
* Llvm_linker.Mode was removed following the changes in LLVM.
|
||||
This breaks the interface of Llvm_linker.
|
||||
|
||||
* All combinations of ocamlc/ocamlc -custom/ocamlopt and shared/static
|
||||
builds of LLVM are now supported.
|
||||
|
||||
* Absolute paths are not embedded into the OCaml libraries anymore.
|
||||
Either OCaml >=4.02.2 must be used, which includes an rpath-like $ORIGIN
|
||||
mechanism, or META file must be updated for out-of-tree installations;
|
||||
see r221139.
|
||||
|
||||
* As usual, many more functions have been exposed to OCaml.
|
||||
During this release ...
|
||||
|
||||
|
||||
Go bindings
|
||||
-----------
|
||||
|
||||
* A set of Go bindings based on `gollvm <https://github.com/go-llvm/llvm>`_
|
||||
was introduced in this release.
|
||||
|
||||
|
||||
External Open Source Projects Using LLVM 3.6
|
||||
External Open Source Projects Using LLVM 3.7
|
||||
============================================
|
||||
|
||||
An exciting aspect of LLVM is that it is used as an enabling technology for
|
||||
a lot of other language and tools projects. This section lists some of the
|
||||
projects that have already been updated to work with LLVM 3.6.
|
||||
projects that have already been updated to work with LLVM 3.7.
|
||||
|
||||
|
||||
Portable Computing Language (pocl)
|
||||
----------------------------------
|
||||
|
||||
In addition to producing an easily portable open source OpenCL
|
||||
implementation, another major goal of `pocl <http://portablecl.org/>`_
|
||||
is improving performance portability of OpenCL programs with
|
||||
compiler optimizations, reducing the need for target-dependent manual
|
||||
optimizations. An important part of pocl is a set of LLVM passes used to
|
||||
statically parallelize multiple work-items with the kernel compiler, even in
|
||||
the presence of work-group barriers. This enables static parallelization of
|
||||
the fine-grained static concurrency in the work groups in multiple ways.
|
||||
|
||||
|
||||
TTA-based Co-design Environment (TCE)
|
||||
-------------------------------------
|
||||
|
||||
`TCE <http://tce.cs.tut.fi/>`_ is a toolset for designing customized
|
||||
exposed datapath processors based on the Transport triggered
|
||||
architecture (TTA).
|
||||
|
||||
The toolset provides a complete co-design flow from C/C++
|
||||
programs down to synthesizable VHDL/Verilog and parallel program binaries.
|
||||
Processor customization points include the register files, function units,
|
||||
supported operations, and the interconnection network.
|
||||
|
||||
TCE uses Clang and LLVM for C/C++/OpenCL C language support, target independent
|
||||
optimizations and also for parts of code generation. It generates
|
||||
new LLVM-based code generators "on the fly" for the designed processors and
|
||||
loads them in to the compiler backend as runtime libraries to avoid
|
||||
per-target recompilation of larger parts of the compiler chain.
|
||||
|
||||
|
||||
Likely
|
||||
------
|
||||
|
||||
`Likely <http://www.liblikely.org>`_ is an embeddable just-in-time Lisp for
|
||||
image recognition and heterogeneous computing. Algorithms are just-in-time
|
||||
compiled using LLVM's MCJIT infrastructure to execute on single or
|
||||
multi-threaded CPUs and potentially OpenCL SPIR or CUDA enabled GPUs.
|
||||
Likely seeks to explore new optimizations for statistical learning
|
||||
algorithms by moving them from an offline model generation step to the
|
||||
compile-time evaluation of a function (the learning algorithm) with constant
|
||||
arguments (the training data).
|
||||
|
||||
|
||||
LDC - the LLVM-based D compiler
|
||||
-------------------------------
|
||||
|
||||
`D <http://dlang.org>`_ is a language with C-like syntax and static typing. It
|
||||
pragmatically combines efficiency, control, and modeling power, with safety and
|
||||
programmer productivity. D supports powerful concepts like Compile-Time Function
|
||||
Execution (CTFE) and Template Meta-Programming, provides an innovative approach
|
||||
to concurrency and offers many classical paradigms.
|
||||
|
||||
`LDC <http://wiki.dlang.org/LDC>`_ uses the frontend from the reference compiler
|
||||
combined with LLVM as backend to produce efficient native code. LDC targets
|
||||
x86/x86_64 systems like Linux, OS X, FreeBSD and Windows and also Linux on
|
||||
PowerPC (32/64 bit). Ports to other architectures like ARM, AArch64 and MIPS64
|
||||
are underway.
|
||||
|
||||
|
||||
LLVMSharp & ClangSharp
|
||||
----------------------
|
||||
|
||||
`LLVMSharp <http://www.llvmsharp.org>`_ and
|
||||
`ClangSharp <http://www.clangsharp.org>`_ are type-safe C# bindings for
|
||||
Microsoft.NET and Mono that Platform Invoke into the native libraries.
|
||||
ClangSharp is self-hosted and is used to generated LLVMSharp using the
|
||||
LLVM-C API.
|
||||
|
||||
`LLVMSharp Kaleidoscope Tutorials <http://www.llvmsharp.org/Kaleidoscope/>`_
|
||||
are instructive examples of writing a compiler in C#, with certain improvements
|
||||
like using the visitor pattern to generate LLVM IR.
|
||||
|
||||
`ClangSharp PInvoke Generator <http://www.clangsharp.org/PInvoke/>`_ is the
|
||||
self-hosting mechanism for LLVM/ClangSharp and is demonstrative of using
|
||||
LibClang to generate Platform Invoke (PInvoke) signatures for C APIs.
|
||||
* A project
|
||||
|
||||
|
||||
Additional Information
|
||||
|
@ -153,487 +153,21 @@ debugger to interpret the information.
|
||||
To provide basic functionality, the LLVM debugger does have to make some
|
||||
assumptions about the source-level language being debugged, though it keeps
|
||||
these to a minimum. The only common features that the LLVM debugger assumes
|
||||
exist are :ref:`source files <format_files>`, and :ref:`program objects
|
||||
<format_global_variables>`. These abstract objects are used by a debugger to
|
||||
form stack traces, show information about local variables, etc.
|
||||
exist are `source files <LangRef.html#difile>`_, and `program objects
|
||||
<LangRef.html#diglobalvariable>`_. These abstract objects are used by a
|
||||
debugger to form stack traces, show information about local variables, etc.
|
||||
|
||||
This section of the documentation first describes the representation aspects
|
||||
common to any source-language. :ref:`ccxx_frontend` describes the data layout
|
||||
conventions used by the C and C++ front-ends.
|
||||
|
||||
Debug information descriptors
|
||||
-----------------------------
|
||||
|
||||
In consideration of the complexity and volume of debug information, LLVM
|
||||
provides a specification for well formed debug descriptors.
|
||||
|
||||
Consumers of LLVM debug information expect the descriptors for program objects
|
||||
to start in a canonical format, but the descriptors can include additional
|
||||
information appended at the end that is source-language specific. All debugging
|
||||
information objects start with a tag to indicate what type of object it is.
|
||||
The source-language is allowed to define its own objects, by using unreserved
|
||||
tag numbers. We recommend using with tags in the range 0x1000 through 0x2000
|
||||
(there is a defined ``enum DW_TAG_user_base = 0x1000``.)
|
||||
|
||||
The fields of debug descriptors used internally by LLVM are restricted to only
|
||||
the simple data types ``i32``, ``i1``, ``float``, ``double``, ``mdstring`` and
|
||||
``mdnode``.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!1 = metadata !{
|
||||
i32, ;; A tag
|
||||
...
|
||||
}
|
||||
|
||||
Most of the string and integer fields in descriptors are packed into a single,
|
||||
null-separated ``mdstring``. The first field of the header is always an
|
||||
``i32`` containing the DWARF tag value identifying the content of the
|
||||
descriptor.
|
||||
|
||||
For clarity of definition in this document, these header fields are described
|
||||
below split inside an imaginary ``DIHeader`` construct. This is invalid
|
||||
assembly syntax. In valid IR, these fields are stringified and concatenated,
|
||||
separated by ``\00``.
|
||||
|
||||
The details of the various descriptors follow.
|
||||
|
||||
Compile unit descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!0 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag = 17 (DW_TAG_compile_unit)
|
||||
i32, ;; DWARF language identifier (ex. DW_LANG_C89)
|
||||
mdstring, ;; Producer (ex. "4.0.1 LLVM (LLVM research group)")
|
||||
i1, ;; True if this is optimized.
|
||||
mdstring, ;; Flags
|
||||
i32, ;; Runtime version
|
||||
mdstring, ;; Split debug filename
|
||||
i32 ;; Debug info emission kind (1 = Full Debug Info, 2 = Line Tables Only)
|
||||
),
|
||||
metadata, ;; Source directory (including trailing slash) & file pair
|
||||
metadata, ;; List of enums types
|
||||
metadata, ;; List of retained types
|
||||
metadata, ;; List of subprograms
|
||||
metadata, ;; List of global variables
|
||||
metadata ;; List of imported entities
|
||||
}
|
||||
|
||||
These descriptors contain a source language ID for the file (we use the DWARF
|
||||
3.0 ID numbers, such as ``DW_LANG_C89``, ``DW_LANG_C_plus_plus``,
|
||||
``DW_LANG_Cobol74``, etc), a reference to a metadata node containing a pair of
|
||||
strings for the source file name and the working directory, as well as an
|
||||
identifier string for the compiler that produced it.
|
||||
|
||||
Compile unit descriptors provide the root context for objects declared in a
|
||||
specific compilation unit. File descriptors are defined using this context.
|
||||
These descriptors are collected by a named metadata ``!llvm.dbg.cu``. They
|
||||
keep track of subprograms, global variables, type information, and imported
|
||||
entities (declarations and namespaces).
|
||||
|
||||
.. _format_files:
|
||||
|
||||
File descriptors
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!0 = metadata !{
|
||||
DIHeader(
|
||||
i32 ;; Tag = 41 (DW_TAG_file_type)
|
||||
),
|
||||
metadata ;; Source directory (including trailing slash) & file pair
|
||||
}
|
||||
|
||||
These descriptors contain information for a file. Global variables and top
|
||||
level functions would be defined using this context. File descriptors also
|
||||
provide context for source line correspondence.
|
||||
|
||||
Each input file is encoded as a separate file descriptor in LLVM debugging
|
||||
information output.
|
||||
|
||||
.. _format_global_variables:
|
||||
|
||||
Global variable descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!1 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag = 52 (DW_TAG_variable)
|
||||
mdstring, ;; Name
|
||||
mdstring, ;; Display name (fully qualified C++ name)
|
||||
mdstring, ;; MIPS linkage name (for C++)
|
||||
i32, ;; Line number where defined
|
||||
i1, ;; True if the global is local to compile unit (static)
|
||||
i1 ;; True if the global is defined in the compile unit (not extern)
|
||||
),
|
||||
metadata, ;; Reference to context descriptor
|
||||
metadata, ;; Reference to file where defined
|
||||
metadata, ;; Reference to type descriptor
|
||||
{}*, ;; Reference to the global variable
|
||||
metadata, ;; The static member declaration, if any
|
||||
}
|
||||
|
||||
These descriptors provide debug information about global variables. They
|
||||
provide details such as name, type and where the variable is defined. All
|
||||
global variables are collected inside the named metadata ``!llvm.dbg.cu``.
|
||||
|
||||
.. _format_subprograms:
|
||||
|
||||
Subprogram descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!2 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag = 46 (DW_TAG_subprogram)
|
||||
mdstring, ;; Name
|
||||
mdstring, ;; Display name (fully qualified C++ name)
|
||||
mdstring, ;; MIPS linkage name (for C++)
|
||||
i32, ;; Line number where defined
|
||||
i1, ;; True if the global is local to compile unit (static)
|
||||
i1, ;; True if the global is defined in the compile unit (not extern)
|
||||
i32, ;; Virtuality, e.g. dwarf::DW_VIRTUALITY__virtual
|
||||
i32, ;; Index into a virtual function
|
||||
i32, ;; Flags - Artificial, Private, Protected, Explicit, Prototyped.
|
||||
i1, ;; isOptimized
|
||||
i32 ;; Line number where the scope of the subprogram begins
|
||||
),
|
||||
metadata, ;; Source directory (including trailing slash) & file pair
|
||||
metadata, ;; Reference to context descriptor
|
||||
metadata, ;; Reference to type descriptor
|
||||
metadata, ;; indicates which base type contains the vtable pointer for the
|
||||
;; derived class
|
||||
{}*, ;; Reference to the LLVM function
|
||||
metadata, ;; Lists function template parameters
|
||||
metadata, ;; Function declaration descriptor
|
||||
metadata ;; List of function variables
|
||||
}
|
||||
|
||||
These descriptors provide debug information about functions, methods and
|
||||
subprograms. They provide details such as name, return types and the source
|
||||
location where the subprogram is defined.
|
||||
|
||||
Block descriptors
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!3 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag = 11 (DW_TAG_lexical_block)
|
||||
i32, ;; Line number
|
||||
i32, ;; Column number
|
||||
i32 ;; Unique ID to identify blocks from a template function
|
||||
),
|
||||
metadata, ;; Source directory (including trailing slash) & file pair
|
||||
metadata ;; Reference to context descriptor
|
||||
}
|
||||
|
||||
This descriptor provides debug information about nested blocks within a
|
||||
subprogram. The line number and column numbers are used to dinstinguish two
|
||||
lexical blocks at same depth.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!3 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag = 11 (DW_TAG_lexical_block)
|
||||
i32 ;; DWARF path discriminator value
|
||||
),
|
||||
metadata, ;; Source directory (including trailing slash) & file pair
|
||||
metadata ;; Reference to the scope we're annotating with a file change
|
||||
}
|
||||
|
||||
This descriptor provides a wrapper around a lexical scope to handle file
|
||||
changes in the middle of a lexical block.
|
||||
|
||||
.. _format_basic_type:
|
||||
|
||||
Basic type descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!4 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag = 36 (DW_TAG_base_type)
|
||||
mdstring, ;; Name (may be "" for anonymous types)
|
||||
i32, ;; Line number where defined (may be 0)
|
||||
i64, ;; Size in bits
|
||||
i64, ;; Alignment in bits
|
||||
i64, ;; Offset in bits
|
||||
i32, ;; Flags
|
||||
i32 ;; DWARF type encoding
|
||||
),
|
||||
metadata, ;; Source directory (including trailing slash) & file pair (may be null)
|
||||
metadata ;; Reference to context
|
||||
}
|
||||
|
||||
These descriptors define primitive types used in the code. Example ``int``,
|
||||
``bool`` and ``float``. The context provides the scope of the type, which is
|
||||
usually the top level. Since basic types are not usually user defined the
|
||||
context and line number can be left as NULL and 0. The size, alignment and
|
||||
offset are expressed in bits and can be 64 bit values. The alignment is used
|
||||
to round the offset when embedded in a :ref:`composite type
|
||||
<format_composite_type>` (example to keep float doubles on 64 bit boundaries).
|
||||
The offset is the bit offset if embedded in a :ref:`composite type
|
||||
<format_composite_type>`.
|
||||
|
||||
The type encoding provides the details of the type. The values are typically
|
||||
one of the following:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
DW_ATE_address = 1
|
||||
DW_ATE_boolean = 2
|
||||
DW_ATE_float = 4
|
||||
DW_ATE_signed = 5
|
||||
DW_ATE_signed_char = 6
|
||||
DW_ATE_unsigned = 7
|
||||
DW_ATE_unsigned_char = 8
|
||||
|
||||
.. _format_derived_type:
|
||||
|
||||
Derived type descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!5 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag (see below)
|
||||
mdstring, ;; Name (may be "" for anonymous types)
|
||||
i32, ;; Line number where defined (may be 0)
|
||||
i64, ;; Size in bits
|
||||
i64, ;; Alignment in bits
|
||||
i64, ;; Offset in bits
|
||||
i32 ;; Flags to encode attributes, e.g. private
|
||||
),
|
||||
metadata, ;; Source directory (including trailing slash) & file pair (may be null)
|
||||
metadata, ;; Reference to context
|
||||
metadata, ;; Reference to type derived from
|
||||
metadata ;; (optional) Objective C property node
|
||||
}
|
||||
|
||||
These descriptors are used to define types derived from other types. The value
|
||||
of the tag varies depending on the meaning. The following are possible tag
|
||||
values:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
DW_TAG_formal_parameter = 5
|
||||
DW_TAG_member = 13
|
||||
DW_TAG_pointer_type = 15
|
||||
DW_TAG_reference_type = 16
|
||||
DW_TAG_typedef = 22
|
||||
DW_TAG_ptr_to_member_type = 31
|
||||
DW_TAG_const_type = 38
|
||||
DW_TAG_volatile_type = 53
|
||||
DW_TAG_restrict_type = 55
|
||||
|
||||
``DW_TAG_member`` is used to define a member of a :ref:`composite type
|
||||
<format_composite_type>` or :ref:`subprogram <format_subprograms>`. The type
|
||||
of the member is the :ref:`derived type <format_derived_type>`.
|
||||
``DW_TAG_formal_parameter`` is used to define a member which is a formal
|
||||
argument of a subprogram.
|
||||
|
||||
``DW_TAG_typedef`` is used to provide a name for the derived type.
|
||||
|
||||
``DW_TAG_pointer_type``, ``DW_TAG_reference_type``, ``DW_TAG_const_type``,
|
||||
``DW_TAG_volatile_type`` and ``DW_TAG_restrict_type`` are used to qualify the
|
||||
:ref:`derived type <format_derived_type>`.
|
||||
|
||||
:ref:`Derived type <format_derived_type>` location can be determined from the
|
||||
context and line number. The size, alignment and offset are expressed in bits
|
||||
and can be 64 bit values. The alignment is used to round the offset when
|
||||
embedded in a :ref:`composite type <format_composite_type>` (example to keep
|
||||
float doubles on 64 bit boundaries.) The offset is the bit offset if embedded
|
||||
in a :ref:`composite type <format_composite_type>`.
|
||||
|
||||
Note that the ``void *`` type is expressed as a type derived from NULL.
|
||||
|
||||
.. _format_composite_type:
|
||||
|
||||
Composite type descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!6 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag (see below)
|
||||
mdstring, ;; Name (may be "" for anonymous types)
|
||||
i32, ;; Line number where defined (may be 0)
|
||||
i64, ;; Size in bits
|
||||
i64, ;; Alignment in bits
|
||||
i64, ;; Offset in bits
|
||||
i32, ;; Flags
|
||||
i32 ;; Runtime languages
|
||||
),
|
||||
metadata, ;; Source directory (including trailing slash) & file pair (may be null)
|
||||
metadata, ;; Reference to context
|
||||
metadata, ;; Reference to type derived from
|
||||
metadata, ;; Reference to array of member descriptors
|
||||
metadata, ;; Base type containing the vtable pointer for this type
|
||||
metadata, ;; Template parameters
|
||||
mdstring ;; A unique identifier for type uniquing purpose (may be null)
|
||||
}
|
||||
|
||||
These descriptors are used to define types that are composed of 0 or more
|
||||
elements. The value of the tag varies depending on the meaning. The following
|
||||
are possible tag values:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
DW_TAG_array_type = 1
|
||||
DW_TAG_enumeration_type = 4
|
||||
DW_TAG_structure_type = 19
|
||||
DW_TAG_union_type = 23
|
||||
DW_TAG_subroutine_type = 21
|
||||
DW_TAG_inheritance = 28
|
||||
|
||||
The vector flag indicates that an array type is a native packed vector.
|
||||
|
||||
The members of array types (tag = ``DW_TAG_array_type``) are
|
||||
:ref:`subrange descriptors <format_subrange>`, each
|
||||
representing the range of subscripts at that level of indexing.
|
||||
|
||||
The members of enumeration types (tag = ``DW_TAG_enumeration_type``) are
|
||||
:ref:`enumerator descriptors <format_enumerator>`, each representing the
|
||||
definition of enumeration value for the set. All enumeration type descriptors
|
||||
are collected inside the named metadata ``!llvm.dbg.cu``.
|
||||
|
||||
The members of structure (tag = ``DW_TAG_structure_type``) or union (tag =
|
||||
``DW_TAG_union_type``) types are any one of the :ref:`basic
|
||||
<format_basic_type>`, :ref:`derived <format_derived_type>` or :ref:`composite
|
||||
<format_composite_type>` type descriptors, each representing a field member of
|
||||
the structure or union.
|
||||
|
||||
For C++ classes (tag = ``DW_TAG_structure_type``), member descriptors provide
|
||||
information about base classes, static members and member functions. If a
|
||||
member is a :ref:`derived type descriptor <format_derived_type>` and has a tag
|
||||
of ``DW_TAG_inheritance``, then the type represents a base class. If the member
|
||||
of is a :ref:`global variable descriptor <format_global_variables>` then it
|
||||
represents a static member. And, if the member is a :ref:`subprogram
|
||||
descriptor <format_subprograms>` then it represents a member function. For
|
||||
static members and member functions, ``getName()`` returns the members link or
|
||||
the C++ mangled name. ``getDisplayName()`` the simplied version of the name.
|
||||
|
||||
The first member of subroutine (tag = ``DW_TAG_subroutine_type``) type elements
|
||||
is the return type for the subroutine. The remaining elements are the formal
|
||||
arguments to the subroutine.
|
||||
|
||||
:ref:`Composite type <format_composite_type>` location can be determined from
|
||||
the context and line number. The size, alignment and offset are expressed in
|
||||
bits and can be 64 bit values. The alignment is used to round the offset when
|
||||
embedded in a :ref:`composite type <format_composite_type>` (as an example, to
|
||||
keep float doubles on 64 bit boundaries). The offset is the bit offset if
|
||||
embedded in a :ref:`composite type <format_composite_type>`.
|
||||
|
||||
.. _format_subrange:
|
||||
|
||||
Subrange descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!42 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag = 33 (DW_TAG_subrange_type)
|
||||
i64, ;; Low value
|
||||
i64 ;; High value
|
||||
)
|
||||
}
|
||||
|
||||
These descriptors are used to define ranges of array subscripts for an array
|
||||
:ref:`composite type <format_composite_type>`. The low value defines the lower
|
||||
bounds typically zero for C/C++. The high value is the upper bounds. Values
|
||||
are 64 bit. ``High - Low + 1`` is the size of the array. If ``Low > High``
|
||||
the array bounds are not included in generated debugging information.
|
||||
|
||||
.. _format_enumerator:
|
||||
|
||||
Enumerator descriptors
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!6 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag = 40 (DW_TAG_enumerator)
|
||||
mdstring, ;; Name
|
||||
i64 ;; Value
|
||||
)
|
||||
}
|
||||
|
||||
These descriptors are used to define members of an enumeration :ref:`composite
|
||||
type <format_composite_type>`, it associates the name to the value.
|
||||
|
||||
Local variables
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!7 = metadata !{
|
||||
DIHeader(
|
||||
i32, ;; Tag (see below)
|
||||
mdstring, ;; Name
|
||||
i32, ;; 24 bit - Line number where defined
|
||||
;; 8 bit - Argument number. 1 indicates 1st argument.
|
||||
i32 ;; flags
|
||||
),
|
||||
metadata, ;; Context
|
||||
metadata, ;; Reference to file where defined
|
||||
metadata, ;; Reference to the type descriptor
|
||||
metadata ;; (optional) Reference to inline location
|
||||
}
|
||||
|
||||
These descriptors are used to define variables local to a sub program. The
|
||||
value of the tag depends on the usage of the variable:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
DW_TAG_auto_variable = 256
|
||||
DW_TAG_arg_variable = 257
|
||||
|
||||
An auto variable is any variable declared in the body of the function. An
|
||||
argument variable is any variable that appears as a formal argument to the
|
||||
function.
|
||||
|
||||
The context is either the subprogram or block where the variable is defined.
|
||||
Name the source variable name. Context and line indicate where the variable
|
||||
was defined. Type descriptor defines the declared type of the variable.
|
||||
|
||||
Complex Expressions
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
.. code-block:: llvm
|
||||
|
||||
!8 = metadata !{
|
||||
i32, ;; DW_TAG_expression
|
||||
...
|
||||
}
|
||||
|
||||
Complex expressions describe variable storage locations in terms of
|
||||
prefix-notated DWARF expressions. Currently the only supported
|
||||
operators are ``DW_OP_plus``, ``DW_OP_deref``, and ``DW_OP_piece``.
|
||||
|
||||
The ``DW_OP_piece`` operator is used for (typically larger aggregate)
|
||||
variables that are fragmented across several locations. It takes two
|
||||
i32 arguments, an offset and a size in bytes to describe which piece
|
||||
of the variable is at this location.
|
||||
|
||||
Debug information descriptors are `specialized metadata nodes
|
||||
<LangRef.html#specialized-metadata>`_, first-class subclasses of ``Metadata``.
|
||||
|
||||
.. _format_common_intrinsics:
|
||||
|
||||
Debugger intrinsic functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
----------------------------
|
||||
|
||||
LLVM uses several intrinsic functions (name prefixed with "``llvm.dbg``") to
|
||||
provide debug information at various points in generated code.
|
||||
@ -643,24 +177,27 @@ provide debug information at various points in generated code.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
void %llvm.dbg.declare(metadata, metadata)
|
||||
void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
This intrinsic provides information about a local element (e.g., variable).
|
||||
The first argument is metadata holding the alloca for the variable. The second
|
||||
argument is metadata containing a description of the variable.
|
||||
argument is a `local variable <LangRef.html#dilocalvariable>`_ containing a
|
||||
description of the variable. The third argument is a `complex expression
|
||||
<LangRef.html#diexpression>`_.
|
||||
|
||||
``llvm.dbg.value``
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
void %llvm.dbg.value(metadata, i64, metadata)
|
||||
void @llvm.dbg.value(metadata, i64, metadata, metadata)
|
||||
|
||||
This intrinsic provides information when a user source variable is set to a new
|
||||
value. The first argument is the new value (wrapped as metadata). The second
|
||||
argument is the offset in the user source variable where the new value is
|
||||
written. The third argument is metadata containing a description of the user
|
||||
source variable.
|
||||
written. The third argument is a `local variable
|
||||
<LangRef.html#dilocalvariable>`_ containing a description of the variable. The
|
||||
third argument is a `complex expression <LangRef.html#diexpression>`_.
|
||||
|
||||
Object lifetimes and scoping
|
||||
============================
|
||||
@ -693,86 +230,61 @@ Compiled to LLVM, this function would be represented like this:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
; Function Attrs: nounwind ssp uwtable
|
||||
define void @foo() #0 {
|
||||
entry:
|
||||
%X = alloca i32, align 4
|
||||
%X = alloca i32, align 4
|
||||
%Y = alloca i32, align 4
|
||||
%Z = alloca i32, align 4
|
||||
call void @llvm.dbg.declare(metadata !{i32* %X}, metadata !10), !dbg !12
|
||||
; [debug line = 2:7] [debug variable = X]
|
||||
store i32 21, i32* %X, align 4, !dbg !12
|
||||
call void @llvm.dbg.declare(metadata !{i32* %Y}, metadata !13), !dbg !14
|
||||
; [debug line = 3:7] [debug variable = Y]
|
||||
store i32 22, i32* %Y, align 4, !dbg !14
|
||||
call void @llvm.dbg.declare(metadata !{i32* %Z}, metadata !15), !dbg !17
|
||||
; [debug line = 5:9] [debug variable = Z]
|
||||
store i32 23, i32* %Z, align 4, !dbg !17
|
||||
%0 = load i32* %X, align 4, !dbg !18
|
||||
[debug line = 6:5]
|
||||
store i32 %0, i32* %Z, align 4, !dbg !18
|
||||
%1 = load i32* %Y, align 4, !dbg !19
|
||||
[debug line = 8:3]
|
||||
store i32 %1, i32* %X, align 4, !dbg !19
|
||||
ret void, !dbg !20
|
||||
call void @llvm.dbg.declare(metadata i32* %X, metadata !11, metadata !13), !dbg !14
|
||||
store i32 21, i32* %X, align 4, !dbg !14
|
||||
call void @llvm.dbg.declare(metadata i32* %Y, metadata !15, metadata !13), !dbg !16
|
||||
store i32 22, i32* %Y, align 4, !dbg !16
|
||||
call void @llvm.dbg.declare(metadata i32* %Z, metadata !17, metadata !13), !dbg !19
|
||||
store i32 23, i32* %Z, align 4, !dbg !19
|
||||
%0 = load i32, i32* %X, align 4, !dbg !20
|
||||
store i32 %0, i32* %Z, align 4, !dbg !21
|
||||
%1 = load i32, i32* %Y, align 4, !dbg !22
|
||||
store i32 %1, i32* %X, align 4, !dbg !23
|
||||
ret void, !dbg !24
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare void @llvm.dbg.declare(metadata, metadata) #1
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
|
||||
|
||||
attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false"
|
||||
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
|
||||
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
|
||||
"stack-protector-buffer-size"="8" "unsafe-fp-math"="false"
|
||||
"use-soft-float"="false" }
|
||||
attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { nounwind readnone }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!8}
|
||||
!llvm.ident = !{!9}
|
||||
!llvm.module.flags = !{!7, !8, !9}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
|
||||
!1 = !DIFile(filename: "/dev/stdin", directory: "/Users/dexonsmith/data/llvm/debug-info")
|
||||
!2 = !{}
|
||||
!3 = !{!4}
|
||||
!4 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, function: void ()* @foo, variables: !2)
|
||||
!5 = !DISubroutineType(types: !6)
|
||||
!6 = !{null}
|
||||
!7 = !{i32 2, !"Dwarf Version", i32 2}
|
||||
!8 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!9 = !{i32 1, !"PIC Level", i32 2}
|
||||
!10 = !{!"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)"}
|
||||
!11 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "X", scope: !4, file: !1, line: 2, type: !12)
|
||||
!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!13 = !DIExpression()
|
||||
!14 = !DILocation(line: 2, column: 9, scope: !4)
|
||||
!15 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "Y", scope: !4, file: !1, line: 3, type: !12)
|
||||
!16 = !DILocation(line: 3, column: 9, scope: !4)
|
||||
!17 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "Z", scope: !18, file: !1, line: 5, type: !12)
|
||||
!18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
|
||||
!19 = !DILocation(line: 5, column: 11, scope: !18)
|
||||
!20 = !DILocation(line: 6, column: 11, scope: !18)
|
||||
!21 = !DILocation(line: 6, column: 9, scope: !18)
|
||||
!22 = !DILocation(line: 8, column: 9, scope: !4)
|
||||
!23 = !DILocation(line: 8, column: 7, scope: !4)
|
||||
!24 = !DILocation(line: 9, column: 3, scope: !4)
|
||||
|
||||
!0 = metadata !{i32 786449, metadata !1, i32 12,
|
||||
metadata !"clang version 3.4 (trunk 193128) (llvm/trunk 193139)",
|
||||
i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3,
|
||||
metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] \
|
||||
[/private/tmp/foo.c] \
|
||||
[DW_LANG_C99]
|
||||
!1 = metadata !{metadata !"t.c", metadata !"/private/tmp"}
|
||||
!2 = metadata !{i32 0}
|
||||
!3 = metadata !{metadata !4}
|
||||
!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo",
|
||||
metadata !"foo", metadata !"", i32 1, metadata !6,
|
||||
i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false,
|
||||
void ()* @foo, null, null, metadata !2, i32 1}
|
||||
; [ DW_TAG_subprogram ] [line 1] [def] [foo]
|
||||
!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] \
|
||||
[/private/tmp/t.c]
|
||||
!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0,
|
||||
i64 0, i32 0, null, metadata !7, i32 0, null, null, null}
|
||||
; [ DW_TAG_subroutine_type ] \
|
||||
[line 0, size 0, align 0, offset 0] [from ]
|
||||
!7 = metadata !{null}
|
||||
!8 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
|
||||
!9 = metadata !{metadata !"clang version 3.4 (trunk 193128) (llvm/trunk 193139)"}
|
||||
!10 = metadata !{i32 786688, metadata !4, metadata !"X", metadata !5, i32 2,
|
||||
metadata !11, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [X] \
|
||||
[line 2]
|
||||
!11 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32,
|
||||
i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] \
|
||||
[line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
|
||||
!12 = metadata !{i32 2, i32 0, metadata !4, null}
|
||||
!13 = metadata !{i32 786688, metadata !4, metadata !"Y", metadata !5, i32 3,
|
||||
metadata !11, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [Y] \
|
||||
[line 3]
|
||||
!14 = metadata !{i32 3, i32 0, metadata !4, null}
|
||||
!15 = metadata !{i32 786688, metadata !16, metadata !"Z", metadata !5, i32 5,
|
||||
metadata !11, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [Z] \
|
||||
[line 5]
|
||||
!16 = metadata !{i32 786443, metadata !1, metadata !4, i32 4, i32 0, i32 0} \
|
||||
; [ DW_TAG_lexical_block ] [/private/tmp/t.c]
|
||||
!17 = metadata !{i32 5, i32 0, metadata !16, null}
|
||||
!18 = metadata !{i32 6, i32 0, metadata !16, null}
|
||||
!19 = metadata !{i32 8, i32 0, metadata !4, null} ; [ DW_TAG_imported_declaration ]
|
||||
!20 = metadata !{i32 9, i32 0, metadata !4, null}
|
||||
|
||||
This example illustrates a few important details about LLVM debugging
|
||||
information. In particular, it shows how the ``llvm.dbg.declare`` intrinsic and
|
||||
@ -782,27 +294,24 @@ variable definitions, and the code used to implement the function.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
call void @llvm.dbg.declare(metadata !{i32* %X}, metadata !10), !dbg !12
|
||||
call void @llvm.dbg.declare(metadata i32* %X, metadata !11, metadata !13), !dbg !14
|
||||
; [debug line = 2:7] [debug variable = X]
|
||||
|
||||
The first intrinsic ``%llvm.dbg.declare`` encodes debugging information for the
|
||||
variable ``X``. The metadata ``!dbg !12`` attached to the intrinsic provides
|
||||
variable ``X``. The metadata ``!dbg !14`` attached to the intrinsic provides
|
||||
scope information for the variable ``X``.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!12 = metadata !{i32 2, i32 0, metadata !4, null}
|
||||
!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo",
|
||||
metadata !"foo", metadata !"", i32 1, metadata !6,
|
||||
i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false,
|
||||
void ()* @foo, null, null, metadata !2, i32 1}
|
||||
; [ DW_TAG_subprogram ] [line 1] [def] [foo]
|
||||
!14 = !DILocation(line: 2, column: 9, scope: !4)
|
||||
!4 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5,
|
||||
isLocal: false, isDefinition: true, scopeLine: 1,
|
||||
isOptimized: false, function: void ()* @foo,
|
||||
variables: !2)
|
||||
|
||||
Here ``!12`` is metadata providing location information. It has four fields:
|
||||
line number, column number, scope, and original scope. The original scope
|
||||
represents inline location if this instruction is inlined inside a caller, and
|
||||
is null otherwise. In this example, scope is encoded by ``!4``, a
|
||||
:ref:`subprogram descriptor <format_subprograms>`. This way the location
|
||||
Here ``!14`` is metadata providing `location information
|
||||
<LangRef.html#dilocation>`_. In this example, scope is encoded by ``!4``, a
|
||||
`subprogram descriptor <LangRef.html#disubprogram>`_. This way the location
|
||||
information attached to the intrinsics indicates that the variable ``X`` is
|
||||
declared at line number 2 at a function level scope in function ``foo``.
|
||||
|
||||
@ -810,22 +319,21 @@ Now lets take another example.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
call void @llvm.dbg.declare(metadata !{i32* %Z}, metadata !15), !dbg !17
|
||||
call void @llvm.dbg.declare(metadata i32* %Z, metadata !17, metadata !13), !dbg !19
|
||||
; [debug line = 5:9] [debug variable = Z]
|
||||
|
||||
The third intrinsic ``%llvm.dbg.declare`` encodes debugging information for
|
||||
variable ``Z``. The metadata ``!dbg !17`` attached to the intrinsic provides
|
||||
variable ``Z``. The metadata ``!dbg !19`` attached to the intrinsic provides
|
||||
scope information for the variable ``Z``.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!16 = metadata !{i32 786443, metadata !1, metadata !4, i32 4, i32 0, i32 0} \
|
||||
; [ DW_TAG_lexical_block ] [/private/tmp/t.c]
|
||||
!17 = metadata !{i32 5, i32 0, metadata !16, null}
|
||||
!18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
|
||||
!19 = !DILocation(line: 5, column: 11, scope: !18)
|
||||
|
||||
Here ``!15`` indicates that ``Z`` is declared at line number 5 and
|
||||
column number 0 inside of lexical scope ``!16``. The lexical scope itself
|
||||
resides inside of subprogram ``!4`` described above.
|
||||
Here ``!19`` indicates that ``Z`` is declared at line number 5 and column
|
||||
number 0 inside of lexical scope ``!18``. The lexical scope itself resides
|
||||
inside of subprogram ``!4`` described above.
|
||||
|
||||
The scope information attached with each instruction provides a straightforward
|
||||
way to find instructions covered by a scope.
|
||||
@ -888,98 +396,52 @@ a C/C++ front-end would generate the following descriptors:
|
||||
;; Define the global itself.
|
||||
;;
|
||||
@MyGlobal = global i32 100, align 4
|
||||
...
|
||||
|
||||
;;
|
||||
;; List of debug info of globals
|
||||
;;
|
||||
!llvm.dbg.cu = !{!0}
|
||||
|
||||
;; Some unrelated metadata.
|
||||
!llvm.module.flags = !{!6, !7}
|
||||
|
||||
;; Define the compile unit.
|
||||
!0 = metadata !{
|
||||
; Header(
|
||||
; i32 17, ;; Tag
|
||||
; i32 0, ;; Context
|
||||
; i32 4, ;; Language
|
||||
; metadata !"clang version 3.6.0 ", ;; Producer
|
||||
; i1 false, ;; "isOptimized"?
|
||||
; metadata !"", ;; Flags
|
||||
; i32 0, ;; Runtime Version
|
||||
; "", ;; Split debug filename
|
||||
; 1 ;; Full debug info
|
||||
; )
|
||||
metadata !"0x11\0012\00clang version 3.6.0 \000\00\000\00\001",
|
||||
metadata !1, ;; File
|
||||
metadata !2, ;; Enum Types
|
||||
metadata !2, ;; Retained Types
|
||||
metadata !2, ;; Subprograms
|
||||
metadata !3, ;; Global Variables
|
||||
metadata !2 ;; Imported entities
|
||||
} ; [ DW_TAG_compile_unit ]
|
||||
|
||||
;; The file/directory pair.
|
||||
!1 = metadata !{
|
||||
metadata !"foo.c", ;; Filename
|
||||
metadata !"/Users/dexonsmith/data/llvm/debug-info" ;; Directory
|
||||
}
|
||||
|
||||
;; An empty array.
|
||||
!2 = metadata !{}
|
||||
|
||||
;; The Array of Global Variables
|
||||
!3 = metadata !{
|
||||
metadata !4
|
||||
}
|
||||
|
||||
;;
|
||||
;; Define the global variable itself.
|
||||
;;
|
||||
!4 = metadata !{
|
||||
; Header(
|
||||
; i32 52, ;; Tag
|
||||
; metadata !"MyGlobal", ;; Name
|
||||
; metadata !"MyGlobal", ;; Display Name
|
||||
; metadata !"", ;; Linkage Name
|
||||
; i32 1, ;; Line
|
||||
; i32 0, ;; IsLocalToUnit
|
||||
; i32 1 ;; IsDefinition
|
||||
; )
|
||||
metadata !"0x34\00MyGlobal\00MyGlobal\00\001\000\001",
|
||||
null, ;; Unused
|
||||
metadata !5, ;; File
|
||||
metadata !6, ;; Type
|
||||
i32* @MyGlobal, ;; LLVM-IR Value
|
||||
null ;; Static member declaration
|
||||
} ; [ DW_TAG_variable ]
|
||||
!0 = !DICompileUnit(language: DW_LANG_C99, file: !1,
|
||||
producer:
|
||||
"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)",
|
||||
isOptimized: false, runtimeVersion: 0, emissionKind: 1,
|
||||
enums: !2, retainedTypes: !2, subprograms: !2, globals:
|
||||
!3, imports: !2)
|
||||
|
||||
;;
|
||||
;; Define the file
|
||||
;;
|
||||
!5 = metadata !{
|
||||
; Header(
|
||||
; i32 41 ;; Tag
|
||||
; )
|
||||
metadata !"0x29",
|
||||
metadata !1 ;; File/directory pair
|
||||
} ; [ DW_TAG_file_type ]
|
||||
!1 = !DIFile(filename: "/dev/stdin",
|
||||
directory: "/Users/dexonsmith/data/llvm/debug-info")
|
||||
|
||||
;; An empty array.
|
||||
!2 = !{}
|
||||
|
||||
;; The Array of Global Variables
|
||||
!3 = !{!4}
|
||||
|
||||
;;
|
||||
;; Define the global variable itself.
|
||||
;;
|
||||
!4 = !DIGlobalVariable(name: "MyGlobal", scope: !0, file: !1, line: 1,
|
||||
type: !5, isLocal: false, isDefinition: true,
|
||||
variable: i32* @MyGlobal)
|
||||
|
||||
;;
|
||||
;; Define the type
|
||||
;;
|
||||
!6 = metadata !{
|
||||
; Header(
|
||||
; i32 36, ;; Tag
|
||||
; metadata !"int", ;; Name
|
||||
; i32 0, ;; Line
|
||||
; i64 32, ;; Size in Bits
|
||||
; i64 32, ;; Align in Bits
|
||||
; i64 0, ;; Offset
|
||||
; i32 0, ;; Flags
|
||||
; i32 5 ;; Encoding
|
||||
; )
|
||||
metadata !"0x24\00int\000\0032\0032\000\000\005",
|
||||
null, ;; Unused
|
||||
null ;; Unused
|
||||
} ; [ DW_TAG_base_type ]
|
||||
!5 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
|
||||
;; Dwarf version to output.
|
||||
!6 = !{i32 2, !"Dwarf Version", i32 2}
|
||||
|
||||
;; Debug info schema version.
|
||||
!7 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
|
||||
C/C++ function information
|
||||
--------------------------
|
||||
@ -999,31 +461,10 @@ a C/C++ front-end would generate the following descriptors:
|
||||
;;
|
||||
;; Define the anchor for subprograms.
|
||||
;;
|
||||
!6 = metadata !{
|
||||
; Header(
|
||||
; i32 46, ;; Tag
|
||||
; metadata !"main", ;; Name
|
||||
; metadata !"main", ;; Display name
|
||||
; metadata !"", ;; Linkage name
|
||||
; i32 1, ;; Line number
|
||||
; i1 false, ;; Is local
|
||||
; i1 true, ;; Is definition
|
||||
; i32 0, ;; Virtuality attribute, e.g. pure virtual function
|
||||
; i32 0, ;; Index into virtual table for C++ methods
|
||||
; i32 256, ;; Flags
|
||||
; i1 0, ;; True if this function is optimized
|
||||
; 1 ;; Line number of the opening '{' of the function
|
||||
; )
|
||||
metadata !"0x2e\00main\00main\00\001\000\001\000\000\00256\000\001",
|
||||
metadata !1, ;; File
|
||||
metadata !5, ;; Context
|
||||
metadata !6, ;; Type
|
||||
null, ;; Containing type
|
||||
i32 (i32, i8**)* @main, ;; Pointer to llvm::Function
|
||||
null, ;; Function template parameters
|
||||
null, ;; Function declaration
|
||||
metadata !2 ;; List of function variables (emitted when optimizing)
|
||||
}
|
||||
!4 = !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !5,
|
||||
isLocal: false, isDefinition: true, scopeLine: 1,
|
||||
flags: DIFlagPrototyped, isOptimized: false,
|
||||
function: i32 (i32, i8**)* @main, variables: !2)
|
||||
|
||||
;;
|
||||
;; Define the subprogram itself.
|
||||
@ -1807,7 +1248,6 @@ tag is one of:
|
||||
* DW_TAG_subrange_type
|
||||
* DW_TAG_base_type
|
||||
* DW_TAG_const_type
|
||||
* DW_TAG_constant
|
||||
* DW_TAG_file_type
|
||||
* DW_TAG_namelist
|
||||
* DW_TAG_packed_type
|
||||
|
@ -221,11 +221,12 @@ lowered according to the calling convention specified at the
|
||||
intrinsic's callsite. Variants of the intrinsic with non-void return
|
||||
type also return a value according to calling convention.
|
||||
|
||||
On PowerPC, note that the ``<target>`` must be the actual intended target of
|
||||
the indirect call, not the function-descriptor address normally used as the
|
||||
C/C++ function-pointer representation. As a result, the call target must be
|
||||
local because no adjustment or restoration of the TOC pointer (in register r2)
|
||||
will be performed.
|
||||
On PowerPC, note that ``<target>`` must be the actual intended target of
|
||||
the indirect call. Specifically, even when compiling for the ELF V1 ABI,
|
||||
``<target>`` is not the function-descriptor address normally used as the C/C++
|
||||
function-pointer representation. As a result, the call target must be local
|
||||
because no adjustment or restoration of the TOC pointer (in register r2) will
|
||||
be performed.
|
||||
|
||||
Requesting zero patch point arguments is valid. In this case, all
|
||||
variable operands are handled just like
|
||||
|
@ -14,8 +14,8 @@ with caution. Because the intrinsics have experimental status,
|
||||
compatibility across LLVM releases is not guaranteed.
|
||||
|
||||
LLVM currently supports an alternate mechanism for conservative
|
||||
garbage collection support using the gc_root intrinsic. The mechanism
|
||||
described here shares little in common with the alternate
|
||||
garbage collection support using the ``gcroot`` intrinsic. The mechanism
|
||||
described here shares little in common with the alternate ``gcroot``
|
||||
implementation and it is hoped that this mechanism will eventually
|
||||
replace the gc_root mechanism.
|
||||
|
||||
@ -111,25 +111,41 @@ garbage collected objects.
|
||||
collected values, transforming the IR to expose a pointer giving the
|
||||
base object for every such live pointer, and inserting all the
|
||||
intrinsics correctly is explicitly out of scope for this document.
|
||||
The recommended approach is described in the section of Late
|
||||
Safepoint Placement below.
|
||||
The recommended approach is to use the :ref:`utility passes
|
||||
<statepoint-utilities>` described below.
|
||||
|
||||
This abstract function call is concretely represented by a sequence of
|
||||
intrinsic calls known as a 'statepoint sequence'.
|
||||
|
||||
intrinsic calls known collectively as a "statepoint relocation sequence".
|
||||
|
||||
Let's consider a simple call in LLVM IR:
|
||||
todo
|
||||
|
||||
Depending on our language we may need to allow a safepoint during the
|
||||
execution of the function called from this site. If so, we need to
|
||||
let the collector update local values in the current frame.
|
||||
.. code-block:: llvm
|
||||
|
||||
Let's say we need to relocate SSA values 'a', 'b', and 'c' at this
|
||||
safepoint. To represent this, we would generate the statepoint
|
||||
sequence:
|
||||
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
|
||||
gc "statepoint-example" {
|
||||
call void ()* @foo()
|
||||
ret i8 addrspace(1)* %obj
|
||||
}
|
||||
|
||||
todo
|
||||
Depending on our language we may need to allow a safepoint during the execution
|
||||
of ``foo``. If so, we need to let the collector update local values in the
|
||||
current frame. If we don't, we'll be accessing a potential invalid reference
|
||||
once we eventually return from the call.
|
||||
|
||||
In this example, we need to relocate the SSA value ``%obj``. Since we can't
|
||||
actually change the value in the SSA value ``%obj``, we need to introduce a new
|
||||
SSA value ``%obj.relocated`` which represents the potentially changed value of
|
||||
``%obj`` after the safepoint and update any following uses appropriately. The
|
||||
resulting relocation sequence is:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
|
||||
gc "statepoint-example" {
|
||||
%0 = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
|
||||
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 7, i32 7)
|
||||
ret i8 addrspace(1)* %obj.relocated
|
||||
}
|
||||
|
||||
Ideally, this sequence would have been represented as a M argument, N
|
||||
return value function (where M is the number of values being
|
||||
@ -140,14 +156,24 @@ representation.
|
||||
Instead, the statepoint intrinsic marks the actual site of the
|
||||
safepoint or statepoint. The statepoint returns a token value (which
|
||||
exists only at compile time). To get back the original return value
|
||||
of the call, we use the 'gc.result' intrinsic. To get the relocation
|
||||
of each pointer in turn, we use the 'gc.relocate' intrinsic with the
|
||||
appropriate index. Note that both the gc.relocate and gc.result are
|
||||
tied to the statepoint. The combination forms a "statepoint sequence"
|
||||
and represents the entitety of a parseable call or 'statepoint'.
|
||||
of the call, we use the ``gc.result`` intrinsic. To get the relocation
|
||||
of each pointer in turn, we use the ``gc.relocate`` intrinsic with the
|
||||
appropriate index. Note that both the ``gc.relocate`` and ``gc.result`` are
|
||||
tied to the statepoint. The combination forms a "statepoint relocation
|
||||
sequence" and represents the entitety of a parseable call or 'statepoint'.
|
||||
|
||||
When lowered, this example would generate the following x86 assembly::
|
||||
put assembly here
|
||||
When lowered, this example would generate the following x86 assembly:
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
.globl test1
|
||||
.align 16, 0x90
|
||||
pushq %rax
|
||||
callq foo
|
||||
.Ltmp1:
|
||||
movq (%rsp), %rax # This load is redundant (oops!)
|
||||
popq %rdx
|
||||
retq
|
||||
|
||||
Each of the potentially relocated values has been spilled to the
|
||||
stack, and a record of that location has been recorded to the
|
||||
@ -155,11 +181,115 @@ stack, and a record of that location has been recorded to the
|
||||
needs to update any of these pointers during the call, it knows
|
||||
exactly what to change.
|
||||
|
||||
The relevant parts of the StackMap section for our example are:
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
# This describes the call site
|
||||
# Stack Maps: callsite 2882400000
|
||||
.quad 2882400000
|
||||
.long .Ltmp1-test1
|
||||
.short 0
|
||||
# .. 8 entries skipped ..
|
||||
# This entry describes the spill slot which is directly addressable
|
||||
# off RSP with offset 0. Given the value was spilled with a pushq,
|
||||
# that makes sense.
|
||||
# Stack Maps: Loc 8: Direct RSP [encoding: .byte 2, .byte 8, .short 7, .int 0]
|
||||
.byte 2
|
||||
.byte 8
|
||||
.short 7
|
||||
.long 0
|
||||
|
||||
This example was taken from the tests for the :ref:`RewriteStatepointsForGC` utility pass. As such, it's full StackMap can be easily examined with the following command.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
opt -rewrite-statepoints-for-gc test/Transforms/RewriteStatepointsForGC/basics.ll -S | llc -debug-only=stackmaps
|
||||
|
||||
|
||||
GC Transitions
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As a practical consideration, many garbage-collected systems allow code that is
|
||||
collector-aware ("managed code") to call code that is not collector-aware
|
||||
("unmanaged code"). It is common that such calls must also be safepoints, since
|
||||
it is desirable to allow the collector to run during the execution of
|
||||
unmanaged code. Futhermore, it is common that coordinating the transition from
|
||||
managed to unmanaged code requires extra code generation at the call site to
|
||||
inform the collector of the transition. In order to support these needs, a
|
||||
statepoint may be marked as a GC transition, and data that is necessary to
|
||||
perform the transition (if any) may be provided as additional arguments to the
|
||||
statepoint.
|
||||
|
||||
Note that although in many cases statepoints may be inferred to be GC
|
||||
transitions based on the function symbols involved (e.g. a call from a
|
||||
function with GC strategy "foo" to a function with GC strategy "bar"),
|
||||
indirect calls that are also GC transitions must also be supported. This
|
||||
requirement is the driving force behing the decision to require that GC
|
||||
transitions are explicitly marked.
|
||||
|
||||
Let's revisit the sample given above, this time treating the call to ``@foo``
|
||||
as a GC transition. Depending on our target, the transition code may need to
|
||||
access some extra state in order to inform the collector of the transition.
|
||||
Let's assume a hypothetical GC--somewhat unimaginatively named "hypothetical-gc"
|
||||
--that requires that a TLS variable must be written to before and after a call
|
||||
to unmanaged code. The resulting relocation sequence is:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
@flag = thread_local global i32 0, align 4
|
||||
|
||||
define i8 addrspace(1)* @test1(i8 addrspace(1) *%obj)
|
||||
gc "hypothetical-gc" {
|
||||
|
||||
%0 = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 1, i32* @Flag, i32 0, i8 addrspace(1)* %obj)
|
||||
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 7, i32 7)
|
||||
ret i8 addrspace(1)* %obj.relocated
|
||||
}
|
||||
|
||||
During lowering, this will result in a instruction selection DAG that looks
|
||||
something like:
|
||||
|
||||
::
|
||||
|
||||
CALLSEQ_START
|
||||
...
|
||||
GC_TRANSITION_START (lowered i32 *@Flag), SRCVALUE i32* Flag
|
||||
STATEPOINT
|
||||
GC_TRANSITION_END (lowered i32 *@Flag), SRCVALUE i32 *Flag
|
||||
...
|
||||
CALLSEQ_END
|
||||
|
||||
In order to generate the necessary transition code, the backend for each target
|
||||
supported by "hypothetical-gc" must be modified to lower ``GC_TRANSITION_START``
|
||||
and ``GC_TRANSITION_END`` nodes appropriately when the "hypothetical-gc"
|
||||
strategy is in use for a particular function. Assuming that such lowering has
|
||||
been added for X86, the generated assembly would be:
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
.globl test1
|
||||
.align 16, 0x90
|
||||
pushq %rax
|
||||
movl $1, %fs:Flag@TPOFF
|
||||
callq foo
|
||||
movl $0, %fs:Flag@TPOFF
|
||||
.Ltmp1:
|
||||
movq (%rsp), %rax # This load is redundant (oops!)
|
||||
popq %rdx
|
||||
retq
|
||||
|
||||
Note that the design as presented above is not fully implemented: in particular,
|
||||
strategy-specific lowering is not present, and all GC transitions are emitted as
|
||||
as single no-op before and after the call instruction. These no-ops are often
|
||||
removed by the backend during dead machine instruction elimination.
|
||||
|
||||
|
||||
Intrinsics
|
||||
===========
|
||||
|
||||
'''gc.statepoint''' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
'llvm.experimental.gc.statepoint' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
@ -167,8 +297,11 @@ Syntax:
|
||||
::
|
||||
|
||||
declare i32
|
||||
@gc.statepoint(func_type <target>, i64 <#call args>.
|
||||
i64 <unused>, ... (call parameters),
|
||||
@llvm.experimental.gc.statepoint(i64 <id>, i32 <num patch bytes>,
|
||||
func_type <target>,
|
||||
i64 <#call args>, i64 <flags>,
|
||||
... (call parameters),
|
||||
i64 <# transition args>, ... (transition parameters),
|
||||
i64 <# deopt args>, ... (deopt parameters),
|
||||
... (gc parameters))
|
||||
|
||||
@ -181,18 +314,49 @@ runtime.
|
||||
Operands:
|
||||
"""""""""
|
||||
|
||||
The 'id' operand is a constant integer that is reported as the ID
|
||||
field in the generated stackmap. LLVM does not interpret this
|
||||
parameter in any way and its meaning is up to the statepoint user to
|
||||
decide. Note that LLVM is free to duplicate code containing
|
||||
statepoint calls, and this may transform IR that had a unique 'id' per
|
||||
lexical call to statepoint to IR that does not.
|
||||
|
||||
If 'num patch bytes' is non-zero then the call instruction
|
||||
corresponding to the statepoint is not emitted and LLVM emits 'num
|
||||
patch bytes' bytes of nops in its place. LLVM will emit code to
|
||||
prepare the function arguments and retrieve the function return value
|
||||
in accordance to the calling convention; the former before the nop
|
||||
sequence and the latter after the nop sequence. It is expected that
|
||||
the user will patch over the 'num patch bytes' bytes of nops with a
|
||||
calling sequence specific to their runtime before executing the
|
||||
generated machine code. There are no guarantees with respect to the
|
||||
alignment of the nop sequence. Unlike :doc:`StackMaps` statepoints do
|
||||
not have a concept of shadow bytes.
|
||||
|
||||
The 'target' operand is the function actually being called. The
|
||||
target can be specified as either a symbolic LLVM function, or as an
|
||||
arbitrary Value of appropriate function type. Note that the function
|
||||
type must match the signature of the callee and the types of the 'call
|
||||
parameters' arguments.
|
||||
parameters' arguments. If 'num patch bytes' is non-zero then 'target'
|
||||
has to be the constant pointer null of the appropriate function type.
|
||||
|
||||
The '#call args' operand is the number of arguments to the actual
|
||||
call. It must exactly match the number of arguments passed in the
|
||||
'call parameters' variable length section.
|
||||
|
||||
The 'unused' operand is unused and likely to be removed. Please do
|
||||
not use.
|
||||
The 'flags' operand is used to specify extra information about the
|
||||
statepoint. This is currently only used to mark certain statepoints
|
||||
as GC transitions. This operand is a 64-bit integer with the following
|
||||
layout, where bit 0 is the least significant bit:
|
||||
|
||||
+-------+---------------------------------------------------+
|
||||
| Bit # | Usage |
|
||||
+=======+===================================================+
|
||||
| 0 | Set if the statepoint is a GC transition, cleared |
|
||||
| | otherwise. |
|
||||
+-------+---------------------------------------------------+
|
||||
| 1-63 | Reserved for future use; must be cleared. |
|
||||
+-------+---------------------------------------------------+
|
||||
|
||||
The 'call parameters' arguments are simply the arguments which need to
|
||||
be passed to the call target. They will be lowered according to the
|
||||
@ -201,6 +365,14 @@ instruction. The number of arguments must exactly match what is
|
||||
specified in '# call args'. The types must match the signature of
|
||||
'target'.
|
||||
|
||||
The 'transition parameters' arguments contain an arbitrary list of
|
||||
Values which need to be passed to GC transition code. They will be
|
||||
lowered and passed as operands to the appropriate GC_TRANSITION nodes
|
||||
in the selection DAG. It is assumed that these arguments must be
|
||||
available before and after (but not necessarily during) the execution
|
||||
of the callee. The '# transition args' field indicates how many operands
|
||||
are to be interpreted as 'transition parameters'.
|
||||
|
||||
The 'deopt parameters' arguments contain an arbitrary list of Values
|
||||
which is meaningful to the runtime. The runtime may read any of these
|
||||
values, but is assumed not to modify them. If the garbage collector
|
||||
@ -225,10 +397,10 @@ illegal to mark a statepoint as being either 'readonly' or 'readnone'.
|
||||
Note that legal IR can not perform any memory operation on a 'gc
|
||||
pointer' argument of the statepoint in a location statically reachable
|
||||
from the statepoint. Instead, the explicitly relocated value (from a
|
||||
''gc.relocate'') must be used.
|
||||
``gc.relocate``) must be used.
|
||||
|
||||
'''gc.result''' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
'llvm.experimental.gc.result' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
@ -236,19 +408,13 @@ Syntax:
|
||||
::
|
||||
|
||||
declare type*
|
||||
@gc.result_ptr(i32 %statepoint_token)
|
||||
|
||||
declare fX
|
||||
@gc.result_float(i32 %statepoint_token)
|
||||
|
||||
declare iX
|
||||
@gc.result_int(i32 %statepoint_token)
|
||||
@llvm.experimental.gc.result(i32 %statepoint_token)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
'''gc.result''' extracts the result of the original call instruction
|
||||
which was replaced by the '''gc.statepoint'''. The '''gc.result'''
|
||||
``gc.result`` extracts the result of the original call instruction
|
||||
which was replaced by the ``gc.statepoint``. The ``gc.result``
|
||||
intrinsic is actually a family of three intrinsics due to an
|
||||
implementation limitation. Other than the type of the return value,
|
||||
the semantics are the same.
|
||||
@ -256,47 +422,49 @@ the semantics are the same.
|
||||
Operands:
|
||||
"""""""""
|
||||
|
||||
The first and only argument is the '''gc.statepoint''' which starts
|
||||
the safepoint sequence of which this '''gc.result'' is a part.
|
||||
The first and only argument is the ``gc.statepoint`` which starts
|
||||
the safepoint sequence of which this ``gc.result`` is a part.
|
||||
Despite the typing of this as a generic i32, *only* the value defined
|
||||
by a '''gc.statepoint''' is legal here.
|
||||
by a ``gc.statepoint`` is legal here.
|
||||
|
||||
Semantics:
|
||||
""""""""""
|
||||
|
||||
The ''gc.result'' represents the return value of the call target of
|
||||
the ''statepoint''. The type of the ''gc.result'' must exactly match
|
||||
The ``gc.result`` represents the return value of the call target of
|
||||
the ``statepoint``. The type of the ``gc.result`` must exactly match
|
||||
the type of the target. If the call target returns void, there will
|
||||
be no ''gc.result''.
|
||||
be no ``gc.result``.
|
||||
|
||||
A ''gc.result'' is modeled as a 'readnone' pure function. It has no
|
||||
A ``gc.result`` is modeled as a 'readnone' pure function. It has no
|
||||
side effects since it is just a projection of the return value of the
|
||||
previous call represented by the ''gc.statepoint''.
|
||||
previous call represented by the ``gc.statepoint``.
|
||||
|
||||
'''gc.relocate''' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
'llvm.experimental.gc.relocate' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare <type> addrspace(1)*
|
||||
@gc.relocate(i32 %statepoint_token, i32 %base_offset, i32 %pointer_offset)
|
||||
declare <pointer type>
|
||||
@llvm.experimental.gc.relocate(i32 %statepoint_token,
|
||||
i32 %base_offset,
|
||||
i32 %pointer_offset)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
A ''gc.relocate'' returns the potentially relocated value of a pointer
|
||||
A ``gc.relocate`` returns the potentially relocated value of a pointer
|
||||
at the safepoint.
|
||||
|
||||
Operands:
|
||||
"""""""""
|
||||
|
||||
The first argument is the '''gc.statepoint''' which starts the
|
||||
safepoint sequence of which this '''gc.relocation'' is a part.
|
||||
The first argument is the ``gc.statepoint`` which starts the
|
||||
safepoint sequence of which this ``gc.relocation`` is a part.
|
||||
Despite the typing of this as a generic i32, *only* the value defined
|
||||
by a '''gc.statepoint''' is legal here.
|
||||
by a ``gc.statepoint`` is legal here.
|
||||
|
||||
The second argument is an index into the statepoints list of arguments
|
||||
which specifies the base pointer for the pointer being relocated.
|
||||
@ -312,19 +480,20 @@ within the 'gc parameter' section of the statepoint's argument list.
|
||||
Semantics:
|
||||
""""""""""
|
||||
|
||||
The return value of ''gc.relocate'' is the potentially relocated value
|
||||
The return value of ``gc.relocate`` is the potentially relocated value
|
||||
of the pointer specified by it's arguments. It is unspecified how the
|
||||
value of the returned pointer relates to the argument to the
|
||||
''gc.statepoint'' other than that a) it points to the same source
|
||||
``gc.statepoint`` other than that a) it points to the same source
|
||||
language object with the same offset, and b) the 'based-on'
|
||||
relationship of the newly relocated pointers is a projection of the
|
||||
unrelocated pointers. In particular, the integer value of the pointer
|
||||
returned is unspecified.
|
||||
|
||||
A ''gc.relocate'' is modeled as a 'readnone' pure function. It has no
|
||||
A ``gc.relocate`` is modeled as a ``readnone`` pure function. It has no
|
||||
side effects since it is just a way to extract information about work
|
||||
done during the actual call modeled by the ''gc.statepoint''.
|
||||
done during the actual call modeled by the ``gc.statepoint``.
|
||||
|
||||
.. _statepoint-stackmap-format:
|
||||
|
||||
Stack Map Format
|
||||
================
|
||||
@ -335,6 +504,12 @@ the runtime or collector are provided via the :ref:`Stack Map format
|
||||
|
||||
Each statepoint generates the following Locations:
|
||||
|
||||
* Constant which describes the calling convention of the call target. This
|
||||
constant is a valid :ref:`calling convention identifier <callingconv>` for
|
||||
the version of LLVM used to generate the stackmap. No additional compatibility
|
||||
guarantees are made for this constant over what LLVM provides elsewhere w.r.t.
|
||||
these identifiers.
|
||||
* Constant which describes the flags passed to the statepoint intrinsic
|
||||
* Constant which describes number of following deopt *Locations* (not
|
||||
operands)
|
||||
* Variable number of Locations, one for each deopt parameter listed in
|
||||
@ -352,9 +527,6 @@ Note that the Locations used in each section may describe the same
|
||||
physical location. e.g. A stack slot may appear as a deopt location,
|
||||
a gc base pointer, and a gc derived pointer.
|
||||
|
||||
The ID field of the 'StkMapRecord' for a statepoint is meaningless and
|
||||
it's value is explicitly unspecified.
|
||||
|
||||
The LiveOut section of the StkMapRecord will be empty for a statepoint
|
||||
record.
|
||||
|
||||
@ -396,6 +568,137 @@ key relocation invariant, but this is ongoing work on developing such
|
||||
a verifier. Please ask on llvmdev if you're interested in
|
||||
experimenting with the current version.
|
||||
|
||||
.. _statepoint-utilities:
|
||||
|
||||
Utility Passes for Safepoint Insertion
|
||||
======================================
|
||||
|
||||
.. _RewriteStatepointsForGC:
|
||||
|
||||
RewriteStatepointsForGC
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The pass RewriteStatepointsForGC transforms a functions IR by replacing a
|
||||
``gc.statepoint`` (with an optional ``gc.result``) with a full relocation
|
||||
sequence, including all required ``gc.relocates``. To function, the pass
|
||||
requires that the GC strategy specified for the function be able to reliably
|
||||
distinguish between GC references and non-GC references in IR it is given.
|
||||
|
||||
As an example, given this code:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
|
||||
gc "statepoint-example" {
|
||||
call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||
ret i8 addrspace(1)* %obj
|
||||
}
|
||||
|
||||
The pass would produce this IR:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
|
||||
gc "statepoint-example" {
|
||||
%0 = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
|
||||
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 12, i32 12)
|
||||
ret i8 addrspace(1)* %obj.relocated
|
||||
}
|
||||
|
||||
In the above examples, the addrspace(1) marker on the pointers is the mechanism
|
||||
that the ``statepoint-example`` GC strategy uses to distinguish references from
|
||||
non references. Address space 1 is not globally reserved for this purpose.
|
||||
|
||||
This pass can be used an utility function by a language frontend that doesn't
|
||||
want to manually reason about liveness, base pointers, or relocation when
|
||||
constructing IR. As currently implemented, RewriteStatepointsForGC must be
|
||||
run after SSA construction (i.e. mem2ref).
|
||||
|
||||
|
||||
In practice, RewriteStatepointsForGC can be run much later in the pass
|
||||
pipeline, after most optimization is already done. This helps to improve
|
||||
the quality of the generated code when compiled with garbage collection support.
|
||||
In the long run, this is the intended usage model. At this time, a few details
|
||||
have yet to be worked out about the semantic model required to guarantee this
|
||||
is always correct. As such, please use with caution and report bugs.
|
||||
|
||||
.. _PlaceSafepoints:
|
||||
|
||||
PlaceSafepoints
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The pass PlaceSafepoints transforms a function's IR by replacing any call or
|
||||
invoke instructions with appropriate ``gc.statepoint`` and ``gc.result`` pairs,
|
||||
and inserting safepoint polls sufficient to ensure running code checks for a
|
||||
safepoint request on a timely manner. This pass is expected to be run before
|
||||
RewriteStatepointsForGC and thus does not produce full relocation sequences.
|
||||
|
||||
As an example, given input IR of the following:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define void @test() gc "statepoint-example" {
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @do_safepoint()
|
||||
define void @gc.safepoint_poll() {
|
||||
call void @do_safepoint()
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
This pass would produce the following IR:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define void @test() gc "statepoint-example" {
|
||||
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
|
||||
%safepoint_token1 = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
|
||||
ret void
|
||||
}
|
||||
|
||||
In this case, we've added an (unconditional) entry safepoint poll and converted the call into a ``gc.statepoint``. Note that despite appearances, the entry poll is not necessarily redundant. We'd have to know that ``foo`` and ``test`` were not mutually recursive for the poll to be redundant. In practice, you'd probably want to your poll definition to contain a conditional branch of some form.
|
||||
|
||||
|
||||
At the moment, PlaceSafepoints can insert safepoint polls at method entry and
|
||||
loop backedges locations. Extending this to work with return polls would be
|
||||
straight forward if desired.
|
||||
|
||||
PlaceSafepoints includes a number of optimizations to avoid placing safepoint
|
||||
polls at particular sites unless needed to ensure timely execution of a poll
|
||||
under normal conditions. PlaceSafepoints does not attempt to ensure timely
|
||||
execution of a poll under worst case conditions such as heavy system paging.
|
||||
|
||||
The implementation of a safepoint poll action is specified by looking up a
|
||||
function of the name ``gc.safepoint_poll`` in the containing Module. The body
|
||||
of this function is inserted at each poll site desired. While calls or invokes
|
||||
inside this method are transformed to a ``gc.statepoints``, recursive poll
|
||||
insertion is not performed.
|
||||
|
||||
By default PlaceSafepoints passes in ``0xABCDEF00`` as the statepoint
|
||||
ID and ``0`` as the number of patchable bytes to the newly constructed
|
||||
``gc.statepoint``. These values can be configured on a per-callsite
|
||||
basis using the attributes ``"statepoint-id"`` and
|
||||
``"statepoint-num-patch-bytes"``. If a call site is marked with a
|
||||
``"statepoint-id"`` function attribute and its value is a positive
|
||||
integer (represented as a string), then that value is used as the ID
|
||||
of the newly constructed ``gc.statepoint``. If a call site is marked
|
||||
with a ``"statepoint-num-patch-bytes"`` function attribute and its
|
||||
value is a positive integer, then that value is used as the 'num patch
|
||||
bytes' parameter of the newly constructed ``gc.statepoint``. The
|
||||
``"statepoint-id"`` and ``"statepoint-num-patch-bytes"`` attributes
|
||||
are not propagated to the ``gc.statepoint`` call or invoke if they
|
||||
could be successfully parsed.
|
||||
|
||||
If you are scheduling the RewriteStatepointsForGC pass late in the pass order,
|
||||
you should probably schedule this pass immediately before it. The exception
|
||||
would be if you need to preserve abstract frame information (e.g. for
|
||||
deoptimization or introspection) at safepoints. In that case, ask on the
|
||||
llvmdev mailing list for suggestions.
|
||||
|
||||
|
||||
Bugs and Enhancements
|
||||
=====================
|
||||
|
||||
|
@ -473,6 +473,25 @@ RUN lines:
|
||||
To add more substituations, look at ``test/lit.cfg`` or ``lit.local.cfg``.
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
The llvm lit configuration allows to customize some things with user options:
|
||||
|
||||
``llc``, ``opt``, ...
|
||||
Substitute the respective llvm tool name with a custom command line. This
|
||||
allows to specify custom paths and default arguments for these tools.
|
||||
Example:
|
||||
|
||||
% llvm-lit "-Dllc=llc -verify-machineinstrs"
|
||||
|
||||
``run_long_tests``
|
||||
Enable the execution of long running tests.
|
||||
|
||||
``llvm_site_config``
|
||||
Load the specified lit configuration instead of the default one.
|
||||
|
||||
|
||||
Other Features
|
||||
--------------
|
||||
|
||||
|
@ -366,7 +366,7 @@ The decision to unroll the loop depends on the register pressure and the generat
|
||||
Performance
|
||||
-----------
|
||||
|
||||
This section shows the the execution time of Clang on a simple benchmark:
|
||||
This section shows the execution time of Clang on a simple benchmark:
|
||||
`gcc-loops <http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Vectorizer/>`_.
|
||||
This benchmarks is a collection of loops from the GCC autovectorization
|
||||
`page <http://gcc.gnu.org/projects/tree-ssa/vectorization.html>`_ by Dorit Nuzman.
|
||||
|
@ -853,7 +853,7 @@ Example implementations of ``getAnalysisUsage``
|
||||
// This example modifies the program, but does not modify the CFG
|
||||
void LICM::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<LoopInfo>();
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
}
|
||||
|
||||
.. _writing-an-llvm-pass-getAnalysis:
|
||||
@ -870,7 +870,7 @@ you want, and returns a reference to that pass. For example:
|
||||
.. code-block:: c++
|
||||
|
||||
bool LICM::runOnFunction(Function &F) {
|
||||
LoopInfo &LI = getAnalysis<LoopInfo>();
|
||||
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
//...
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,7 @@ as a field type:
|
||||
}
|
||||
};
|
||||
|
||||
When reading YAML, if the string found does not match any of the the strings
|
||||
When reading YAML, if the string found does not match any of the strings
|
||||
specified by enumCase() methods, an error is automatically generated.
|
||||
When writing YAML, if the value being written does not match any of the values
|
||||
specified by the enumCase() methods, a runtime assertion is triggered.
|
||||
@ -456,10 +456,10 @@ looks like:
|
||||
|
||||
template <>
|
||||
struct ScalarTraits<MyCustomType> {
|
||||
static void output(const T &value, llvm::raw_ostream &out) {
|
||||
static void output(const T &value, void*, llvm::raw_ostream &out) {
|
||||
out << value; // do custom formatting here
|
||||
}
|
||||
static StringRef input(StringRef scalar, T &value) {
|
||||
static StringRef input(StringRef scalar, void*, T &value) {
|
||||
// do custom parsing here. Return the empty string on success,
|
||||
// or an error message on failure.
|
||||
return StringRef();
|
||||
@ -467,6 +467,56 @@ looks like:
|
||||
// Determine if this scalar needs quotes.
|
||||
static bool mustQuote(StringRef) { return true; }
|
||||
};
|
||||
|
||||
Block Scalars
|
||||
-------------
|
||||
|
||||
YAML block scalars are string literals that are represented in YAML using the
|
||||
literal block notation, just like the example shown below:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
text: |
|
||||
First line
|
||||
Second line
|
||||
|
||||
The YAML I/O library provides support for translating between YAML block scalars
|
||||
and specific C++ types by allowing you to specialize BlockScalarTraits<> on
|
||||
your data type. The library doesn't provide any built-in support for block
|
||||
scalar I/O for types like std::string and llvm::StringRef as they are already
|
||||
supported by YAML I/O and use the ordinary scalar notation by default.
|
||||
|
||||
BlockScalarTraits specializations are very similar to the
|
||||
ScalarTraits specialization - YAML I/O will provide the native type and your
|
||||
specialization must create a temporary llvm::StringRef when writing, and
|
||||
it will also provide an llvm::StringRef that has the value of that block scalar
|
||||
and your specialization must convert that to your native data type when reading.
|
||||
An example of a custom type with an appropriate specialization of
|
||||
BlockScalarTraits is shown below:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
using llvm::yaml::BlockScalarTraits;
|
||||
using llvm::yaml::IO;
|
||||
|
||||
struct MyStringType {
|
||||
std::string Str;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct BlockScalarTraits<MyStringType> {
|
||||
static void output(const MyStringType &Value, void *Ctxt,
|
||||
llvm::raw_ostream &OS) {
|
||||
OS << Value.Str;
|
||||
}
|
||||
|
||||
static StringRef input(StringRef Scalar, void *Ctxt,
|
||||
MyStringType &Value) {
|
||||
Value.Str = Scalar.str();
|
||||
return StringRef();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Mappings
|
||||
@ -723,6 +773,31 @@ because it is a programming error to have invalid struct values.
|
||||
}
|
||||
};
|
||||
|
||||
Flow Mapping
|
||||
------------
|
||||
A YAML "flow mapping" is a mapping that uses the inline notation
|
||||
(e.g { x: 1, y: 0 } ) when written to YAML. To specify that a type should be
|
||||
written in YAML using flow mapping, your MappingTraits specialization should
|
||||
add "static const bool flow = true;". For instance:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
using llvm::yaml::MappingTraits;
|
||||
using llvm::yaml::IO;
|
||||
|
||||
struct Stuff {
|
||||
...
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MappingTraits<Stuff> {
|
||||
static void mapping(IO &io, Stuff &stuff) {
|
||||
...
|
||||
}
|
||||
|
||||
static const bool flow = true;
|
||||
}
|
||||
|
||||
|
||||
Sequence
|
||||
========
|
||||
@ -767,7 +842,7 @@ add "static const bool flow = true;". For instance:
|
||||
};
|
||||
|
||||
With the above, if you used MyList as the data type in your native data
|
||||
structures, then then when converted to YAML, a flow sequence of integers
|
||||
structures, then when converted to YAML, a flow sequence of integers
|
||||
will be used (e.g. [ 10, -3, 4 ]).
|
||||
|
||||
|
||||
|
@ -47,9 +47,9 @@ copyright = u'2003-2014, LLVM Project'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '3.6'
|
||||
version = '3.7'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '3.6'
|
||||
release = '3.7'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
2366
docs/doxygen.cfg.in
2366
docs/doxygen.cfg.in
File diff suppressed because it is too large
Load Diff
408
docs/doxygen.css
408
docs/doxygen.css
@ -1,408 +0,0 @@
|
||||
BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
|
||||
font-family: Verdana,Geneva,Arial,Helvetica,sans-serif;
|
||||
}
|
||||
BODY,TD {
|
||||
font-size: 90%;
|
||||
}
|
||||
H1 {
|
||||
text-align: center;
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
}
|
||||
H2 {
|
||||
font-size: 120%;
|
||||
font-style: italic;
|
||||
}
|
||||
H3 {
|
||||
font-size: 100%;
|
||||
}
|
||||
CAPTION { font-weight: bold }
|
||||
DIV.qindex {
|
||||
width: 100%;
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
line-height: 140%;
|
||||
}
|
||||
DIV.nav {
|
||||
width: 100%;
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
line-height: 140%;
|
||||
}
|
||||
DIV.navtab {
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
margin-right: 15px;
|
||||
padding: 2px;
|
||||
}
|
||||
TD.navtab {
|
||||
font-size: 70%;
|
||||
}
|
||||
A.qindex {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: #1A419D;
|
||||
}
|
||||
A.qindex:visited {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: #1A419D
|
||||
}
|
||||
A.qindex:hover {
|
||||
text-decoration: none;
|
||||
background-color: #ddddff;
|
||||
}
|
||||
A.qindexHL {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background-color: #6666cc;
|
||||
color: #ffffff;
|
||||
border: 1px double #9295C2;
|
||||
}
|
||||
A.qindexHL:hover {
|
||||
text-decoration: none;
|
||||
background-color: #6666cc;
|
||||
color: #ffffff;
|
||||
}
|
||||
A.qindexHL:visited {
|
||||
text-decoration: none; background-color: #6666cc; color: #ffffff }
|
||||
A.el { text-decoration: none; font-weight: bold }
|
||||
A.elRef { font-weight: bold }
|
||||
A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
|
||||
A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
|
||||
A.codeRef:link { font-weight: normal; color: #0000FF}
|
||||
A.codeRef:visited { font-weight: normal; color: #0000FF}
|
||||
A:hover { text-decoration: none; background-color: #f2f2ff }
|
||||
DL.el { margin-left: -1cm }
|
||||
.fragment {
|
||||
font-family: Fixed, monospace;
|
||||
font-size: 95%;
|
||||
}
|
||||
PRE.fragment {
|
||||
border: 1px solid #CCCCCC;
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
margin-left: 2px;
|
||||
margin-right: 8px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
|
||||
TD.md { background-color: #F4F4FB; font-weight: bold; }
|
||||
TD.mdPrefix {
|
||||
background-color: #F4F4FB;
|
||||
color: #606060;
|
||||
font-size: 80%;
|
||||
}
|
||||
TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
|
||||
TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
|
||||
DIV.groupHeader {
|
||||
margin-left: 16px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
|
||||
BODY {
|
||||
background: white;
|
||||
color: black;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
TD.indexkey {
|
||||
background-color: #eeeeff;
|
||||
font-weight: bold;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
TD.indexvalue {
|
||||
background-color: #eeeeff;
|
||||
font-style: italic;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
TR.memlist {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
P.formulaDsp { text-align: center; }
|
||||
IMG.formulaDsp { }
|
||||
IMG.formulaInl { vertical-align: middle; }
|
||||
SPAN.keyword { color: #008000 }
|
||||
SPAN.keywordtype { color: #604020 }
|
||||
SPAN.keywordflow { color: #e08000 }
|
||||
SPAN.comment { color: #800000 }
|
||||
SPAN.preprocessor { color: #806020 }
|
||||
SPAN.stringliteral { color: #002080 }
|
||||
SPAN.charliteral { color: #008080 }
|
||||
.mdTable {
|
||||
border: 1px solid #868686;
|
||||
background-color: #F4F4FB;
|
||||
}
|
||||
.mdRow {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
.mdescLeft {
|
||||
padding: 0px 8px 4px 8px;
|
||||
font-size: 80%;
|
||||
font-style: italic;
|
||||
background-color: #FAFAFA;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
.mdescRight {
|
||||
padding: 0px 8px 4px 8px;
|
||||
font-size: 80%;
|
||||
font-style: italic;
|
||||
background-color: #FAFAFA;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
.memItemLeft {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memItemRight {
|
||||
padding: 1px 8px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplItemLeft {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: none;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplItemRight {
|
||||
padding: 1px 8px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: none;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplParams {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
color: #606060;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.search { color: #003399;
|
||||
font-weight: bold;
|
||||
}
|
||||
FORM.search {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
INPUT.search { font-size: 75%;
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
background-color: #eeeeff;
|
||||
}
|
||||
TD.tiny { font-size: 75%;
|
||||
}
|
||||
a {
|
||||
color: #252E78;
|
||||
}
|
||||
a:visited {
|
||||
color: #3D2185;
|
||||
}
|
||||
.dirtab { padding: 4px;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #b0b0b0;
|
||||
}
|
||||
TH.dirtab { background: #eeeeff;
|
||||
font-weight: bold;
|
||||
}
|
||||
HR { height: 1px;
|
||||
border: none;
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
/*
|
||||
* LLVM Modifications.
|
||||
* Note: Everything above here is generated with "doxygen -w htlm" command. See
|
||||
* "doxygen --help" for details. What follows are CSS overrides for LLVM
|
||||
* specific formatting. We want to keep the above so it can be replaced with
|
||||
* subsequent doxygen upgrades.
|
||||
*/
|
||||
|
||||
.footer {
|
||||
font-size: 80%;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.title {
|
||||
font-size: 25pt;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
border-width: 1px;
|
||||
border-style: solid none solid none;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
padding-left: 8pt;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 2px
|
||||
}
|
||||
A:link {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-weight: bolder;
|
||||
}
|
||||
A:visited {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
font-weight: bolder;
|
||||
}
|
||||
A:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
font-weight: bolder;
|
||||
}
|
||||
A:active {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
font-weight: bolder;
|
||||
font-style: italic;
|
||||
}
|
||||
H1 {
|
||||
text-align: center;
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
}
|
||||
H2 {
|
||||
font-size: 120%;
|
||||
font-style: italic;
|
||||
}
|
||||
H3 {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
H2, H3 {
|
||||
border-bottom: 2px solid;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
A.qindex {}
|
||||
A.qindexRef {}
|
||||
A.el { text-decoration: none; font-weight: bold }
|
||||
A.elRef { font-weight: bold }
|
||||
A.code { text-decoration: none; font-weight: normal; color: #4444ee }
|
||||
A.codeRef { font-weight: normal; color: #4444ee }
|
||||
|
||||
div.memitem {
|
||||
border: 1px solid #999999;
|
||||
margin-top: 1.0em;
|
||||
margin-bottom: 1.0em;
|
||||
-webkit-border-radius: 0.5em;
|
||||
-webkit-box-shadow: 3px 3px 6px #777777;
|
||||
-moz-border-radius: 0.5em;
|
||||
-moz-box-shadow: black 3px 3px 3px;
|
||||
}
|
||||
|
||||
div.memproto {
|
||||
background-color: #E3E4E5;
|
||||
padding: 0.25em 0.5em;
|
||||
-webkit-border-top-left-radius: 0.5em;
|
||||
-webkit-border-top-right-radius: 0.5em;
|
||||
-moz-border-radius-topleft: 0.5em;
|
||||
-moz-border-radius-topright: 0.5em;
|
||||
}
|
||||
|
||||
div.memdoc {
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<hr>
|
||||
<p class="footer">
|
||||
Generated on $datetime for <a href="http://llvm.org/">$projectname</a> by
|
||||
<a href="http://www.doxygen.org"><img src="doxygen.png" alt="Doxygen"
|
||||
align="middle" border="0"/>$doxygenversion</a><br>
|
||||
Copyright © 2003-2014 University of Illinois at Urbana-Champaign.
|
||||
All Rights Reserved.</p>
|
||||
|
||||
<hr>
|
||||
<!--#include virtual="/attrib.incl" -->
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,9 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
|
||||
<meta name="keywords" content="LLVM,Low Level Virtual Machine,C++,doxygen,API,documentation"/>
|
||||
<meta name="description" content="C++ source code API documentation for LLVM."/>
|
||||
<title>LLVM: $title</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
|
||||
</head><body>
|
||||
<p class="title">LLVM API Documentation</p>
|
@ -1,6 +1,11 @@
|
||||
Overview
|
||||
========
|
||||
|
||||
.. warning::
|
||||
|
||||
If you are using a released version of LLVM, see `the download page
|
||||
<http://llvm.org/releases/>`_ to find your documentation.
|
||||
|
||||
The LLVM compiler infrastructure supports a wide range of projects, from
|
||||
industrial strength compilers to specialized JIT applications to small
|
||||
research projects.
|
||||
@ -65,6 +70,7 @@ representation.
|
||||
CommandGuide/index
|
||||
GettingStarted
|
||||
GettingStartedVS
|
||||
BuildingLLVMWithAutotools
|
||||
FAQ
|
||||
Lexicon
|
||||
HowToAddABuilder
|
||||
@ -78,6 +84,7 @@ representation.
|
||||
Passes
|
||||
YamlIO
|
||||
GetElementPtr
|
||||
Frontend/PerformanceTips
|
||||
MCJITDesignAndImplementation
|
||||
|
||||
:doc:`GettingStarted`
|
||||
@ -99,6 +106,10 @@ representation.
|
||||
An addendum to the main Getting Started guide for those using Visual Studio
|
||||
on Windows.
|
||||
|
||||
:doc:`BuildingLLVMWithAutotools`
|
||||
An addendum to the Getting Started guide with instructions for building LLVM
|
||||
with the Autotools build system.
|
||||
|
||||
:doc:`tutorial/index`
|
||||
Tutorials about using LLVM. Includes a tutorial about making a custom
|
||||
language with LLVM.
|
||||
@ -145,6 +156,11 @@ representation.
|
||||
Answers to some very frequent questions about LLVM's most frequently
|
||||
misunderstood instruction.
|
||||
|
||||
:doc:`Frontend/PerformanceTips`
|
||||
A collection of tips for frontend authors on how to generate IR
|
||||
which LLVM is able to effectively optimize.
|
||||
|
||||
|
||||
Programming Documentation
|
||||
=========================
|
||||
|
||||
@ -161,6 +177,7 @@ For developers of applications which use LLVM as a library.
|
||||
HowToSetUpLLVMStyleRTTI
|
||||
ProgrammersManual
|
||||
Extensions
|
||||
LibFuzzer
|
||||
|
||||
:doc:`LLVM Language Reference Manual <LangRef>`
|
||||
Defines the LLVM intermediate representation and the assembly form of the
|
||||
@ -202,6 +219,9 @@ For developers of applications which use LLVM as a library.
|
||||
:doc:`CompilerWriterInfo`
|
||||
A list of helpful links for compiler writers.
|
||||
|
||||
:doc:`LibFuzzer`
|
||||
A library for writing in-process guided fuzzers.
|
||||
|
||||
Subsystem Documentation
|
||||
=======================
|
||||
|
||||
@ -239,6 +259,7 @@ For API clients and LLVM developers.
|
||||
CoverageMappingFormat
|
||||
Statepoints
|
||||
MergeFunctions
|
||||
BitSets
|
||||
|
||||
:doc:`WritingAnLLVMPass`
|
||||
Information on how to write LLVM transformations and analyses.
|
||||
@ -338,6 +359,9 @@ For API clients and LLVM developers.
|
||||
:doc:`MergeFunctions`
|
||||
Describes functions merging optimization.
|
||||
|
||||
:doc:`InAlloca`
|
||||
Description of the ``inalloca`` argument attribute.
|
||||
|
||||
Development Process Documentation
|
||||
=================================
|
||||
|
||||
|
@ -73,14 +73,21 @@ in the various pieces. The structure of the tutorial is:
|
||||
about this is how easy and trivial it is to construct SSA form in
|
||||
LLVM: no, LLVM does *not* require your front-end to construct SSA
|
||||
form!
|
||||
- `Chapter #8 <LangImpl8.html>`_: Conclusion and other useful LLVM
|
||||
- `Chapter #8 <LangImpl8.html>`_: Extending the Language: Debug
|
||||
Information - Having built a decent little programming language with
|
||||
control flow, functions and mutable variables, we consider what it
|
||||
takes to add debug information to standalone executables. This debug
|
||||
information will allow you to set breakpoints in Kaleidoscope
|
||||
functions, print out argument variables, and call functions - all
|
||||
from within the debugger!
|
||||
- `Chapter #9 <LangImpl8.html>`_: Conclusion and other useful LLVM
|
||||
tidbits - This chapter wraps up the series by talking about
|
||||
potential ways to extend the language, but also includes a bunch of
|
||||
pointers to info about "special topics" like adding garbage
|
||||
collection support, exceptions, debugging, support for "spaghetti
|
||||
stacks", and a bunch of other tips and tricks.
|
||||
|
||||
By the end of the tutorial, we'll have written a bit less than 700 lines
|
||||
By the end of the tutorial, we'll have written a bit less than 1000 lines
|
||||
of non-comment, non-blank, lines of code. With this small amount of
|
||||
code, we'll have built up a very reasonable compiler for a non-trivial
|
||||
language including a hand-written lexer, parser, AST, as well as code
|
||||
|
@ -85,7 +85,7 @@ structure that the LLVM IR uses to contain code.
|
||||
|
||||
The ``Builder`` object is a helper object that makes it easy to generate
|
||||
LLVM instructions. Instances of the
|
||||
```IRBuilder`` <http://llvm.org/doxygen/IRBuilder_8h-source.html>`_
|
||||
`IRBuilder <http://llvm.org/doxygen/IRBuilder_8h-source.html>`_
|
||||
class template keep track of the current place to insert instructions
|
||||
and has methods to create new instructions.
|
||||
|
||||
|
@ -254,7 +254,7 @@ In `Chapter 7 <LangImpl7.html>`_ of this tutorial ("mutable variables"),
|
||||
we'll talk about #1 in depth. For now, just believe me that you don't
|
||||
need SSA construction to handle this case. For #2, you have the choice
|
||||
of using the techniques that we will describe for #1, or you can insert
|
||||
Phi nodes directly, if convenient. In this case, it is really really
|
||||
Phi nodes directly, if convenient. In this case, it is really
|
||||
easy to generate the Phi node, so we choose to do it directly.
|
||||
|
||||
Okay, enough of the motivation and overview, lets generate code!
|
||||
@ -388,7 +388,7 @@ code:
|
||||
|
||||
The first two lines here are now familiar: the first adds the "merge"
|
||||
block to the Function object (it was previously floating, like the else
|
||||
block above). The second block changes the insertion point so that newly
|
||||
block above). The second changes the insertion point so that newly
|
||||
created code will go into the "merge" block. Once that is done, we need
|
||||
to create the PHI node and set up the block/value pairs for the PHI.
|
||||
|
||||
|
@ -632,7 +632,7 @@ own local variables, lets add this next!
|
||||
User-defined Local Variables
|
||||
============================
|
||||
|
||||
Adding var/in is just like any other other extensions we made to
|
||||
Adding var/in is just like any other extension we made to
|
||||
Kaleidoscope: we extend the lexer, the parser, the AST and the code
|
||||
generator. The first step for adding our new 'var/in' construct is to
|
||||
extend the lexer. As before, this is pretty trivial, the code looks like
|
||||
@ -856,5 +856,5 @@ Here is the code:
|
||||
.. literalinclude:: ../../examples/Kaleidoscope/Chapter7/toy.cpp
|
||||
:language: c++
|
||||
|
||||
`Next: Conclusion and other useful LLVM tidbits <LangImpl8.html>`_
|
||||
`Next: Adding Debug Information <LangImpl8.html>`_
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
=======================================================
|
||||
Kaleidoscope: Extending the Language: Debug Information
|
||||
=======================================================
|
||||
======================================
|
||||
Kaleidoscope: Adding Debug Information
|
||||
======================================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
@ -187,13 +187,13 @@ expressions:
|
||||
static DIBuilder *DBuilder;
|
||||
|
||||
struct DebugInfo {
|
||||
DICompileUnit TheCU;
|
||||
DIType DblTy;
|
||||
DICompileUnit *TheCU;
|
||||
DIType *DblTy;
|
||||
|
||||
DIType getDoubleTy();
|
||||
DIType *getDoubleTy();
|
||||
} KSDbgInfo;
|
||||
|
||||
DIType DebugInfo::getDoubleTy() {
|
||||
DIType *DebugInfo::getDoubleTy() {
|
||||
if (DblTy.isValid())
|
||||
return DblTy;
|
||||
|
||||
@ -245,26 +245,26 @@ So the context:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
|
||||
KSDbgInfo.TheCU.getDirectory());
|
||||
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
|
||||
KSDbgInfo.TheCU.getDirectory());
|
||||
|
||||
giving us a DIFile and asking the ``Compile Unit`` we created above for the
|
||||
giving us an DIFile and asking the ``Compile Unit`` we created above for the
|
||||
directory and filename where we are currently. Then, for now, we use some
|
||||
source locations of 0 (since our AST doesn't currently have source location
|
||||
information) and construct our function definition:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
DIDescriptor FContext(Unit);
|
||||
DIScope *FContext = Unit;
|
||||
unsigned LineNo = 0;
|
||||
unsigned ScopeLine = 0;
|
||||
DISubprogram SP = DBuilder->createFunction(
|
||||
DISubprogram *SP = DBuilder->createFunction(
|
||||
FContext, Name, StringRef(), Unit, LineNo,
|
||||
CreateFunctionType(Args.size(), Unit), false /* internal linkage */,
|
||||
true /* definition */, ScopeLine, DIDescriptor::FlagPrototyped, false, F);
|
||||
true /* definition */, ScopeLine, DINode::FlagPrototyped, false, F);
|
||||
|
||||
and we now have a DISubprogram that contains a reference to all of our metadata
|
||||
for the function.
|
||||
and we now have an DISubprogram that contains a reference to all of our
|
||||
metadata for the function.
|
||||
|
||||
Source Locations
|
||||
================
|
||||
@ -332,11 +332,11 @@ by constructing another small function:
|
||||
void DebugInfo::emitLocation(ExprAST *AST) {
|
||||
DIScope *Scope;
|
||||
if (LexicalBlocks.empty())
|
||||
Scope = &TheCU;
|
||||
Scope = TheCU;
|
||||
else
|
||||
Scope = LexicalBlocks.back();
|
||||
Builder.SetCurrentDebugLocation(
|
||||
DebugLoc::get(AST->getLine(), AST->getCol(), DIScope(*Scope)));
|
||||
DebugLoc::get(AST->getLine(), AST->getCol(), Scope));
|
||||
}
|
||||
|
||||
that both tells the main ``IRBuilder`` where we are, but also what scope
|
||||
@ -348,10 +348,10 @@ of scopes:
|
||||
.. code-block:: c++
|
||||
|
||||
std::vector<DIScope *> LexicalBlocks;
|
||||
std::map<const PrototypeAST *, DIScope> FnScopeMap;
|
||||
std::map<const PrototypeAST *, DIScope *> FnScopeMap;
|
||||
|
||||
and keep a map of each function to the scope that it represents (a DISubprogram
|
||||
is also a DIScope).
|
||||
and keep a map of each function to the scope that it represents (an
|
||||
DISubprogram is also an DIScope).
|
||||
|
||||
Then we make sure to:
|
||||
|
||||
@ -393,15 +393,15 @@ argument allocas in ``PrototypeAST::CreateArgumentAllocas``.
|
||||
.. code-block:: c++
|
||||
|
||||
DIScope *Scope = KSDbgInfo.LexicalBlocks.back();
|
||||
DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
|
||||
KSDbgInfo.TheCU.getDirectory());
|
||||
DIVariable D = DBuilder->createLocalVariable(dwarf::DW_TAG_arg_variable,
|
||||
*Scope, Args[Idx], Unit, Line,
|
||||
KSDbgInfo.getDoubleTy(), Idx);
|
||||
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
|
||||
KSDbgInfo.TheCU.getDirectory());
|
||||
DILocalVariable D = DBuilder->createLocalVariable(
|
||||
dwarf::DW_TAG_arg_variable, Scope, Args[Idx], Unit, Line,
|
||||
KSDbgInfo.getDoubleTy(), Idx);
|
||||
|
||||
Instruction *Call = DBuilder->insertDeclare(
|
||||
Alloca, D, DBuilder->createExpression(), Builder.GetInsertBlock());
|
||||
Call->setDebugLoc(DebugLoc::get(Line, 0, *Scope));
|
||||
Call->setDebugLoc(DebugLoc::get(Line, 0, Scope));
|
||||
|
||||
Here we're doing a few things. First, we're grabbing our current scope
|
||||
for the variable so we can say what range of code our variable is valid
|
||||
|
@ -14,9 +14,10 @@ grown our little Kaleidoscope language from being a useless toy, to
|
||||
being a semi-interesting (but probably still useless) toy. :)
|
||||
|
||||
It is interesting to see how far we've come, and how little code it has
|
||||
taken. We built the entire lexer, parser, AST, code generator, and an
|
||||
interactive run-loop (with a JIT!) by-hand in under 700 lines of
|
||||
(non-comment/non-blank) code.
|
||||
taken. We built the entire lexer, parser, AST, code generator, an
|
||||
interactive run-loop (with a JIT!), and emitted debug information in
|
||||
standalone executables - all in under 1000 lines of (non-comment/non-blank)
|
||||
code.
|
||||
|
||||
Our little language supports a couple of interesting features: it
|
||||
supports user defined binary and unary operators, it uses JIT
|
||||
@ -68,12 +69,6 @@ For example, try adding:
|
||||
collection, note that LLVM fully supports `Accurate Garbage
|
||||
Collection <../GarbageCollection.html>`_ including algorithms that
|
||||
move objects and need to scan/update the stack.
|
||||
- **debugger support** - LLVM supports generation of `DWARF Debug
|
||||
info <../SourceLevelDebugging.html>`_ which is understood by common
|
||||
debuggers like GDB. Adding support for debug info is fairly
|
||||
straightforward. The best way to understand it is to compile some
|
||||
C/C++ code with "``clang -g -O0``" and taking a look at what it
|
||||
produces.
|
||||
- **exception handling support** - LLVM supports generation of `zero
|
||||
cost exceptions <../ExceptionHandling.html>`_ which interoperate with
|
||||
code compiled in other languages. You could also generate code by
|
||||
|
@ -65,7 +65,7 @@ the top-level structure that the LLVM IR uses to contain code.
|
||||
|
||||
The ``Codegen.builder`` object is a helper object that makes it easy to
|
||||
generate LLVM instructions. Instances of the
|
||||
```IRBuilder`` <http://llvm.org/doxygen/IRBuilder_8h-source.html>`_
|
||||
`IRBuilder <http://llvm.org/doxygen/IRBuilder_8h-source.html>`_
|
||||
class keep track of the current place to insert instructions and has
|
||||
methods to create new instructions.
|
||||
|
||||
|
@ -336,7 +336,7 @@ for the 'then' block.
|
||||
let phi = build_phi incoming "iftmp" builder in
|
||||
|
||||
The first two lines here are now familiar: the first adds the "merge"
|
||||
block to the Function object. The second block changes the insertion
|
||||
block to the Function object. The second changes the insertion
|
||||
point so that newly created code will go into the "merge" block. Once
|
||||
that is done, we need to create the PHI node and set up the block/value
|
||||
pairs for the PHI.
|
||||
|
@ -163,7 +163,7 @@ void BrainF::header(LLVMContext& C) {
|
||||
};
|
||||
|
||||
Constant *msgptr = ConstantExpr::
|
||||
getGetElementPtr(aberrormsg, gep_params);
|
||||
getGetElementPtr(aberrormsg->getValueType(), aberrormsg, gep_params);
|
||||
|
||||
Value *puts_params[] = {
|
||||
msgptr
|
||||
@ -201,7 +201,8 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb,
|
||||
case SYM_READ:
|
||||
{
|
||||
//%tape.%d = call i32 @getchar()
|
||||
CallInst *getchar_call = builder->CreateCall(getchar_func, tapereg);
|
||||
CallInst *getchar_call =
|
||||
builder->CreateCall(getchar_func, {}, tapereg);
|
||||
getchar_call->setTailCall(false);
|
||||
Value *tape_0 = getchar_call;
|
||||
|
||||
|
@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
|
||||
ExecutionEngine
|
||||
MC
|
||||
MCJIT
|
||||
RuntimeDyld
|
||||
Support
|
||||
nativecodegen
|
||||
)
|
||||
@ -11,8 +12,10 @@ set(LLVM_LINK_COMPONENTS
|
||||
set(LLVM_REQUIRES_EH 1)
|
||||
set(LLVM_REQUIRES_RTTI 1)
|
||||
|
||||
set(LLVM_BUILD_EXAMPLES OFF)
|
||||
|
||||
add_llvm_example(ExceptionDemo
|
||||
ExceptionDemo.cpp
|
||||
)
|
||||
|
||||
set_target_properties(ExceptionDemo PROPERTIES ENABLE_EXPORTS 1)
|
||||
export_executable_symbols(ExceptionDemo)
|
||||
|
@ -48,6 +48,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
@ -56,8 +57,8 @@
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Support/Dwarf.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
@ -1122,14 +1123,11 @@ static llvm::BasicBlock *createCatchBlock(llvm::LLVMContext &context,
|
||||
/// @param numExceptionsToCatch length of exceptionTypesToCatch array
|
||||
/// @param exceptionTypesToCatch array of type info types to "catch"
|
||||
/// @returns generated function
|
||||
static
|
||||
llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
|
||||
llvm::IRBuilder<> &builder,
|
||||
llvm::FunctionPassManager &fpm,
|
||||
llvm::Function &toInvoke,
|
||||
std::string ourId,
|
||||
unsigned numExceptionsToCatch,
|
||||
unsigned exceptionTypesToCatch[]) {
|
||||
static llvm::Function *createCatchWrappedInvokeFunction(
|
||||
llvm::Module &module, llvm::IRBuilder<> &builder,
|
||||
llvm::legacy::FunctionPassManager &fpm, llvm::Function &toInvoke,
|
||||
std::string ourId, unsigned numExceptionsToCatch,
|
||||
unsigned exceptionTypesToCatch[]) {
|
||||
|
||||
llvm::LLVMContext &context = module.getContext();
|
||||
llvm::Function *toPrint32Int = module.getFunction("print32Int");
|
||||
@ -1295,10 +1293,11 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
|
||||
// (_Unwind_Exception instance). This member tells us whether or not
|
||||
// the exception is foreign.
|
||||
llvm::Value *unwindExceptionClass =
|
||||
builder.CreateLoad(builder.CreateStructGEP(
|
||||
builder.CreatePointerCast(unwindException,
|
||||
ourUnwindExceptionType->getPointerTo()),
|
||||
0));
|
||||
builder.CreateLoad(builder.CreateStructGEP(
|
||||
ourUnwindExceptionType,
|
||||
builder.CreatePointerCast(unwindException,
|
||||
ourUnwindExceptionType->getPointerTo()),
|
||||
0));
|
||||
|
||||
// Branch to the externalExceptionBlock if the exception is foreign or
|
||||
// to a catch router if not. Either way the finally block will be run.
|
||||
@ -1338,10 +1337,10 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
|
||||
//
|
||||
// Note: Index is not relative to pointer but instead to structure
|
||||
// unlike a true getelementptr (GEP) instruction
|
||||
typeInfoThrown = builder.CreateStructGEP(typeInfoThrown, 0);
|
||||
typeInfoThrown = builder.CreateStructGEP(ourExceptionType, typeInfoThrown, 0);
|
||||
|
||||
llvm::Value *typeInfoThrownType =
|
||||
builder.CreateStructGEP(typeInfoThrown, 0);
|
||||
builder.CreateStructGEP(builder.getInt8PtrTy(), typeInfoThrown, 0);
|
||||
|
||||
generateIntegerPrint(context,
|
||||
module,
|
||||
@ -1389,13 +1388,11 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
|
||||
/// @param nativeThrowFunct function which will throw a foreign exception
|
||||
/// if the above nativeThrowType matches generated function's arg.
|
||||
/// @returns generated function
|
||||
static
|
||||
llvm::Function *createThrowExceptionFunction(llvm::Module &module,
|
||||
llvm::IRBuilder<> &builder,
|
||||
llvm::FunctionPassManager &fpm,
|
||||
std::string ourId,
|
||||
int32_t nativeThrowType,
|
||||
llvm::Function &nativeThrowFunct) {
|
||||
static llvm::Function *
|
||||
createThrowExceptionFunction(llvm::Module &module, llvm::IRBuilder<> &builder,
|
||||
llvm::legacy::FunctionPassManager &fpm,
|
||||
std::string ourId, int32_t nativeThrowType,
|
||||
llvm::Function &nativeThrowFunct) {
|
||||
llvm::LLVMContext &context = module.getContext();
|
||||
namedValues.clear();
|
||||
ArgTypes unwindArgTypes;
|
||||
@ -1508,10 +1505,10 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos,
|
||||
/// @param nativeThrowFunctName name of external function which will throw
|
||||
/// a foreign exception
|
||||
/// @returns outermost generated test function.
|
||||
llvm::Function *createUnwindExceptionTest(llvm::Module &module,
|
||||
llvm::IRBuilder<> &builder,
|
||||
llvm::FunctionPassManager &fpm,
|
||||
std::string nativeThrowFunctName) {
|
||||
llvm::Function *
|
||||
createUnwindExceptionTest(llvm::Module &module, llvm::IRBuilder<> &builder,
|
||||
llvm::legacy::FunctionPassManager &fpm,
|
||||
std::string nativeThrowFunctName) {
|
||||
// Number of type infos to generate
|
||||
unsigned numTypeInfos = 6;
|
||||
|
||||
@ -1577,7 +1574,7 @@ public:
|
||||
std::runtime_error::operator=(toCopy)));
|
||||
}
|
||||
|
||||
virtual ~OurCppRunException (void) throw () {}
|
||||
~OurCppRunException(void) throw() override {}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@ -1971,13 +1968,12 @@ int main(int argc, char *argv[]) {
|
||||
llvm::ExecutionEngine *executionEngine = factory.create();
|
||||
|
||||
{
|
||||
llvm::FunctionPassManager fpm(module);
|
||||
llvm::legacy::FunctionPassManager fpm(module);
|
||||
|
||||
// Set up the optimizer pipeline.
|
||||
// Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
module->setDataLayout(executionEngine->getDataLayout());
|
||||
fpm.add(new llvm::DataLayoutPass());
|
||||
module->setDataLayout(*executionEngine->getDataLayout());
|
||||
|
||||
// Optimizations turned on
|
||||
#ifdef ADD_OPT_PASSES
|
||||
|
@ -34,6 +34,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
|
@ -13,3 +13,4 @@ add_subdirectory(Chapter5)
|
||||
add_subdirectory(Chapter6)
|
||||
add_subdirectory(Chapter7)
|
||||
add_subdirectory(Chapter8)
|
||||
add_subdirectory(Orc)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user