Vendor import of llvm trunk r321017:

https://llvm.org/svn/llvm-project/llvm/trunk@321017
This commit is contained in:
Dimitry Andric 2017-12-18 20:10:56 +00:00
parent eb70dddbd7
commit 044eb2f6af
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/llvm/dist/; revision=326938
svn path=/vendor/llvm/llvm-trunk-r321017/; revision=326939; tag=vendor/llvm/llvm-trunk-r321017
9742 changed files with 815146 additions and 299697 deletions

12
.gitattributes vendored Normal file
View File

@ -0,0 +1,12 @@
# binary files
test/Object/Inputs/*.a-* binary
test/tools/dsymutil/Inputs/* binary
test/tools/llvm-ar/Inputs/*.lib binary
test/tools/llvm-objdump/Inputs/*.a binary
test/tools/llvm-rc/Inputs/* binary
test/tools/llvm-strings/Inputs/numbers binary
test/MC/AsmParser/incbin_abcd binary
test/YAMLParser/spec-09-02.test binary
# Windows line ending test
test/MC/AsmParser/preserve-comments-crlf.s text eol=crlf

View File

@ -2,41 +2,32 @@
cmake_minimum_required(VERSION 3.4.3)
if(POLICY CMP0022)
cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required
endif()
cmake_policy(SET CMP0022 NEW)
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()
cmake_policy(SET CMP0048 NEW)
if(POLICY CMP0057)
cmake_policy(SET CMP0057 NEW)
endif()
# 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)
cmake_policy(SET CMP0056 NEW)
cmake_policy(SET CMP0057 NEW)
if(NOT DEFINED LLVM_VERSION_MAJOR)
set(LLVM_VERSION_MAJOR 5)
set(LLVM_VERSION_MAJOR 6)
endif()
if(NOT DEFINED LLVM_VERSION_MINOR)
set(LLVM_VERSION_MINOR 0)
endif()
if(NOT DEFINED LLVM_VERSION_PATCH)
set(LLVM_VERSION_PATCH 1)
set(LLVM_VERSION_PATCH 0)
endif()
if(NOT DEFINED LLVM_VERSION_SUFFIX)
set(LLVM_VERSION_SUFFIX "")
endif()
if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW)
set(cmake_3_0_PROJ_VERSION
VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH})
set(cmake_3_0_LANGUAGES LANGUAGES)
set(LLVM_VERSION_SUFFIX svn)
endif()
if (NOT PACKAGE_VERSION)
@ -52,9 +43,8 @@ if ((CMAKE_GENERATOR MATCHES "Visual Studio") AND (CMAKE_GENERATOR_TOOLSET STREQ
endif()
project(LLVM
${cmake_3_0_PROJ_VERSION}
${cmake_3_0_LANGUAGES}
C CXX ASM)
VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}
LANGUAGES C CXX ASM)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "No build type selected, default to Debug")
@ -120,7 +110,7 @@ endif()
# LLVM_EXTERNAL_${project}_SOURCE_DIR using LLVM_ALL_PROJECTS
# This allows an easy way of setting up a build directory for llvm and another
# one for llvm+clang+... using the same sources.
set(LLVM_ALL_PROJECTS "clang;libcxx;libcxxabi;lldb;compiler-rt;lld;polly")
set(LLVM_ALL_PROJECTS "clang;libcxx;libcxxabi;lldb;compiler-rt;lld;polly;debuginfo-tests")
set(LLVM_ENABLE_PROJECTS "" CACHE STRING
"Semicolon-separated list of projects to build (${LLVM_ALL_PROJECTS}), or \"all\".")
if( LLVM_ENABLE_PROJECTS STREQUAL "all" )
@ -176,12 +166,11 @@ if(LLVM_DEPENDENCY_DEBUGGING)
endif()
endif()
option(LLVM_BUILD_GLOBAL_ISEL "Experimental: Build GlobalISel" ON)
if(LLVM_BUILD_GLOBAL_ISEL)
add_definitions(-DLLVM_BUILD_GLOBAL_ISEL)
endif()
option(LLVM_ENABLE_DAGISEL_COV "Debug: Prints tablegen patterns that were used for selecting" OFF)
option(LLVM_ENABLE_GISEL_COV "Enable collection of GlobalISel rule coverage" OFF)
if(LLVM_ENABLE_GISEL_COV)
set(LLVM_GISEL_COV_PREFIX "${CMAKE_BINARY_DIR}/gisel-coverage-" CACHE STRING "Provide a filename prefix to collect the GlobalISel rule coverage")
endif()
# Add path for custom modules
set(CMAKE_MODULE_PATH
@ -194,6 +183,9 @@ set(CMAKE_MODULE_PATH
# for use by clang_complete, YouCompleteMe, etc.
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
option(LLVM_INSTALL_BINUTILS_SYMLINKS
"Install symlinks from the binutils tool names to the corresponding LLVM tools." OFF)
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)
@ -242,11 +234,11 @@ endif()
include(CPack)
# Sanity check our source directory to make sure that we are not trying to
# generate an in-tree build (unless on MSVC_IDE, where it is ok), and to make
# generate an in-source build (unless on MSVC_IDE, where it is ok), and to make
# sure that we don't have any stray generated files lying around in the tree
# (which would end up getting picked up by header search, instead of the correct
# versions).
if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
if( CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE )
message(FATAL_ERROR "In-source builds are not allowed.
CMake would overwrite the makefiles distributed with LLVM.
Please create a directory and run cmake from there, passing the path
@ -359,6 +351,8 @@ set(LLVM_TARGET_ARCH "host"
option(LLVM_ENABLE_TERMINFO "Use terminfo database if available." ON)
set(LLVM_ENABLE_LIBXML2 "ON" CACHE STRING "Use libxml2 if available. Can be ON, OFF, or FORCE_ON")
option(LLVM_ENABLE_LIBEDIT "Use libedit if available." ON)
option(LLVM_ENABLE_THREADS "Use threads if available." ON)
@ -391,6 +385,8 @@ option(LLVM_ENABLE_LLD "Use lld as C and C++ linker." OFF)
option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
option(LLVM_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
option(LLVM_ENABLE_DUMP "Enable dump functions even when assertions are disabled" OFF)
if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
option(LLVM_ENABLE_ASSERTIONS "Enable assertions" OFF)
else()
@ -432,6 +428,8 @@ endif( LLVM_USE_OPROFILE )
set(LLVM_USE_SANITIZER "" CACHE STRING
"Define the sanitizer used to build binaries and tests.")
set(LLVM_LIB_FUZZING_ENGINE "" CACHE PATH
"Path to fuzzing library for linking with fuzz targets")
option(LLVM_USE_SPLIT_DWARF
"Use -gsplit-dwarf when compiling llvm." OFF)
@ -551,7 +549,8 @@ else()
set(LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION FALSE CACHE INTERNAL "For Visual Studio 2013, manually copy natvis files to Documents\\Visual Studio 2013\\Visualizers" FORCE)
endif()
if (LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE)
if (LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE OR
LLVM_ENABLE_IR_PGO)
if(NOT LLVM_PROFILE_MERGE_POOL_SIZE)
# A pool size of 1-2 is probably sufficient on a SSD. 3-4 should be fine
# for spining disks. Anything higher may only help on slower mediums.
@ -559,10 +558,9 @@ if (LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE)
endif()
if(NOT LLVM_PROFILE_FILE_PATTERN)
if(NOT LLVM_PROFILE_DATA_DIR)
file(TO_NATIVE_PATH "${LLVM_BINARY_DIR}/profiles/%${LLVM_PROFILE_MERGE_POOL_SIZE}m.profraw" LLVM_PROFILE_FILE_PATTERN)
else()
file(TO_NATIVE_PATH "${LLVM_PROFILE_DATA_DIR}/%${LLVM_PROFILE_MERGE_POOL_SIZE}m.profraw" LLVM_PROFILE_FILE_PATTERN)
file(TO_NATIVE_PATH "${LLVM_BINARY_DIR}/profiles" LLVM_PROFILE_DATA_DIR)
endif()
file(TO_NATIVE_PATH "${LLVM_PROFILE_DATA_DIR}/%${LLVM_PROFILE_MERGE_POOL_SIZE}m.profraw" LLVM_PROFILE_FILE_PATTERN)
endif()
endif()
@ -680,9 +678,13 @@ foreach(t ${LLVM_TARGETS_TO_BUILD})
list(FIND LLVM_ALL_TARGETS ${t} idx)
list(FIND LLVM_EXPERIMENTAL_TARGETS_TO_BUILD ${t} idy)
# At this point, LLVMBUILDTOOL already checked all the targets passed in
# LLVM_TARGETS_TO_BUILD and LLVM_EXPERIMENTAL_TARGETS_TO_BUILD, so
# this test just makes sure that any experimental targets were passed via
# LLVM_EXPERIMENTAL_TARGETS_TO_BUILD, not LLVM_TARGETS_TO_BUILD.
if( idx LESS 0 AND idy LESS 0 )
message(FATAL_ERROR "The target `${t}' does not exist.
It should be one of\n${LLVM_ALL_TARGETS}")
message(FATAL_ERROR "The target `${t}' is experimental and must be passed "
"via LLVM_EXPERIMENTAL_TARGETS_TO_BUILD.")
else()
set(LLVM_ENUM_TARGETS "${LLVM_ENUM_TARGETS}LLVM_TARGET(${t})\n")
endif()
@ -757,6 +759,7 @@ configure_file(
add_custom_target(srpm
COMMAND cpack -G TGZ --config CPackSourceConfig.cmake -B ${LLVM_SRPM_DIR}/SOURCES
COMMAND rpmbuild -bs --define '_topdir ${LLVM_SRPM_DIR}' ${LLVM_SRPM_BINARY_SPECFILE})
set_target_properties(srpm PROPERTIES FOLDER "Misc")
# They are not referenced. See set_output_directory().
@ -792,14 +795,14 @@ if(LLVM_USE_HOST_TOOLS)
include(CrossCompile)
endif(LLVM_USE_HOST_TOOLS)
if(LLVM_TARGET_IS_CROSSCOMPILE_HOST)
# Dummy use to avoid CMake Wraning: Manually-specified variables were not used
# Dummy use to avoid CMake Warning: Manually-specified variables were not used
# (this is a variable that CrossCompile sets on recursive invocations)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)")
# On FreeBSD, /usr/local/* is not used by default. In order to build LLVM
# with libxml2, iconv.h, etc., we must add /usr/local paths.
include_directories("/usr/local/include")
include_directories(SYSTEM "/usr/local/include")
link_directories("/usr/local/lib")
endif(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)")
@ -839,15 +842,6 @@ add_subdirectory(lib/TableGen)
add_subdirectory(utils/TableGen)
# Force target to be built as soon as possible. Clang modules builds depend
# header-wise on it as they ship all headers from the umbrella folders. Building
# an entire module might include header, which depends on intrinsics_gen. This
# should be right after LLVMSupport and LLVMTableGen otherwise we introduce a
# circular dependence.
if (LLVM_ENABLE_MODULES)
list(APPEND LLVM_COMMON_DEPENDS intrinsics_gen)
endif(LLVM_ENABLE_MODULES)
add_subdirectory(include/llvm)
add_subdirectory(lib)
@ -857,7 +851,6 @@ if( LLVM_INCLUDE_UTILS )
add_subdirectory(utils/PerfectShuffle)
add_subdirectory(utils/count)
add_subdirectory(utils/not)
add_subdirectory(utils/llvm-lit)
add_subdirectory(utils/yaml-bench)
else()
if ( LLVM_INCLUDE_TESTS )
@ -900,6 +893,7 @@ if( LLVM_INCLUDE_TESTS )
NO_INSTALL
ALWAYS_CLEAN)
endif()
add_subdirectory(utils/lit)
add_subdirectory(test)
add_subdirectory(unittests)
if( LLVM_INCLUDE_UTILS )
@ -943,6 +937,11 @@ endif()
add_subdirectory(cmake/modules)
# Do this last so that all lit targets have already been created.
if (LLVM_INCLUDE_UTILS)
add_subdirectory(utils/llvm-lit)
endif()
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
install(DIRECTORY include/llvm include/llvm-c
DESTINATION include
@ -973,13 +972,11 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
# Installing the headers needs to depend on generating any public
# tablegen'd headers.
add_custom_target(llvm-headers DEPENDS intrinsics_gen)
set_target_properties(llvm-headers PROPERTIES FOLDER "Misc")
if (NOT CMAKE_CONFIGURATION_TYPES)
add_custom_target(install-llvm-headers
DEPENDS llvm-headers
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=llvm-headers
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
add_llvm_install_targets(install-llvm-headers
COMPONENT llvm-headers)
endif()
endif()
@ -992,22 +989,32 @@ if(LLVM_DISTRIBUTION_COMPONENTS)
add_custom_target(distribution)
add_custom_target(install-distribution)
add_custom_target(install-distribution-stripped)
foreach(target ${LLVM_DISTRIBUTION_COMPONENTS})
if(TARGET ${target})
add_dependencies(distribution ${target})
else()
message(FATAL_ERROR "Specified distribution component '${target}' doesn't have a target")
message(SEND_ERROR "Specified distribution component '${target}' doesn't have a target")
endif()
if(TARGET install-${target})
add_dependencies(install-distribution install-${target})
else()
message(FATAL_ERROR "Specified distribution component '${target}' doesn't have an install target")
message(SEND_ERROR "Specified distribution component '${target}' doesn't have an install target")
endif()
if(TARGET install-${target}-stripped)
add_dependencies(install-distribution-stripped install-${target}-stripped)
else()
message(SEND_ERROR "Specified distribution component '${target}' doesn't have an install-stripped target."
" Its installation target creation should be changed to use add_llvm_install_targets,"
" or you should manually create the 'install-${target}-stripped' target.")
endif()
endforeach()
endif()
# This allows us to deploy the Universal CRT DLLs by passing -DCMAKE_INSTALL_UCRT_LIBRARIES=ON to CMake
if (MSVC)
if (MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
include(InstallRequiredSystemLibraries)
endif()

View File

@ -41,9 +41,13 @@ E: andrey.churbanov@intel.com
D: OpenMP runtime library
N: Greg Clayton
E: gclayton@apple.com
E: clayborg@gmail.com
D: LLDB
N: Pete Couperus
E: petecoup@synopsys.com
D: ARC backend (lib/Target/ARC/*)
N: Sanjoy Das
E: sanjoy@playingwithpointers.com
D: IndVar Simplify, Scalar Evolution
@ -61,7 +65,7 @@ E: qcolombet@apple.com
D: Loop Strength Reduction, Register allocators
N: Simon Dardis
E: simon.dardis@imgtec.com
E: simon.dardis@mips.com
D: MIPS Backend (lib/Target/Mips/*)
N: Duncan P. N. Exon Smith

View File

@ -43,6 +43,10 @@ N: Neil Booth
E: neil@daikokuya.co.uk
D: APFloat implementation.
N: Alex Bradbury
E: asb@lowrisc.org
D: RISC-V backend
N: Misha Brukman
E: brukman+llvm@uiuc.edu
W: http://misha.brukman.net

View File

@ -16,3 +16,4 @@ documentation setup.
If you are writing a package for LLVM, see docs/Packaging.rst for our
suggestions.

View File

@ -47,6 +47,6 @@ T: ARM, AArch64
O: Linux
N: Simon Dardis
E: simon.dardis@imgtec.com
E: simon.dardis@mips.com
T: MIPS
O: Linux

View File

@ -29,25 +29,6 @@ void LLVMDIBuilderDestroy(LLVMDIBuilderRef dref) {
delete d;
}
void LLVMDIBuilderFinalize(LLVMDIBuilderRef dref) { unwrap(dref)->finalize(); }
LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef Dref,
unsigned Lang, const char *File,
const char *Dir,
const char *Producer,
int Optimized, const char *Flags,
unsigned RuntimeVersion) {
DIBuilder *D = unwrap(Dref);
return wrap(D->createCompileUnit(Lang, D->createFile(File, Dir), Producer,
Optimized, Flags, RuntimeVersion));
}
LLVMMetadataRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Dref, const char *File,
const char *Dir) {
DIBuilder *D = unwrap(Dref);
return wrap(D->createFile(File, Dir));
}
LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
LLVMMetadataRef Scope,
LLVMMetadataRef File,
@ -237,7 +218,7 @@ LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref,
}
LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef Dref,
LLVMValueRef Val, uint64_t Offset,
LLVMValueRef Val,
LLVMMetadataRef VarInfo,
LLVMMetadataRef Expr,
LLVMBasicBlockRef Block) {
@ -247,7 +228,7 @@ LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef Dref,
DIBuilder *D = unwrap(Dref);
Instruction *Instr = D->insertDbgValueIntrinsic(
unwrap(Val), Offset, unwrap<DILocalVariable>(VarInfo),
unwrap<DIExpression>(Expr), /* DebugLoc */ nullptr, unwrap(Block));
unwrap(Val), unwrap<DILocalVariable>(VarInfo), unwrap<DIExpression>(Expr),
/* DebugLoc */ nullptr, unwrap(Block));
return wrap(Instr);
}

View File

@ -16,6 +16,7 @@
#include "IRBindings.h"
#include "llvm-c/Core.h"
#include "llvm-c/DebugInfo.h"
#ifdef __cplusplus
extern "C" {
@ -30,16 +31,6 @@ typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef;
LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef m);
void LLVMDIBuilderDestroy(LLVMDIBuilderRef d);
void LLVMDIBuilderFinalize(LLVMDIBuilderRef d);
LLVMMetadataRef
LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef D, unsigned Language,
const char *File, const char *Dir,
const char *Producer, int Optimized,
const char *Flags, unsigned RuntimeVersion);
LLVMMetadataRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef D, const char *File,
const char *Dir);
LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef D,
LLVMMetadataRef Scope,
@ -132,7 +123,6 @@ LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef D,
LLVMBasicBlockRef Block);
LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef D, LLVMValueRef Val,
uint64_t Offset,
LLVMMetadataRef VarInfo,
LLVMMetadataRef Expr,
LLVMBasicBlockRef Block);

View File

@ -132,12 +132,17 @@ func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Metadata {
defer C.free(unsafe.Pointer(flags))
result := C.LLVMDIBuilderCreateCompileUnit(
d.ref,
C.unsigned(cu.Language),
file, dir,
producer,
boolToCInt(cu.Optimized),
flags,
C.LLVMDWARFSourceLanguage(cu.Language),
C.LLVMDIBuilderCreateFile(d.ref, file, C.size_t(len(cu.File)), dir, C.size_t(len(cu.Dir))),
producer, C.size_t(len(cu.Producer)),
C.LLVMBool(boolToCInt(cu.Optimized)),
flags, C.size_t(len(cu.Flags)),
C.unsigned(cu.RuntimeVersion),
/*SplitName=*/ nil, 0,
C.LLVMDWARFEmissionFull,
/*DWOId=*/ 0,
/*SplitDebugInlining*/ C.LLVMBool(boolToCInt(true)),
/*DebugInfoForProfiling*/ C.LLVMBool(boolToCInt(false)),
)
return Metadata{C: result}
}
@ -148,7 +153,9 @@ func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
defer C.free(unsafe.Pointer(cfilename))
cdir := C.CString(dir)
defer C.free(unsafe.Pointer(cdir))
result := C.LLVMDIBuilderCreateFile(d.ref, cfilename, cdir)
result := C.LLVMDIBuilderCreateFile(d.ref,
cfilename, C.size_t(len(filename)),
cdir, C.size_t(len(dir)))
return Metadata{C: result}
}
@ -533,8 +540,8 @@ func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, bb Bas
// InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
// specified basic block for the given value and associated debug metadata.
func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, offset uint64, bb BasicBlock) Value {
result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, C.uint64_t(offset), diVarInfo.C, expr.C, bb.C)
func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value {
result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
return Value{C: result}
}

View File

@ -8,6 +8,7 @@ include(CheckIncludeFileCXX)
include(CheckLibraryExists)
include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckCCompilerFlag)
include(CheckCXXSourceCompiles)
include(TestBigEndian)
@ -126,35 +127,61 @@ if(HAVE_LIBPTHREAD)
set(LLVM_PTHREAD_LIB ${CMAKE_THREAD_LIBS_INIT})
endif()
# Don't look for these libraries on Windows. Also don't look for them if we're
# using MSan, since uninstrumented third party code may call MSan interceptors
# like strlen, leading to false positives.
if( NOT PURE_WINDOWS AND NOT LLVM_USE_SANITIZER MATCHES "Memory.*")
if (LLVM_ENABLE_ZLIB)
check_library_exists(z compress2 "" HAVE_LIBZ)
else()
set(HAVE_LIBZ 0)
endif()
# Skip libedit if using ASan as it contains memory leaks.
if (LLVM_ENABLE_LIBEDIT AND HAVE_HISTEDIT_H AND NOT LLVM_USE_SANITIZER MATCHES ".*Address.*")
check_library_exists(edit el_init "" HAVE_LIBEDIT)
else()
set(HAVE_LIBEDIT 0)
endif()
if(LLVM_ENABLE_TERMINFO)
set(HAVE_TERMINFO 0)
foreach(library tinfo terminfo curses ncurses ncursesw)
# Don't look for these libraries if we're using MSan, since uninstrumented third
# party code may call MSan interceptors like strlen, leading to false positives.
if(NOT LLVM_USE_SANITIZER MATCHES "Memory.*")
set(HAVE_LIBZ 0)
if(LLVM_ENABLE_ZLIB)
foreach(library z zlib_static zlib)
string(TOUPPER ${library} library_suffix)
check_library_exists(${library} setupterm "" HAVE_TERMINFO_${library_suffix})
if(HAVE_TERMINFO_${library_suffix})
set(HAVE_TERMINFO 1)
set(TERMINFO_LIBS "${library}")
check_library_exists(${library} compress2 "" HAVE_LIBZ_${library_suffix})
if(HAVE_LIBZ_${library_suffix})
set(HAVE_LIBZ 1)
set(ZLIB_LIBRARIES "${library}")
break()
endif()
endforeach()
else()
set(HAVE_TERMINFO 0)
endif()
# Don't look for these libraries on Windows.
if (NOT PURE_WINDOWS)
# Skip libedit if using ASan as it contains memory leaks.
if (LLVM_ENABLE_LIBEDIT AND HAVE_HISTEDIT_H AND NOT LLVM_USE_SANITIZER MATCHES ".*Address.*")
check_library_exists(edit el_init "" HAVE_LIBEDIT)
else()
set(HAVE_LIBEDIT 0)
endif()
if(LLVM_ENABLE_TERMINFO)
set(HAVE_TERMINFO 0)
foreach(library tinfo terminfo curses ncurses ncursesw)
string(TOUPPER ${library} library_suffix)
check_library_exists(${library} setupterm "" HAVE_TERMINFO_${library_suffix})
if(HAVE_TERMINFO_${library_suffix})
set(HAVE_TERMINFO 1)
set(TERMINFO_LIBS "${library}")
break()
endif()
endforeach()
else()
set(HAVE_TERMINFO 0)
endif()
find_library(ICONV_LIBRARY_PATH NAMES iconv libiconv libiconv-2 c)
set(LLVM_LIBXML2_ENABLED 0)
set(LIBXML2_FOUND 0)
if((LLVM_ENABLE_LIBXML2) AND ((CMAKE_SYSTEM_NAME MATCHES "Linux") AND (ICONV_LIBRARY_PATH) OR APPLE))
find_package(LibXml2)
if (LIBXML2_FOUND)
set(LLVM_LIBXML2_ENABLED 1)
include_directories(${LIBXML2_INCLUDE_DIR})
set(LIBXML2_LIBS "xml2")
endif()
endif()
endif()
endif()
if (LLVM_ENABLE_LIBXML2 STREQUAL "FORCE_ON" AND NOT LLVM_LIBXML2_ENABLED)
message(FATAL_ERROR "Failed to congifure libxml2")
endif()
check_library_exists(xar xar_open "" HAVE_LIBXAR)
@ -167,6 +194,14 @@ check_symbol_exists(arc4random "stdlib.h" HAVE_DECL_ARC4RANDOM)
find_package(Backtrace)
set(HAVE_BACKTRACE ${Backtrace_FOUND})
set(BACKTRACE_HEADER ${Backtrace_HEADER})
# Prevent check_symbol_exists from using API that is not supported for a given
# deployment target.
check_c_compiler_flag("-Werror=unguarded-availability-new" "C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW")
if(C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unguarded-availability-new")
endif()
check_symbol_exists(_Unwind_Backtrace "unwind.h" HAVE__UNWIND_BACKTRACE)
check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE)
check_symbol_exists(sysconf unistd.h HAVE_SYSCONF)
@ -246,8 +281,11 @@ endif()
check_symbol_exists(__GLIBC__ stdio.h LLVM_USING_GLIBC)
if( LLVM_USING_GLIBC )
add_definitions( -D_GNU_SOURCE )
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
endif()
# This check requires _GNU_SOURCE
check_symbol_exists(sched_getaffinity sched.h HAVE_SCHED_GETAFFINITY)
check_symbol_exists(CPU_COUNT sched.h HAVE_CPU_COUNT)
if(HAVE_LIBPTHREAD)
check_library_exists(pthread pthread_getname_np "" HAVE_PTHREAD_GETNAME_NP)
check_library_exists(pthread pthread_setname_np "" HAVE_PTHREAD_SETNAME_NP)
@ -600,3 +638,34 @@ else()
endif()
string(REPLACE " " ";" LLVM_BINDINGS_LIST "${LLVM_BINDINGS}")
function(find_python_module module)
string(TOUPPER ${module} module_upper)
set(FOUND_VAR PY_${module_upper}_FOUND)
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import ${module}"
RESULT_VARIABLE status
ERROR_QUIET)
if(status)
set(${FOUND_VAR} 0 PARENT_SCOPE)
message(STATUS "Could NOT find Python module ${module}")
else()
set(${FOUND_VAR} 1 PARENT_SCOPE)
message(STATUS "Found Python module ${module}")
endif()
endfunction()
set (PYTHON_MODULES
pygments
yaml
)
foreach(module ${PYTHON_MODULES})
find_python_module(${module})
endforeach()
if(PY_PYGMENTS_FOUND AND PY_YAML_FOUND)
set (LLVM_HAVE_OPT_VIEWER_MODULES 1)
else()
set (LLVM_HAVE_OPT_VIEWER_MODULES 0)
endif()

4
cmake/config.guess vendored
View File

@ -206,10 +206,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;

View File

@ -149,8 +149,13 @@ endfunction(add_llvm_symbol_exports)
if(NOT WIN32 AND NOT APPLE)
# Detect what linker we have here
if( LLVM_USE_LINKER )
set(command ${CMAKE_C_COMPILER} -fuse-ld=${LLVM_USE_LINKER} -Wl,--version)
else()
set(command ${CMAKE_C_COMPILER} -Wl,--version)
endif()
execute_process(
COMMAND ${CMAKE_C_COMPILER} -Wl,--version
COMMAND ${command}
OUTPUT_VARIABLE stdout
ERROR_VARIABLE stderr
)
@ -164,7 +169,8 @@ if(NOT WIN32 AND NOT APPLE)
elseif("${stdout}" MATCHES "GNU ld")
set(LLVM_LINKER_IS_GNULD ON)
message(STATUS "Linker detection: GNU ld")
elseif("${stderr}" MATCHES "Solaris Link Editors")
elseif("${stderr}" MATCHES "Solaris Link Editors" OR
"${stdout}" MATCHES "Solaris Link Editors")
set(LLVM_LINKER_IS_SOLARISLD ON)
message(STATUS "Linker detection: Solaris ld")
else()
@ -263,14 +269,14 @@ endfunction()
#
function(add_windows_version_resource_file OUT_VAR)
set(sources ${ARGN})
if (MSVC)
if (MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(resource_file ${LLVM_SOURCE_DIR}/resources/windows_version_resource.rc)
if(EXISTS ${resource_file})
set(sources ${sources} ${resource_file})
source_group("Resource Files" ${resource_file})
set(windows_resource_file ${resource_file} PARENT_SCOPE)
endif()
endif(MSVC)
endif(MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(${OUT_VAR} ${sources} PARENT_SCOPE)
endfunction(add_windows_version_resource_file)
@ -563,6 +569,32 @@ function(llvm_add_library name)
endif()
endfunction()
function(add_llvm_install_targets target)
cmake_parse_arguments(ARG "" "COMPONENT;PREFIX" "DEPENDS" ${ARGN})
if(ARG_COMPONENT)
set(component_option -DCMAKE_INSTALL_COMPONENT="${ARG_COMPONENT}")
endif()
if(ARG_PREFIX)
set(prefix_option -DCMAKE_INSTALL_PREFIX="${ARG_PREFIX}")
endif()
add_custom_target(${target}
DEPENDS ${ARG_DEPENDS}
COMMAND "${CMAKE_COMMAND}"
${component_option}
${prefix_option}
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
USES_TERMINAL)
add_custom_target(${target}-stripped
DEPENDS ${ARG_DEPENDS}
COMMAND "${CMAKE_COMMAND}"
${component_option}
${prefix_option}
-DCMAKE_INSTALL_DO_STRIP=1
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
USES_TERMINAL)
endfunction()
macro(add_llvm_library name)
cmake_parse_arguments(ARG
"SHARED;BUILDTREE_ONLY"
@ -613,11 +645,9 @@ macro(add_llvm_library name)
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")
add_llvm_install_targets(install-${name}
DEPENDS ${name}
COMPONENT ${name})
endif()
endif()
set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
@ -687,7 +717,7 @@ macro(add_llvm_executable name)
# it forces Xcode to properly link the static library.
list(APPEND ALL_FILES "${LLVM_MAIN_SRC_DIR}/cmake/dummy.cpp")
endif()
if( EXCLUDE_FROM_ALL )
add_executable(${name} EXCLUDE_FROM_ALL ${ALL_FILES})
else()
@ -738,7 +768,7 @@ macro(add_llvm_executable name)
# libpthreads overrides some standard library symbols, so main
# executable must be linked with it in order to provide consistent
# API for all shared libaries loaded by this executable.
target_link_libraries(${name} ${LLVM_PTHREAD_LIB})
target_link_libraries(${name} PRIVATE ${LLVM_PTHREAD_LIB})
endif()
endmacro(add_llvm_executable name)
@ -843,11 +873,9 @@ macro(add_llvm_tool name)
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")
add_llvm_install_targets(install-${name}
DEPENDS ${name}
COMPONENT ${name})
endif()
endif()
endif()
@ -883,15 +911,30 @@ macro(add_llvm_utility name)
RUNTIME DESTINATION ${LLVM_UTILS_INSTALL_DIR}
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")
add_llvm_install_targets(install-${name}
DEPENDS ${name}
COMPONENT ${name})
endif()
endif()
endmacro(add_llvm_utility name)
macro(add_llvm_fuzzer name)
cmake_parse_arguments(ARG "" "DUMMY_MAIN" "" ${ARGN})
if( LLVM_LIB_FUZZING_ENGINE )
set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN})
add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS})
target_link_libraries(${name} PRIVATE ${LLVM_LIB_FUZZING_ENGINE})
set_target_properties(${name} PROPERTIES FOLDER "Fuzzers")
elseif( LLVM_USE_SANITIZE_COVERAGE )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")
set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN})
add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS})
set_target_properties(${name} PROPERTIES FOLDER "Fuzzers")
elseif( ARG_DUMMY_MAIN )
add_llvm_executable(${name} ${ARG_DUMMY_MAIN} ${ARG_UNPARSED_ARGUMENTS})
set_target_properties(${name} PROPERTIES FOLDER "Fuzzers")
endif()
endmacro()
macro(add_llvm_target target_name)
include_directories(BEFORE
@ -1020,6 +1063,13 @@ function(add_unittest test_suite test_name)
set(EXCLUDE_FROM_ALL ON)
endif()
# Our current version of gtest does not properly recognize C++11 support
# with MSVC, so it falls back to tr1 / experimental classes. Since LLVM
# itself requires C++11, we can safely force it on unconditionally so that
# we don't have to fight with the buggy gtest check.
add_definitions(-DGTEST_LANG_CXX11=1)
add_definitions(-DGTEST_HAS_TR1_TUPLE=0)
include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include)
include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock/include)
if (NOT LLVM_ENABLE_THREADS)
@ -1043,7 +1093,7 @@ function(add_unittest test_suite test_name)
# libpthreads overrides some standard library symbols, so main
# executable must be linked with it in order to provide consistent
# API for all shared libaries loaded by this executable.
target_link_libraries(${test_name} gtest_main gtest ${LLVM_PTHREAD_LIB})
target_link_libraries(${test_name} PRIVATE gtest_main gtest ${LLVM_PTHREAD_LIB})
add_dependencies(${test_suite} ${test_name})
get_target_property(test_suite_folder ${test_suite} FOLDER)
@ -1095,12 +1145,31 @@ function(llvm_canonicalize_cmake_booleans)
endforeach()
endfunction(llvm_canonicalize_cmake_booleans)
macro(set_llvm_build_mode)
# Configuration-time: See Unit/lit.site.cfg.in
if (CMAKE_CFG_INTDIR STREQUAL ".")
set(LLVM_BUILD_MODE ".")
else ()
set(LLVM_BUILD_MODE "%(build_mode)s")
endif ()
endmacro()
# This function provides an automatic way to 'configure'-like generate a file
# based on a set of common and custom variables, specifically targeting the
# variables needed for the 'lit.site.cfg' files. This function bundles the
# common variables that any Lit instance is likely to need, and custom
# variables can be passed in.
function(configure_lit_site_cfg input output)
function(configure_lit_site_cfg site_in site_out)
cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;OUTPUT_MAPPING" ${ARGN})
if ("${ARG_MAIN_CONFIG}" STREQUAL "")
get_filename_component(INPUT_DIR ${site_in} DIRECTORY)
set(ARG_MAIN_CONFIG "${INPUT_DIR}/lit.cfg")
endif()
if ("${ARG_OUTPUT_MAPPING}" STREQUAL "")
set(ARG_OUTPUT_MAPPING "${site_out}")
endif()
foreach(c ${LLVM_TARGETS_TO_BUILD})
set(TARGETS_BUILT "${TARGETS_BUILT} ${c}")
endforeach(c)
@ -1108,21 +1177,16 @@ function(configure_lit_site_cfg input output)
set(SHLIBEXT "${LTDL_SHLIB_EXT}")
# Configuration-time: See Unit/lit.site.cfg.in
if (CMAKE_CFG_INTDIR STREQUAL ".")
set(LLVM_BUILD_MODE ".")
else ()
set(LLVM_BUILD_MODE "%(build_mode)s")
endif ()
set_llvm_build_mode()
# They below might not be the build tree but provided binary tree.
set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR})
set(LLVM_BINARY_DIR ${LLVM_BINARY_DIR})
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLVM_TOOLS_DIR ${LLVM_TOOLS_BINARY_DIR})
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLVM_LIBS_DIR ${LLVM_LIBRARY_DIR})
string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}")
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLVM_LIBS_DIR "${LLVM_LIBRARY_DIR}")
# SHLIBDIR points the build tree.
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} SHLIBDIR "${LLVM_SHLIB_OUTPUT_INTDIR}")
string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" SHLIBDIR "${LLVM_SHLIB_OUTPUT_INTDIR}")
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
# FIXME: "ENABLE_SHARED" doesn't make sense, since it is used just for
@ -1146,7 +1210,7 @@ function(configure_lit_site_cfg input output)
set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}")
set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}")
set(LIT_SITE_CFG_IN_HEADER "## Autogenerated from ${input}\n## Do not edit!")
set(LIT_SITE_CFG_IN_HEADER "## Autogenerated from ${site_in}\n## Do not edit!")
# Override config_target_triple (and the env)
if(LLVM_TARGET_TRIPLE_ENV)
@ -1161,7 +1225,74 @@ function(configure_lit_site_cfg input output)
set(TARGET_TRIPLE "\"+config.target_triple+\"")
endif()
configure_file(${input} ${output} @ONLY)
string(CONCAT LIT_SITE_CFG_IN_FOOTER
"import lit.llvm\n"
"lit.llvm.initialize(lit_config, config)\n")
configure_file(${site_in} ${site_out} @ONLY)
if (EXISTS "${ARG_MAIN_CONFIG}")
set(PYTHON_STATEMENT "map_config('${ARG_MAIN_CONFIG}', '${site_out}')")
get_property(LLVM_LIT_CONFIG_MAP GLOBAL PROPERTY LLVM_LIT_CONFIG_MAP)
set(LLVM_LIT_CONFIG_MAP "${LLVM_LIT_CONFIG_MAP}\n${PYTHON_STATEMENT}")
set_property(GLOBAL PROPERTY LLVM_LIT_CONFIG_MAP ${LLVM_LIT_CONFIG_MAP})
endif()
endfunction()
function(dump_all_cmake_variables)
get_cmake_property(_variableNames VARIABLES)
foreach (_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
endfunction()
function(get_llvm_lit_path base_dir file_name)
cmake_parse_arguments(ARG "ALLOW_EXTERNAL" "" "" ${ARGN})
if (ARG_ALLOW_EXTERNAL)
set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_EXTERNAL_LIT}")
set (LLVM_EXTERNAL_LIT "" CACHE STRING "Command used to spawn lit")
if ("${LLVM_EXTERNAL_LIT}" STREQUAL "")
set(LLVM_EXTERNAL_LIT "${LLVM_DEFAULT_EXTERNAL_LIT}")
endif()
if (NOT "${LLVM_EXTERNAL_LIT}" STREQUAL "")
if (EXISTS ${LLVM_EXTERNAL_LIT})
get_filename_component(LIT_FILE_NAME ${LLVM_EXTERNAL_LIT} NAME)
get_filename_component(LIT_BASE_DIR ${LLVM_EXTERNAL_LIT} DIRECTORY)
set(${file_name} ${LIT_FILE_NAME} PARENT_SCOPE)
set(${base_dir} ${LIT_BASE_DIR} PARENT_SCOPE)
return()
else()
message(WARN "LLVM_EXTERNAL_LIT set to ${LLVM_EXTERNAL_LIT}, but the path does not exist.")
endif()
endif()
endif()
set(lit_file_name "llvm-lit")
if (WIN32 AND NOT CYGWIN)
# llvm-lit needs suffix.py for multiprocess to find a main module.
set(lit_file_name "${lit_file_name}.py")
endif ()
set(${file_name} ${lit_file_name} PARENT_SCOPE)
get_property(LLVM_LIT_BASE_DIR GLOBAL PROPERTY LLVM_LIT_BASE_DIR)
if (NOT "${LLVM_LIT_BASE_DIR}" STREQUAL "")
set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE)
endif()
# Allow individual projects to provide an override
if (NOT "${LLVM_LIT_OUTPUT_DIR}" STREQUAL "")
set(LLVM_LIT_BASE_DIR ${LLVM_LIT_OUTPUT_DIR})
elseif(NOT "${LLVM_RUNTIME_OUTPUT_INTDIR}" STREQUAL "")
set(LLVM_LIT_BASE_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
else()
set(LLVM_LIT_BASE_DIR "")
endif()
# Cache this so we don't have to do it again and have subsequent calls
# potentially disagree on the value.
set_property(GLOBAL PROPERTY LLVM_LIT_BASE_DIR ${LLVM_LIT_BASE_DIR})
set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE)
endfunction()
# A raw function to create a lit target. This is used to implement the testuite
@ -1173,12 +1304,16 @@ function(add_lit_target target comment)
if (NOT CMAKE_CFG_INTDIR STREQUAL ".")
list(APPEND LIT_ARGS --param build_mode=${CMAKE_CFG_INTDIR})
endif ()
if (EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
set (LIT_COMMAND "${PYTHON_EXECUTABLE};${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py"
CACHE STRING "Command used to spawn llvm-lit")
else()
find_program(LIT_COMMAND NAMES llvm-lit lit.py lit)
endif ()
# Get the path to the lit to *run* tests with. This can be overriden by
# the user by specifying -DLLVM_EXTERNAL_LIT=<path-to-lit.py>
get_llvm_lit_path(
lit_base_dir
lit_file_name
ALLOW_EXTERNAL
)
set(LIT_COMMAND "${PYTHON_EXECUTABLE};${lit_base_dir}/${lit_file_name}")
list(APPEND LIT_COMMAND ${LIT_ARGS})
foreach(param ${ARG_PARAMS})
list(APPEND LIT_COMMAND --param ${param})
@ -1285,11 +1420,9 @@ function(llvm_install_library_symlink name dest type)
COMPONENT ${component})
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT ARG_ALWAYS_GENERATE)
add_custom_target(install-${name}
DEPENDS ${name} ${dest} install-${dest}
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=${name}
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
add_llvm_install_targets(install-${name}
DEPENDS ${name} ${dest} install-${dest}
COMPONENT ${name})
endif()
endfunction()
@ -1320,11 +1453,9 @@ function(llvm_install_symlink name dest)
COMPONENT ${component})
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT ARG_ALWAYS_GENERATE)
add_custom_target(install-${name}
DEPENDS ${name} ${dest} install-${dest}
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=${name}
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
add_llvm_install_targets(install-${name}
DEPENDS ${name} ${dest} install-${dest}
COMPONENT ${name})
endif()
endfunction()
@ -1338,7 +1469,7 @@ function(add_llvm_tool_symlink link_name target)
# magic. First we grab one of the types, and a type-specific path. Then from
# the type-specific path we find the last occurrence of the type in the path,
# and replace it with CMAKE_CFG_INTDIR. This allows the build step to be type
# agnostic again.
# agnostic again.
if(NOT ARG_OUTPUT_DIR)
# If you're not overriding the OUTPUT_DIR, we can make the link relative in
# the same directory.
@ -1488,3 +1619,36 @@ function(setup_dependency_debugging name)
set(sandbox_command "sandbox-exec -p '(version 1) (allow default) ${deny_attributes_gen} ${deny_intrinsics_gen}'")
set_target_properties(${name} PROPERTIES RULE_LAUNCH_COMPILE ${sandbox_command})
endfunction()
# Figure out if we can track VC revisions.
function(find_first_existing_file out_var)
foreach(file ${ARGN})
if(EXISTS "${file}")
set(${out_var} "${file}" PARENT_SCOPE)
return()
endif()
endforeach()
endfunction()
macro(find_first_existing_vc_file out_var path)
find_program(git_executable NAMES git git.exe git.cmd)
# Run from a subdirectory to force git to print an absolute path.
execute_process(COMMAND ${git_executable} rev-parse --git-dir
WORKING_DIRECTORY ${path}/cmake
RESULT_VARIABLE git_result
OUTPUT_VARIABLE git_dir
ERROR_QUIET)
if(git_result EQUAL 0)
string(STRIP "${git_dir}" git_dir)
set(${out_var} "${git_dir}/logs/HEAD")
# some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD
if (NOT EXISTS "${git_dir}/logs/HEAD")
file(WRITE "${git_dir}/logs/HEAD" "")
endif()
else()
find_first_existing_file(${out_var}
"${path}/.svn/wc.db" # SVN 1.7
"${path}/.svn/entries" # SVN 1.6
)
endif()
endmacro()

View File

@ -221,3 +221,4 @@ add_custom_target(ocaml_make_directory
COMMAND "${CMAKE_COMMAND}" "-E" "make_directory" "${LLVM_LIBRARY_DIR}/ocaml/llvm")
add_custom_target("ocaml_all")
set_target_properties(ocaml_all PROPERTIES FOLDER "Misc")
set_target_properties(ocaml_make_directory PROPERTIES FOLDER "Misc")

View File

@ -19,7 +19,7 @@ endif()
# ``project`` should be the project name
function (add_sphinx_target builder project)
set(SPHINX_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/${builder}")
set(SPHINX_DOC_TREE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees-${builder}")
set(SPHINX_DOC_TREE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees-${project}-${builder}")
set(SPHINX_TARGET_NAME docs-${project}-${builder})
if (SPHINX_WARNINGS_AS_ERRORS)

View File

@ -129,9 +129,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
if (NOT CMAKE_CONFIGURATION_TYPES)
# Add a dummy target so this can be used with LLVM_DISTRIBUTION_COMPONENTS
add_custom_target(cmake-exports)
add_custom_target(install-cmake-exports
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=cmake-exports
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
add_llvm_install_targets(install-cmake-exports
COMPONENT cmake-exports)
endif()
endif()

View File

@ -1,6 +1,7 @@
# atomic builtins are required for threading support.
INCLUDE(CheckCXXSourceCompiles)
INCLUDE(CheckLibraryExists)
# Sometimes linking against libatomic is required for atomic ops, if
# the platform doesn't support lock-free atomics.
@ -80,7 +81,6 @@ endif()
## assumes C++11 <atomic> works.
CHECK_CXX_SOURCE_COMPILES("
#ifdef _MSC_VER
#include <Intrin.h> /* Workaround for PR19898. */
#include <windows.h>
#endif
int main() {

View File

@ -1,8 +1,6 @@
include(CheckCXXCompilerFlag)
function(check_linker_flag flag out_var)
set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${flag}")
check_cxx_compiler_flag("" ${out_var})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
endfunction()

View File

@ -7,52 +7,56 @@ function(llvm_create_cross_target_internal target_name toolchain buildtype)
endif(NOT DEFINED LLVM_${target_name}_BUILD)
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}")
set(CROSS_TOOLCHAIN_FLAGS_INIT
-DCMAKE_TOOLCHAIN_FILE=\"${LLVM_MAIN_SRC_DIR}/cmake/platforms/${toolchain}.cmake\")
else()
set(CROSS_TOOLCHAIN_FLAGS_INIT
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
)
endif()
set(CROSS_TOOLCHAIN_FLAGS_${target_name} ${CROSS_TOOLCHAIN_FLAGS_INIT}
CACHE STRING "Toolchain configuration for ${target_name}")
if (buildtype)
set(build_type_flags "-DCMAKE_BUILD_TYPE=${buildtype}")
endif()
if (LLVM_USE_LINKER AND NOT CMAKE_CROSSCOMPILING)
set(linker_flag "-DLLVM_USE_LINKER=${LLVM_USE_LINKER}")
endif()
if (LLVM_EXTERNAL_CLANG_SOURCE_DIR)
# Propagate LLVM_EXTERNAL_CLANG_SOURCE_DIR so that clang-tblgen can be built
set(external_clang_dir "-DLLVM_EXTERNAL_CLANG_SOURCE_DIR=${LLVM_EXTERNAL_CLANG_SOURCE_DIR}")
endif()
add_custom_command(OUTPUT ${LLVM_${target_name}_BUILD}
COMMAND ${CMAKE_COMMAND} -E make_directory ${LLVM_${target_name}_BUILD}
COMMENT "Creating ${LLVM_${target_name}_BUILD}...")
add_custom_target(CREATE_LLVM_${target_name}
DEPENDS ${LLVM_${target_name}_BUILD})
# Escape semicolons in the targets list so that cmake doesn't expand
# them to spaces.
string(REPLACE ";" "$<SEMICOLON>" targets_to_build_arg
"${LLVM_TARGETS_TO_BUILD}")
string(REPLACE ";" "$<SEMICOLON>" experimental_targets_to_build_arg
"${LLVM_EXPERIMENTAL_TARGETS_TO_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}
-DLLVM_TARGET_IS_CROSSCOMPILE_HOST=TRUE
-DLLVM_TARGETS_TO_BUILD="${targets_to_build_arg}"
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="${experimental_targets_to_build_arg}"
${build_type_flags} ${linker_flag} ${external_clang_dir}
WORKING_DIRECTORY ${LLVM_${target_name}_BUILD}
DEPENDS ${LLVM_${target_name}_BUILD}
DEPENDS CREATE_LLVM_${target_name}
COMMENT "Configuring ${target_name} LLVM...")
add_custom_target(CONFIGURE_LLVM_${target_name}
DEPENDS ${LLVM_${target_name}_BUILD}/CMakeCache.txt)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
${LLVM_${target_name}_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()
if (LLVM_EXTERNAL_CLANG_SOURCE_DIR)
# Propagate LLVM_EXTERNAL_CLANG_SOURCE_DIR so that clang-tblgen can be built
set(external_clang_dir "-DLLVM_EXTERNAL_CLANG_SOURCE_DIR=${LLVM_EXTERNAL_CLANG_SOURCE_DIR}")
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}
-DLLVM_TARGET_IS_CROSSCOMPILE_HOST=TRUE
${external_clang_dir}
WORKING_DIRECTORY ${LLVM_${target_name}_BUILD} )
endif(NOT IS_DIRECTORY ${LLVM_${target_name}_BUILD})
endfunction()
function(llvm_create_cross_target target_name sysroot)

View File

@ -3,7 +3,7 @@
function( get_host_triple var )
if( MSVC )
if( CMAKE_CL_64 )
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
set( value "x86_64-pc-win32" )
else()
set( value "i686-pc-win32" )

View File

@ -1,17 +1,15 @@
# CMake project that writes Subversion revision information to a header.
#
# Input variables:
# FIRST_SOURCE_DIR - First source directory
# FIRST_NAME - The macro prefix for the first repository's info
# SECOND_SOURCE_DIR - Second source directory (opt)
# SECOND_NAME - The macro prefix for the second repository's info (opt)
# HEADER_FILE - The header file to write
# SOURCE_DIRS - A list of source directories.
# NAMES - A list of macro prefixes for each of the source directories.
# HEADER_FILE - The header file to write
#
# The output header will contain macros FIRST_REPOSITORY and FIRST_REVISION,
# and SECOND_REPOSITORY and SECOND_REVISION if requested, where "FIRST" and
# "SECOND" are substituted with the names specified in the input variables.
# The output header will contain macros <NAME>_REPOSITORY and <NAME>_REVISION,
# where "<NAME>" and is substituted with the names specified in the input
# variables, for each of the SOURCE_DIRS given.
# Chop off cmake/modules/GetSVN.cmake
# Chop off cmake/modules/GetSVN.cmake
get_filename_component(LLVM_DIR "${CMAKE_SCRIPT_MODE_FILE}" PATH)
get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
@ -86,7 +84,7 @@ endmacro()
function(get_source_info path revision repository)
if (EXISTS "${path}/.svn")
get_source_info_svn("${path}" revision repository)
elseif (EXISTS "${path}/.git/svn")
elseif (EXISTS "${path}/.git/svn/refs")
get_source_info_git_svn("${path}" revision repository)
elseif (EXISTS "${path}/.git")
get_source_info_git("${path}" revision repository)
@ -103,9 +101,37 @@ function(append_info name path)
"#define ${name}_REPOSITORY \"${repository}\"\n")
endfunction()
append_info(${FIRST_NAME} "${FIRST_SOURCE_DIR}")
if(DEFINED SECOND_SOURCE_DIR)
append_info(${SECOND_NAME} "${SECOND_SOURCE_DIR}")
function(validate_inputs source_dirs names)
list(LENGTH source_dirs source_dirs_length)
list(LENGTH names names_length)
if (NOT source_dirs_length EQUAL names_length)
message(FATAL_ERROR
"GetSVN.cmake takes two arguments: a list of source directories, "
"and a list of names. Expected two lists must be of equal length, "
"but got ${source_dirs_length} source directories and "
"${names_length} names.")
endif()
endfunction()
if (DEFINED SOURCE_DIRS AND DEFINED NAMES)
validate_inputs("${SOURCE_DIRS}" "${NAMES}")
list(LENGTH SOURCE_DIRS source_dirs_length)
math(EXPR source_dirs_max_index ${source_dirs_length}-1)
foreach(index RANGE ${source_dirs_max_index})
list(GET SOURCE_DIRS ${index} source_dir)
list(GET NAMES ${index} name)
append_info(${name} ${source_dir})
endforeach()
endif()
# Allow -DFIRST_SOURCE_DIR arguments until Clang migrates to the new
# -DSOURCE_DIRS argument.
if(DEFINED FIRST_SOURCE_DIR)
append_info(${FIRST_NAME} "${FIRST_SOURCE_DIR}")
if(DEFINED SECOND_SOURCE_DIR)
append_info(${SECOND_NAME} "${SECOND_SOURCE_DIR}")
endif()
endif()
# Copy the file only if it has changed.

View File

@ -151,6 +151,14 @@ if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR WIN32 OR CYGWIN OR
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
endif()
# Pass -Wl,-z,nodelete. This makes sure our shared libraries are not unloaded
# by dlclose(). We need that since the CLI API relies on cross-references
# between global objects which became horribly broken when one of the libraries
# is unloaded.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,nodelete")
endif()
function(append value)
foreach(variable ${ARGN})
@ -194,10 +202,13 @@ if( LLVM_ENABLE_LLD )
endif()
if( LLVM_USE_LINKER )
check_cxx_compiler_flag("-fuse-ld=${LLVM_USE_LINKER}" CXX_SUPPORTS_CUSTOM_LINKER)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fuse-ld=${LLVM_USE_LINKER}")
check_cxx_source_compiles("int main() { return 0; }" CXX_SUPPORTS_CUSTOM_LINKER)
if ( NOT CXX_SUPPORTS_CUSTOM_LINKER )
message(FATAL_ERROR "Host compiler does not support '-fuse-ld=${LLVM_USE_LINKER}'")
endif()
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
append("-fuse-ld=${LLVM_USE_LINKER}"
CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
endif()
@ -229,12 +240,21 @@ if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -m32")
# FIXME: CMAKE_SIZEOF_VOID_P is still 8
add_definitions(-D_LARGEFILE_SOURCE)
add_definitions(-D_FILE_OFFSET_BITS=64)
endif( LLVM_BUILD_32_BITS )
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
# If building on a GNU specific 32-bit system, make sure off_t is 64 bits
# so that off_t can stored offset > 2GB
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
# so that off_t can stored offset > 2GB.
# Android until version N (API 24) doesn't support it.
if (ANDROID AND (ANDROID_NATIVE_API_LEVEL LESS 24))
set(LLVM_FORCE_SMALLFILE_FOR_ANDROID TRUE)
endif()
if( CMAKE_SIZEOF_VOID_P EQUAL 4 AND NOT LLVM_FORCE_SMALLFILE_FOR_ANDROID)
# FIXME: It isn't handled in LLVM_BUILD_32_BITS.
add_definitions( -D_LARGEFILE_SOURCE )
add_definitions( -D_FILE_OFFSET_BITS=64 )
endif()
@ -303,13 +323,13 @@ if( MSVC )
# especially so std::equal(nullptr, nullptr, nullptr) will not assert.
add_definitions("-D_DEBUG_POINTER_IMPL=")
endif()
include(ChooseMSVCCRT)
if( MSVC11 )
add_definitions(-D_VARIADIC_MAX=10)
endif()
# Add definitions that make MSVC much less annoying.
add_definitions(
# For some reason MS wants to deprecate a bunch of standard functions...
@ -370,7 +390,7 @@ if( MSVC )
string(FIND "${upper_exe_flags} ${upper_module_flags} ${upper_shared_flags}"
"/INCREMENTAL" linker_flag_idx)
if (${linker_flag_idx} GREATER -1)
message(WARNING "/Brepro not compatible with /INCREMENTAL linking - builds will be non-deterministic")
else()
@ -381,7 +401,9 @@ if( MSVC )
elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
append_if(LLVM_ENABLE_WERROR "-Werror" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
append_if(LLVM_ENABLE_WERROR "-Wno-error" CMAKE_REQUIRED_FLAGS)
add_flag_if_supported("-Werror=date-time" WERROR_DATE_TIME)
add_flag_if_supported("-Werror=unguarded-availability-new" WERROR_UNGUARDED_AVAILABILITY_NEW)
if (LLVM_ENABLE_CXX1Y)
check_cxx_compiler_flag("-std=c++1y" CXX_SUPPORTS_CXX1Y)
append_if(CXX_SUPPORTS_CXX1Y "-std=c++1y" CMAKE_CXX_FLAGS)
@ -436,64 +458,66 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
endif(LLVM_ENABLE_MODULES)
endif( MSVC )
if (MSVC AND NOT CLANG_CL)
set(msvc_warning_flags
# Disabled warnings.
-wd4141 # Suppress ''modifier' : used more than once' (because of __forceinline combined with inline)
-wd4146 # Suppress 'unary minus operator applied to unsigned type, result still unsigned'
-wd4180 # Suppress 'qualifier applied to function type has no meaning; ignored'
-wd4244 # Suppress ''argument' : conversion from 'type1' to 'type2', possible loss of data'
-wd4258 # Suppress ''var' : definition from the for loop is ignored; the definition from the enclosing scope is used'
-wd4267 # Suppress ''var' : conversion from 'size_t' to 'type', possible loss of data'
-wd4291 # Suppress ''declaration' : no matching operator delete found; memory will not be freed if initialization throws an exception'
-wd4345 # Suppress 'behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized'
-wd4351 # Suppress 'new behavior: elements of array 'array' will be default initialized'
-wd4355 # Suppress ''this' : used in base member initializer list'
-wd4456 # Suppress 'declaration of 'var' hides local variable'
-wd4457 # Suppress 'declaration of 'var' hides function parameter'
-wd4458 # Suppress 'declaration of 'var' hides class member'
-wd4459 # Suppress 'declaration of 'var' hides global declaration'
-wd4503 # Suppress ''identifier' : decorated name length exceeded, name was truncated'
-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'
-wd4577 # Suppress 'noexcept used with no exception handling mode specified; termination on exception is not guaranteed'
-wd4091 # Suppress 'typedef: ignored on left of '' when no variable is declared'
# C4592 is disabled because of false positives in Visual Studio 2015
# Update 1. Re-evaluate the usefulness of this diagnostic with Update 2.
-wd4592 # Suppress ''var': symbol will be dynamically initialized (implementation limitation)
-wd4319 # Suppress ''operator' : zero extending 'type' to 'type' of greater size'
if (MSVC)
if (NOT CLANG_CL)
set(msvc_warning_flags
# Disabled warnings.
-wd4141 # Suppress ''modifier' : used more than once' (because of __forceinline combined with inline)
-wd4146 # Suppress 'unary minus operator applied to unsigned type, result still unsigned'
-wd4180 # Suppress 'qualifier applied to function type has no meaning; ignored'
-wd4244 # Suppress ''argument' : conversion from 'type1' to 'type2', possible loss of data'
-wd4258 # Suppress ''var' : definition from the for loop is ignored; the definition from the enclosing scope is used'
-wd4267 # Suppress ''var' : conversion from 'size_t' to 'type', possible loss of data'
-wd4291 # Suppress ''declaration' : no matching operator delete found; memory will not be freed if initialization throws an exception'
-wd4345 # Suppress 'behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized'
-wd4351 # Suppress 'new behavior: elements of array 'array' will be default initialized'
-wd4355 # Suppress ''this' : used in base member initializer list'
-wd4456 # Suppress 'declaration of 'var' hides local variable'
-wd4457 # Suppress 'declaration of 'var' hides function parameter'
-wd4458 # Suppress 'declaration of 'var' hides class member'
-wd4459 # Suppress 'declaration of 'var' hides global declaration'
-wd4503 # Suppress ''identifier' : decorated name length exceeded, name was truncated'
-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'
-wd4577 # Suppress 'noexcept used with no exception handling mode specified; termination on exception is not guaranteed'
-wd4091 # Suppress 'typedef: ignored on left of '' when no variable is declared'
# C4592 is disabled because of false positives in Visual Studio 2015
# Update 1. Re-evaluate the usefulness of this diagnostic with Update 2.
-wd4592 # Suppress ''var': symbol will be dynamically initialized (implementation limitation)
-wd4319 # Suppress ''operator' : zero extending 'type' to 'type' of greater size'
# Ideally, 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 macro), 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())'
# Ideally, 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 macro), 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.
# Promoted warnings.
-w14062 # Promote 'enumerator in switch of enum is not handled' to level 1 warning.
# Promoted warnings to errors.
-we4238 # Promote 'nonstandard extension used : class rvalue used as lvalue' to error.
)
# Promoted warnings to errors.
-we4238 # Promote 'nonstandard extension used : class rvalue used as lvalue' to error.
)
endif(NOT CLANG_CL)
# Enable warnings
if (LLVM_ENABLE_WARNINGS)
@ -516,10 +540,17 @@ if (MSVC AND NOT CLANG_CL)
foreach(flag ${msvc_warning_flags})
append("${flag}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endforeach(flag)
endif (MSVC AND NOT CLANG_CL)
endif (MSVC)
if (LLVM_ENABLE_WARNINGS AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL))
append("-Wall -W -Wno-unused-parameter -Wwrite-strings" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
# Don't add -Wall for clang-cl, because it maps -Wall to -Weverything for
# MSVC compatibility. /W4 is added above instead.
if (NOT CLANG_CL)
append("-Wall" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
append("-W -Wno-unused-parameter -Wwrite-strings" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
append("-Wcast-qual" CMAKE_CXX_FLAGS)
# Turn off missing field initializer warnings for gcc to avoid noise from
@ -663,7 +694,7 @@ if(LLVM_USE_SANITIZER)
FSANITIZE_USE_AFTER_SCOPE_FLAG)
endif()
if (LLVM_USE_SANITIZE_COVERAGE)
append("-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
append("-fsanitize=fuzzer-no-link" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
endif()
@ -724,15 +755,30 @@ if(LLVM_ENABLE_EH AND NOT LLVM_ENABLE_RTTI)
message(FATAL_ERROR "Exception handling requires RTTI. You must set LLVM_ENABLE_RTTI to ON")
endif()
option(LLVM_BUILD_INSTRUMENTED "Build LLVM and tools with PGO instrumentation (experimental)" Off)
mark_as_advanced(LLVM_BUILD_INSTRUMENTED)
append_if(LLVM_BUILD_INSTRUMENTED "-fprofile-instr-generate='${LLVM_PROFILE_FILE_PATTERN}'"
CMAKE_CXX_FLAGS
CMAKE_C_FLAGS
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS)
option(LLVM_ENABLE_IR_PGO "Build LLVM and tools with IR PGO instrumentation (deprecated)" Off)
mark_as_advanced(LLVM_ENABLE_IR_PGO)
option(LLVM_BUILD_INSTRUMENTED_COVERAGE "Build LLVM and tools with Code Coverage instrumentation (experimental)" Off)
set(LLVM_BUILD_INSTRUMENTED OFF CACHE STRING "Build LLVM and tools with PGO instrumentation. May be specified as IR or Frontend")
mark_as_advanced(LLVM_BUILD_INSTRUMENTED)
string(TOUPPER "${LLVM_BUILD_INSTRUMENTED}" uppercase_LLVM_BUILD_INSTRUMENTED)
if (LLVM_BUILD_INSTRUMENTED)
if (LLVM_ENABLE_IR_PGO OR uppercase_LLVM_BUILD_INSTRUMENTED STREQUAL "IR")
append("-fprofile-generate='${LLVM_PROFILE_DATA_DIR}'"
CMAKE_CXX_FLAGS
CMAKE_C_FLAGS
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS)
else()
append("-fprofile-instr-generate='${LLVM_PROFILE_FILE_PATTERN}'"
CMAKE_CXX_FLAGS
CMAKE_C_FLAGS
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS)
endif()
endif()
option(LLVM_BUILD_INSTRUMENTED_COVERAGE "Build LLVM and tools with Code Coverage instrumentation" Off)
mark_as_advanced(LLVM_BUILD_INSTRUMENTED_COVERAGE)
append_if(LLVM_BUILD_INSTRUMENTED_COVERAGE "-fprofile-instr-generate='${LLVM_PROFILE_FILE_PATTERN}' -fcoverage-mapping"
CMAKE_CXX_FLAGS
@ -740,6 +786,10 @@ append_if(LLVM_BUILD_INSTRUMENTED_COVERAGE "-fprofile-instr-generate='${LLVM_PRO
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS)
if (LLVM_BUILD_INSTRUMENTED AND LLVM_BUILD_INSTRUMENTED_COVERAGE)
message(FATAL_ERROR "LLVM_BUILD_INSTRUMENTED and LLVM_BUILD_INSTRUMENTED_COVERAGE cannot both be specified")
endif()
if(LLVM_ENABLE_LTO AND LLVM_ON_WIN32 AND NOT LINKER_IS_LLD_LINK)
message(FATAL_ERROR "When compiling for Windows, LLVM_ENABLE_LTO requires using lld as the linker (point CMAKE_LINKER at lld-link.exe)")
endif()
@ -790,7 +840,7 @@ endif()
# Plugin support
# FIXME: Make this configurable.
if(WIN32 OR CYGWIN)
if(BUILD_SHARED_LIBS)
if(BUILD_SHARED_LIBS OR LLVM_BUILD_LLVM_DYLIB)
set(LLVM_ENABLE_PLUGINS ON)
else()
set(LLVM_ENABLE_PLUGINS OFF)

View File

@ -87,7 +87,7 @@ macro(llvm_config executable)
endif()
endif()
target_link_libraries(${executable} LLVM)
target_link_libraries(${executable} PRIVATE LLVM)
endif()
explicit_llvm_config(${executable} ${link_components})
@ -99,9 +99,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")
if(t STREQUAL "STATIC_LIBRARY")
target_link_libraries(${executable} INTERFACE ${LIBRARIES})
elseif("x${t}" STREQUAL "xSHARED_LIBRARY" OR "x${t}" STREQUAL "xMODULE_LIBRARY")
elseif(t STREQUAL "EXECUTABLE" OR t STREQUAL "SHARED_LIBRARY" OR t STREQUAL "MODULE_LIBRARY")
target_link_libraries(${executable} PRIVATE ${LIBRARIES})
else()
# Use plain form for legacy user.
@ -175,18 +175,15 @@ function(llvm_map_components_to_libnames out_libs)
message(FATAL_ERROR "Target ${c} is not in the set of libraries.")
endif()
endif()
if( TARGET LLVM${c}AsmPrinter )
list(APPEND expanded_components "LLVM${c}AsmPrinter")
endif()
if( TARGET LLVM${c}AsmParser )
list(APPEND expanded_components "LLVM${c}AsmParser")
endif()
if( TARGET LLVM${c}AsmPrinter )
list(APPEND expanded_components "LLVM${c}AsmPrinter")
endif()
if( TARGET LLVM${c}Desc )
list(APPEND expanded_components "LLVM${c}Desc")
endif()
if( TARGET LLVM${c}Info )
list(APPEND expanded_components "LLVM${c}Info")
endif()
if( TARGET LLVM${c}Disassembler )
list(APPEND expanded_components "LLVM${c}Disassembler")
endif()

View File

@ -72,6 +72,7 @@ set(LLVM_CMAKE_DIR "@LLVM_CONFIG_CMAKE_DIR@")
set(LLVM_BINARY_DIR "@LLVM_CONFIG_BINARY_DIR@")
set(LLVM_TOOLS_BINARY_DIR "@LLVM_CONFIG_TOOLS_BINARY_DIR@")
set(LLVM_TOOLS_INSTALL_DIR "@LLVM_TOOLS_INSTALL_DIR@")
set(LLVM_HAVE_OPT_VIEWER_MODULES @LLVM_HAVE_OPT_VIEWER_MODULES@)
if(NOT TARGET LLVMSupport)
set(LLVM_EXPORTED_TARGETS "@LLVM_CONFIG_EXPORTS@")
@ -79,5 +80,12 @@ if(NOT TARGET LLVMSupport)
@llvm_config_include_buildtree_only_exports@
endif()
# By creating intrinsics_gen here, subprojects that depend on LLVM's
# tablegen-generated headers can always depend on this target whether building
# in-tree with LLVM or not.
if(NOT TARGET intrinsics_gen)
add_custom_target(intrinsics_gen)
endif()
set_property(GLOBAL PROPERTY LLVM_TARGETS_CONFIGURED On)
include(${LLVM_CMAKE_DIR}/LLVM-Config.cmake)

View File

@ -95,7 +95,7 @@ function(llvm_ExternalProject_Add name source_dir)
foreach(prefix ${ARG_PASSTHROUGH_PREFIXES})
foreach(variableName ${variableNames})
if(variableName MATCHES "^${prefix}")
string(REPLACE ";" "\;" value "${${variableName}}")
string(REPLACE ";" "|" value "${${variableName}}")
list(APPEND PASSTHROUGH_VARIABLES
-D${variableName}=${value})
endif()
@ -132,6 +132,10 @@ function(llvm_ExternalProject_Add name source_dir)
set(exclude EXCLUDE_FROM_ALL 1)
endif()
if(CMAKE_SYSROOT)
set(sysroot_arg -DCMAKE_SYSROOT=${CMAKE_SYSROOT})
endif()
ExternalProject_Add(${name}
DEPENDS ${ARG_DEPENDS} llvm-config
${name}-clobber
@ -143,12 +147,16 @@ function(llvm_ExternalProject_Add name source_dir)
CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
${compiler_args}
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
${sysroot_arg}
-DLLVM_BINARY_DIR=${PROJECT_BINARY_DIR}
-DLLVM_CONFIG_PATH=$<TARGET_FILE:llvm-config>
-DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR}
-DLLVM_HOST_TRIPLE=${LLVM_HOST_TRIPLE}
-DLLVM_HAVE_LINK_VERSION_SCRIPT=${LLVM_HAVE_LINK_VERSION_SCRIPT}
-DPACKAGE_VERSION=${PACKAGE_VERSION}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
-DCMAKE_EXPORT_COMPILE_COMMANDS=1
${ARG_CMAKE_ARGS}
${PASSTHROUGH_VARIABLES}
INSTALL_COMMAND ""
@ -157,6 +165,7 @@ function(llvm_ExternalProject_Add name source_dir)
USES_TERMINAL_CONFIGURE 1
USES_TERMINAL_BUILD 1
USES_TERMINAL_INSTALL 1
LIST_SEPARATOR |
)
if(ARG_USE_TOOLCHAIN)
@ -185,12 +194,9 @@ function(llvm_ExternalProject_Add name source_dir)
install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -P ${BINARY_DIR}/cmake_install.cmake \)"
COMPONENT ${name})
add_custom_target(install-${name}
DEPENDS ${name}
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=${name}
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
USES_TERMINAL)
add_llvm_install_targets(install-${name}
DEPENDS ${name}
COMPONENT ${name})
endif()
# Add top-level targets

View File

@ -68,17 +68,29 @@ endfunction(llvm_process_sources)
function(llvm_check_source_file_list)
set(listed ${ARGN})
file(GLOB globbed *.c *.cpp)
cmake_parse_arguments(ARG "" "SOURCE_DIR" "" ${ARGN})
set(listed ${ARG_UNPARSED_ARGUMENTS})
if(ARG_SOURCE_DIR)
file(GLOB globbed
RELATIVE "${CMAKE_CURRENT_LIST_DIR}"
"${ARG_SOURCE_DIR}/*.c" "${ARG_SOURCE_DIR}/*.cpp")
else()
file(GLOB globbed *.c *.cpp)
endif()
foreach(g ${globbed})
get_filename_component(fn ${g} NAME)
if(ARG_SOURCE_DIR)
set(entry "${g}")
else()
set(entry "${fn}")
endif()
# Don't reject hidden files. Some editors create backups in the
# same directory as the file.
if (NOT "${fn}" MATCHES "^\\.")
list(FIND LLVM_OPTIONAL_SOURCES ${fn} idx)
list(FIND LLVM_OPTIONAL_SOURCES ${entry} idx)
if( idx LESS 0 )
list(FIND listed ${fn} idx)
list(FIND listed ${entry} idx)
if( idx LESS 0 )
message(SEND_ERROR "Found unknown source file ${g}
Please update ${CMAKE_CURRENT_LIST_FILE}\n")

View File

@ -52,6 +52,13 @@ function(tablegen project ofn)
list(APPEND LLVM_TABLEGEN_FLAGS "-instrument-coverage")
endif()
endif()
if (LLVM_ENABLE_GISEL_COV)
list(FIND ARGN "-gen-global-isel" idx)
if( NOT idx EQUAL -1 )
list(APPEND LLVM_TABLEGEN_FLAGS "-instrument-gisel-coverage")
list(APPEND LLVM_TABLEGEN_FLAGS "-gisel-coverage-file=${LLVM_GISEL_COV_PREFIX}all")
endif()
endif()
# We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the DEPENDS list
# (both the target and the file) to have .inc files rebuilt on
@ -110,19 +117,6 @@ function(add_public_tablegen_target target)
set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} ${target} PARENT_SCOPE)
endfunction()
if(LLVM_USE_HOST_TOOLS)
llvm_ExternalProject_BuildCmd(tblgen_build_cmd LLVMSupport
${LLVM_NATIVE_BUILD}
CONFIGURATION Release)
add_custom_command(OUTPUT LIB_LLVMTABLEGEN
COMMAND ${tblgen_build_cmd}
DEPENDS CONFIGURE_LLVM_NATIVE
WORKING_DIRECTORY ${LLVM_NATIVE_BUILD}
COMMENT "Building libLLVMTableGen for native TableGen..."
USES_TERMINAL)
add_custom_target(NATIVE_LIB_LLVMTABLEGEN DEPENDS LIB_LLVMTABLEGEN)
endif(LLVM_USE_HOST_TOOLS)
macro(add_tablegen target project)
set(${target}_OLD_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS})
set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} TableGen)
@ -166,7 +160,7 @@ macro(add_tablegen target project)
CONFIGURATION Release)
add_custom_command(OUTPUT ${${project}_TABLEGEN_EXE}
COMMAND ${tblgen_build_cmd}
DEPENDS ${target} NATIVE_LIB_LLVMTABLEGEN
DEPENDS CONFIGURE_LLVM_NATIVE ${target}
WORKING_DIRECTORY ${LLVM_NATIVE_BUILD}
COMMENT "Building native TableGen..."
USES_TERMINAL)

View File

@ -0,0 +1,9 @@
# macOS paths usually start with /Users/*. Unfortunately, clang-cl interprets
# paths starting with /U as macro undefines, so we need to put a -- before the
# input file path to force it to be treated as a path. CMake's compilation rules
# should be tweaked accordingly, but until that's done, and to support older
# CMake versions, overriding compilation rules works well enough. This file will
# be included by cmake after the default compilation rules have already been set
# up, so we can just modify them instead of duplicating them entirely.
string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}")
string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}")

View File

@ -0,0 +1,304 @@
# Cross toolchain configuration for using clang-cl on non-Windows hosts to
# target MSVC.
#
# Usage:
# cmake -G Ninja
# -DCMAKE_TOOLCHAIN_FILE=/path/to/this/file
# -DHOST_ARCH=[aarch64|arm64|armv7|arm|i686|x86|x86_64|x64]
# -DLLVM_NATIVE_TOOLCHAIN=/path/to/llvm/installation
# -DMSVC_BASE=/path/to/MSVC/system/libraries/and/includes
# -DWINSDK_BASE=/path/to/windows-sdk
# -DWINSDK_VER=windows sdk version folder name
#
# HOST_ARCH:
# The architecture to build for.
#
# LLVM_NATIVE_TOOLCHAIN:
# *Absolute path* to a folder containing the toolchain which will be used to
# build. At a minimum, this folder should have a bin directory with a
# copy of clang-cl, clang, clang++, and lld-link, as well as a lib directory
# containing clang's system resource directory.
#
# MSVC_BASE:
# *Absolute path* to the folder containing MSVC headers and system libraries.
# The layout of the folder matches that which is intalled by MSVC 2017 on
# Windows, and should look like this:
#
# ${MSVC_BASE}
# include
# vector
# stdint.h
# etc...
# lib
# x64
# libcmt.lib
# msvcrt.lib
# etc...
# x86
# libcmt.lib
# msvcrt.lib
# etc...
#
# For versions of MSVC < 2017, or where you have a hermetic toolchain in a
# custom format, you must use symlinks or restructure it to look like the above.
#
# WINSDK_BASE:
# Together with WINSDK_VER, determines the location of Windows SDK headers
# and libraries.
#
# WINSDK_VER:
# Together with WINSDK_BASE, determines the locations of Windows SDK headers
# and libraries.
#
# WINSDK_BASE and WINSDK_VER work together to define a folder layout that matches
# that of the Windows SDK installation on a standard Windows machine. It should
# match the layout described below.
#
# Note that if you install Windows SDK to a windows machine and simply copy the
# files, it will already be in the correct layout.
#
# ${WINSDK_BASE}
# Include
# ${WINSDK_VER}
# shared
# ucrt
# um
# windows.h
# etc...
# Lib
# ${WINSDK_VER}
# ucrt
# x64
# x86
# ucrt.lib
# etc...
# um
# x64
# x86
# kernel32.lib
# etc
#
# IMPORTANT: In order for this to work, you will need a valid copy of the Windows
# SDK and C++ STL headers and libraries on your host. Additionally, since the
# Windows libraries and headers are not case-correct, this toolchain file sets
# up a VFS overlay for the SDK headers and case-correcting symlinks for the
# libraries when running on a case-sensitive filesystem.
# When configuring CMake with a toolchain file against a top-level CMakeLists.txt,
# it will actually run CMake many times, once for each small test program used to
# determine what features a compiler supports. Unfortunately, none of these
# invocations share a CMakeCache.txt with the top-level invocation, meaning they
# won't see the value of any arguments the user passed via -D. Since these are
# necessary to properly configure MSVC in both the top-level configuration as well as
# all feature-test invocations, we set environment variables with the values so that
# these environments get inherited by child invocations.
function(init_user_prop prop)
if(${prop})
set(ENV{_${prop}} "${${prop}}")
else()
set(${prop} "$ENV{_${prop}}" PARENT_SCOPE)
endif()
endfunction()
function(generate_winsdk_vfs_overlay winsdk_include_dir output_path)
set(include_dirs)
file(GLOB_RECURSE entries LIST_DIRECTORIES true "${winsdk_include_dir}/*")
foreach(entry ${entries})
if(IS_DIRECTORY "${entry}")
list(APPEND include_dirs "${entry}")
endif()
endforeach()
file(WRITE "${output_path}" "version: 0\n")
file(APPEND "${output_path}" "case-sensitive: false\n")
file(APPEND "${output_path}" "roots:\n")
foreach(dir ${include_dirs})
file(GLOB headers RELATIVE "${dir}" "${dir}/*.h")
if(NOT headers)
continue()
endif()
file(APPEND "${output_path}" " - name: \"${dir}\"\n")
file(APPEND "${output_path}" " type: directory\n")
file(APPEND "${output_path}" " contents:\n")
foreach(header ${headers})
file(APPEND "${output_path}" " - name: \"${header}\"\n")
file(APPEND "${output_path}" " type: file\n")
file(APPEND "${output_path}" " external-contents: \"${dir}/${header}\"\n")
endforeach()
endforeach()
endfunction()
function(generate_winsdk_lib_symlinks winsdk_um_lib_dir output_dir)
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${output_dir}")
file(GLOB libraries RELATIVE "${winsdk_um_lib_dir}" "${winsdk_um_lib_dir}/*")
foreach(library ${libraries})
string(TOLOWER "${library}" symlink_name)
execute_process(COMMAND "${CMAKE_COMMAND}"
-E create_symlink
"${winsdk_um_lib_dir}/${library}"
"${output_dir}/${symlink_name}")
endforeach()
endfunction()
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_VERSION 10.0)
set(CMAKE_SYSTEM_PROCESSOR AMD64)
init_user_prop(HOST_ARCH)
init_user_prop(LLVM_NATIVE_TOOLCHAIN)
init_user_prop(MSVC_BASE)
init_user_prop(WINSDK_BASE)
init_user_prop(WINSDK_VER)
if(NOT HOST_ARCH)
set(HOST_ARCH x86_64)
endif()
if(HOST_ARCH STREQUAL "aarch64" OR HOST_ARCH STREQUAL "arm64")
set(TRIPLE_ARCH "aarch64")
set(WINSDK_ARCH "arm64")
elseif(HOST_ARCH STREQUAL "armv7" OR HOST_ARCH STREQUAL "arm")
set(TRIPLE_ARCH "armv7")
set(WINSDK_ARCH "arm")
elseif(HOST_ARCH STREQUAL "i686" OR HOST_ARCH STREQUAL "x86")
set(TRIPLE_ARCH "i686")
set(WINSDK_ARCH "x86")
elseif(HOST_ARCH STREQUAL "x86_64" OR HOST_ARCH STREQUAL "x64")
set(TRIPLE_ARCH "x86_64")
set(WINSDK_ARCH "x64")
else()
message(SEND_ERROR "Unknown host architecture ${HOST_ARCH}. Must be aarch64 (or arm64), armv7 (or arm), i686 (or x86), or x86_64 (or x64).")
endif()
set(MSVC_INCLUDE "${MSVC_BASE}/include")
set(MSVC_LIB "${MSVC_BASE}/lib")
set(WINSDK_INCLUDE "${WINSDK_BASE}/Include/${WINSDK_VER}")
set(WINSDK_LIB "${WINSDK_BASE}/Lib/${WINSDK_VER}")
# Do some sanity checking to make sure we can find a native toolchain and
# that the Windows SDK / MSVC STL directories look kosher.
if(NOT EXISTS "${LLVM_NATIVE_TOOLCHAIN}/bin/clang-cl" OR
NOT EXISTS "${LLVM_NATIVE_TOOLCHAIN}/bin/lld-link")
message(SEND_ERROR
"LLVM_NATIVE_TOOLCHAIN folder '${LLVM_NATIVE_TOOLCHAIN}' does not "
"point to a valid directory containing bin/clang-cl and bin/lld-link "
"binaries")
endif()
if(NOT EXISTS "${MSVC_BASE}" OR
NOT EXISTS "${MSVC_INCLUDE}" OR
NOT EXISTS "${MSVC_LIB}")
message(SEND_ERROR
"CMake variable MSVC_BASE must point to a folder containing MSVC "
"system headers and libraries")
endif()
if(NOT EXISTS "${WINSDK_BASE}" OR
NOT EXISTS "${WINSDK_INCLUDE}" OR
NOT EXISTS "${WINSDK_LIB}")
message(SEND_ERROR
"CMake variable WINSDK_BASE and WINSDK_VER must resolve to a valid "
"Windows SDK installation")
endif()
if(NOT EXISTS "${WINSDK_INCLUDE}/um/Windows.h")
message(SEND_ERROR "Cannot find Windows.h")
endif()
if(NOT EXISTS "${WINSDK_INCLUDE}/um/WINDOWS.H")
set(case_sensitive_filesystem TRUE)
endif()
set(CMAKE_C_COMPILER "${LLVM_NATIVE_TOOLCHAIN}/bin/clang-cl" CACHE FILEPATH "")
set(CMAKE_CXX_COMPILER "${LLVM_NATIVE_TOOLCHAIN}/bin/clang-cl" CACHE FILEPATH "")
set(CMAKE_LINKER "${LLVM_NATIVE_TOOLCHAIN}/bin/lld-link" CACHE FILEPATH "")
# Even though we're cross-compiling, we need some native tools (e.g. llvm-tblgen), and those
# native tools have to be built before we can start doing the cross-build. LLVM supports
# a CROSS_TOOLCHAIN_FLAGS_NATIVE argument which consists of a list of flags to pass to CMake
# when configuring the NATIVE portion of the cross-build. By default we construct this so
# that it points to the tools in the same location as the native clang-cl that we're using.
list(APPEND _CTF_NATIVE_DEFAULT "-DCMAKE_ASM_COMPILER=${LLVM_NATIVE_TOOLCHAIN}/bin/clang")
list(APPEND _CTF_NATIVE_DEFAULT "-DCMAKE_C_COMPILER=${LLVM_NATIVE_TOOLCHAIN}/bin/clang")
list(APPEND _CTF_NATIVE_DEFAULT "-DCMAKE_CXX_COMPILER=${LLVM_NATIVE_TOOLCHAIN}/bin/clang++")
set(CROSS_TOOLCHAIN_FLAGS_NATIVE "${_CTF_NATIVE_DEFAULT}" CACHE STRING "")
set(COMPILE_FLAGS
-D_CRT_SECURE_NO_WARNINGS
--target=${TRIPLE_ARCH}-windows-msvc
-fms-compatibility-version=19.11
-imsvc "${MSVC_INCLUDE}"
-imsvc "${WINSDK_INCLUDE}/ucrt"
-imsvc "${WINSDK_INCLUDE}/shared"
-imsvc "${WINSDK_INCLUDE}/um"
-imsvc "${WINSDK_INCLUDE}/winrt")
if(case_sensitive_filesystem)
# Ensure all sub-configures use the top-level VFS overlay instead of generating their own.
init_user_prop(winsdk_vfs_overlay_path)
if(NOT winsdk_vfs_overlay_path)
set(winsdk_vfs_overlay_path "${CMAKE_BINARY_DIR}/winsdk_vfs_overlay.yaml")
generate_winsdk_vfs_overlay("${WINSDK_BASE}/Include/${WINSDK_VER}" "${winsdk_vfs_overlay_path}")
init_user_prop(winsdk_vfs_overlay_path)
endif()
list(APPEND COMPILE_FLAGS
-Xclang -ivfsoverlay -Xclang "${winsdk_vfs_overlay_path}")
endif()
string(REPLACE ";" " " COMPILE_FLAGS "${COMPILE_FLAGS}")
# We need to preserve any flags that were passed in by the user. However, we
# can't append to CMAKE_C_FLAGS and friends directly, because toolchain files
# will be re-invoked on each reconfigure and therefore need to be idempotent.
# The assignments to the _INITIAL cache variables don't use FORCE, so they'll
# only be populated on the initial configure, and their values won't change
# afterward.
set(_CMAKE_C_FLAGS_INITIAL "${CMAKE_C_FLAGS}" CACHE STRING "")
set(CMAKE_C_FLAGS "${_CMAKE_C_FLAGS_INITIAL} ${COMPILE_FLAGS}" CACHE STRING "" FORCE)
set(_CMAKE_CXX_FLAGS_INITIAL "${CMAKE_CXX_FLAGS}" CACHE STRING "")
set(CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS_INITIAL} ${COMPILE_FLAGS}" CACHE STRING "" FORCE)
set(LINK_FLAGS
# Prevent CMake from attempting to invoke mt.exe. It only recognizes the slashed form and not the dashed form.
/manifest:no
-libpath:"${MSVC_LIB}/${WINSDK_ARCH}"
-libpath:"${WINSDK_LIB}/ucrt/${WINSDK_ARCH}"
-libpath:"${WINSDK_LIB}/um/${WINSDK_ARCH}")
if(case_sensitive_filesystem)
# Ensure all sub-configures use the top-level symlinks dir instead of generating their own.
init_user_prop(winsdk_lib_symlinks_dir)
if(NOT winsdk_lib_symlinks_dir)
set(winsdk_lib_symlinks_dir "${CMAKE_BINARY_DIR}/winsdk_lib_symlinks")
generate_winsdk_lib_symlinks("${WINSDK_BASE}/Lib/${WINSDK_VER}/um/${WINSDK_ARCH}" "${winsdk_lib_symlinks_dir}")
init_user_prop(winsdk_lib_symlinks_dir)
endif()
list(APPEND LINK_FLAGS
-libpath:"${winsdk_lib_symlinks_dir}")
endif()
string(REPLACE ";" " " LINK_FLAGS "${LINK_FLAGS}")
# See explanation for compiler flags above for the _INITIAL variables.
set(_CMAKE_EXE_LINKER_FLAGS_INITIAL "${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "")
set(CMAKE_EXE_LINKER_FLAGS "${_CMAKE_EXE_LINKER_FLAGS_INITIAL} ${LINK_FLAGS}" CACHE STRING "" FORCE)
set(_CMAKE_MODULE_LINKER_FLAGS_INITIAL "${CMAKE_MODULE_LINKER_FLAGS}" CACHE STRING "")
set(CMAKE_MODULE_LINKER_FLAGS "${_CMAKE_MODULE_LINKER_FLAGS_INITIAL} ${LINK_FLAGS}" CACHE STRING "" FORCE)
set(_CMAKE_SHARED_LINKER_FLAGS_INITIAL "${CMAKE_SHARED_LINKER_FLAGS}" CACHE STRING "")
set(CMAKE_SHARED_LINKER_FLAGS "${_CMAKE_SHARED_LINKER_FLAGS_INITIAL} ${LINK_FLAGS}" CACHE STRING "" FORCE)
# CMake populates these with a bunch of unnecessary libraries, which requires
# extra case-correcting symlinks and what not. Instead, let projects explicitly
# control which libraries they require.
set(CMAKE_C_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
# Allow clang-cl to work with macOS paths.
set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_CURRENT_LIST_DIR}/ClangClCMakeCompileRules.cmake")

File diff suppressed because it is too large Load Diff

View File

@ -681,7 +681,7 @@ for each library name referenced.
MODULE_CODE_GLOBALVAR Record
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``[GLOBALVAR, strtab offset, strtab size, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr, externally_initialized, dllstorageclass, comdat]``
``[GLOBALVAR, strtab offset, strtab size, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr, externally_initialized, dllstorageclass, comdat, attributes, preemptionspecifier]``
The ``GLOBALVAR`` record (code 7) marks the declaration or definition of a
global variable. The operand fields are:
@ -761,12 +761,21 @@ global variable. The operand fields are:
* *comdat*: An encoding of the COMDAT of this function
* *attributes*: If nonzero, the 1-based index into the table of AttributeLists.
.. _bcpreemptionspecifier:
* *preemptionspecifier*: If present, an encoding of the runtime preemption specifier of this variable:
* ``dso_preemptable``: code 0
* ``dso_local``: code 1
.. _FUNCTION:
MODULE_CODE_FUNCTION Record
^^^^^^^^^^^^^^^^^^^^^^^^^^^
``[FUNCTION, strtab offset, strtab size, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prologuedata, dllstorageclass, comdat, prefixdata, personalityfn]``
``[FUNCTION, strtab offset, strtab size, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prologuedata, dllstorageclass, comdat, prefixdata, personalityfn, preemptionspecifier]``
The ``FUNCTION`` record (code 8) marks the declaration or definition of a
function. The operand fields are:
@ -828,10 +837,12 @@ function. The operand fields are:
* *personalityfn*: If non-zero, the value index of the personality function for this function,
plus 1.
* *preemptionspecifier*: If present, an encoding of the :ref:`runtime preemption specifier<bcpreemptionspecifier>` of this function.
MODULE_CODE_ALIAS Record
^^^^^^^^^^^^^^^^^^^^^^^^
``[ALIAS, strtab offset, strtab size, alias type, aliasee val#, linkage, visibility, dllstorageclass, threadlocal, unnamed_addr]``
``[ALIAS, strtab offset, strtab size, alias type, aliasee val#, linkage, visibility, dllstorageclass, threadlocal, unnamed_addr, preemptionspecifier]``
The ``ALIAS`` record (code 9) marks the definition of an alias. The operand
fields are
@ -856,6 +867,8 @@ fields are
* *unnamed_addr*: If present, an encoding of the
:ref:`unnamed_addr<bcunnamedaddr>` attribute of this alias
* *preemptionspecifier*: If present, an encoding of the :ref:`runtime preemption specifier<bcpreemptionspecifier>` of this alias.
.. _MODULE_CODE_GCNAME:
MODULE_CODE_GCNAME Record
@ -1039,6 +1052,9 @@ The integer codes are mapped to well-known attributes as follows.
* code 50: ``inaccessiblememonly_or_argmemonly``
* code 51: ``allocsize(<EltSizeParam>[, <NumEltsParam>])``
* code 52: ``writeonly``
* code 53: ``speculatable``
* code 54: ``strictfp``
* code 55: ``sanitize_hwaddress``
.. note::
The ``allocsize`` attribute has a special encoding for its arguments. Its two

View File

@ -151,6 +151,11 @@ non-obvious ways. Here are some hints and tips:
optimizations to be randomized and applied to the program. This process will
repeat until a bug is found or the user kills ``bugpoint``.
* ``bugpoint`` can produce IR which contains long names. Run ``opt
-metarenamer`` over the IR to rename everything using easy-to-read,
metasyntactic names. Alternatively, run ``opt -strip -instnamer`` to rename
everything with very short (often purely numeric) names.
What to do when bugpoint isn't enough
=====================================

91
docs/CFIVerify.rst Normal file
View File

@ -0,0 +1,91 @@
==============================================
Control Flow Verification Tool Design Document
==============================================
.. contents::
:local:
Objective
=========
This document provides an overview of an external tool to verify the protection
mechanisms implemented by Clang's *Control Flow Integrity* (CFI) schemes
(``-fsanitize=cfi``). This tool, provided a binary or DSO, should infer whether
indirect control flow operations are protected by CFI, and should output these
results in a human-readable form.
This tool should also be added as part of Clang's continuous integration testing
framework, where modifications to the compiler ensure that CFI protection
schemes are still present in the final binary.
Location
========
This tool will be present as a part of the LLVM toolchain, and will reside in
the "/llvm/tools/llvm-cfi-verify" directory, relative to the LLVM trunk. It will
be tested in two methods:
- Unit tests to validate code sections, present in "/llvm/unittests/llvm-cfi-
verify".
- Integration tests, present in "/llvm/tools/clang/test/LLVMCFIVerify". These
integration tests are part of clang as part of a continuous integration
framework, ensuring updates to the compiler that reduce CFI coverage on
indirect control flow instructions are identified.
Background
==========
This tool will continuously validate that CFI directives are properly
implemented around all indirect control flows by analysing the output machine
code. The analysis of machine code is important as it ensures that any bugs
present in linker or compiler do not subvert CFI protections in the final
shipped binary.
Unprotected indirect control flow instructions will be flagged for manual
review. These unexpected control flows may simply have not been accounted for in
the compiler implementation of CFI (e.g. indirect jumps to facilitate switch
statements may not be fully protected).
It may be possible in the future to extend this tool to flag unnecessary CFI
directives (e.g. CFI directives around a static call to a non-polymorphic base
type). This type of directive has no security implications, but may present
performance impacts.
Design Ideas
============
This tool will disassemble binaries and DSO's from their machine code format and
analyse the disassembled machine code. The tool will inspect virtual calls and
indirect function calls. This tool will also inspect indirect jumps, as inlined
functions and jump tables should also be subject to CFI protections. Non-virtual
calls (``-fsanitize=cfi-nvcall``) and cast checks (``-fsanitize=cfi-*cast*``)
are not implemented due to a lack of information provided by the bytecode.
The tool would operate by searching for indirect control flow instructions in
the disassembly. A control flow graph would be generated from a small buffer of
the instructions surrounding the 'target' control flow instruction. If the
target instruction is branched-to, the fallthrough of the branch should be the
CFI trap (on x86, this is a ``ud2`` instruction). If the target instruction is
the fallthrough (i.e. immediately succeeds) of a conditional jump, the
conditional jump target should be the CFI trap. If an indirect control flow
instruction does not conform to one of these formats, the target will be noted
as being CFI-unprotected.
Note that in the second case outlined above (where the target instruction is the
fallthrough of a conditional jump), if the target represents a vcall that takes
arguments, these arguments may be pushed to the stack after the branch but
before the target instruction. In these cases, a secondary 'spill graph' in
constructed, to ensure the register argument used by the indirect jump/call is
not spilled from the stack at any point in the interim period. If there are no
spills that affect the target register, the target is marked as CFI-protected.
Other Design Notes
~~~~~~~~~~~~~~~~~~
Only machine code sections that are marked as executable will be subject to this
analysis. Non-executable sections do not require analysis as any execution
present in these sections has already violated the control flow integrity.
Suitable extensions may be made at a later date to include anaylsis for indirect
control flow operations across DSO boundaries. Currently, these CFI features are
only experimental with an unstable ABI, making them unsuitable for analysis.

View File

@ -224,6 +224,10 @@ LLVM-specific variables
Generate build targets for the LLVM tools. Defaults to ON. You can use this
option to disable the generation of build targets for the LLVM tools.
**LLVM_INSTALL_BINUTILS_SYMLINKS**:BOOL
Install symlinks from the binutils tool names to the corresponding LLVM tools.
For example, ar will be symlinked to llvm-ar.
**LLVM_BUILD_EXAMPLES**:BOOL
Build LLVM examples. Defaults to OFF. Targets for building each example are
generated in any case. See documentation for *LLVM_BUILD_TOOLS* above for more
@ -542,6 +546,11 @@ LLVM-specific variables
reverse order. This is useful for uncovering non-determinism caused by
iteration of unordered containers.
**LLVM_BUILD_INSTRUMENTED_COVERAGE**:BOOL
If enabled, `source-based code coverage
<http://clang.llvm.org/docs/SourceBasedCodeCoverage.html>`_ instrumentation
is enabled while building llvm.
CMake Caches
============

View File

@ -3,7 +3,7 @@ if (DOXYGEN_FOUND)
if (LLVM_ENABLE_DOXYGEN)
set(abs_top_srcdir ${CMAKE_CURRENT_SOURCE_DIR})
set(abs_top_builddir ${CMAKE_CURRENT_BINARY_DIR})
if (HAVE_DOT)
set(DOT ${LLVM_PATH_DOT})
endif()
@ -21,20 +21,20 @@ if (LLVM_ENABLE_DOXYGEN)
set(enable_external_search "NO")
set(extra_search_mappings "")
endif()
# If asked, configure doxygen for the creation of a Qt Compressed Help file.
option(LLVM_ENABLE_DOXYGEN_QT_HELP
"Generate a Qt Compressed Help file." OFF)
if (LLVM_ENABLE_DOXYGEN_QT_HELP)
set(LLVM_DOXYGEN_QCH_FILENAME "org.llvm.qch" CACHE STRING
"Filename of the Qt Compressed help file")
set(LLVM_DOXYGEN_QHP_NAMESPACE "org.llvm" CACHE STRING
set(LLVM_DOXYGEN_QHP_NAMESPACE "org.llvm" CACHE STRING
"Namespace under which the intermediate Qt Help Project file lives")
set(LLVM_DOXYGEN_QHP_CUST_FILTER_NAME "${PACKAGE_STRING}" CACHE STRING
"See http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters")
set(LLVM_DOXYGEN_QHP_CUST_FILTER_ATTRS "${PACKAGE_NAME},${PACKAGE_VERSION}" CACHE STRING
"See http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes")
find_program(LLVM_DOXYGEN_QHELPGENERATOR_PATH qhelpgenerator
find_program(LLVM_DOXYGEN_QHELPGENERATOR_PATH qhelpgenerator
DOC "Path to the qhelpgenerator binary")
if (NOT LLVM_DOXYGEN_QHELPGENERATOR_PATH)
message(FATAL_ERROR "Failed to find qhelpgenerator binary")
@ -55,7 +55,7 @@ if (LLVM_ENABLE_DOXYGEN)
set(llvm_doxygen_qhp_cust_filter_name "")
set(llvm_doxygen_qhp_cust_filter_attrs "")
endif()
option(LLVM_DOXYGEN_SVG
"Use svg instead of png files for doxygen graphs." OFF)
if (LLVM_DOXYGEN_SVG)
@ -112,6 +112,8 @@ if (LLVM_ENABLE_SPHINX)
if (${SPHINX_OUTPUT_MAN})
add_sphinx_target(man llvm)
add_sphinx_target(man llvm-dwarfdump)
add_sphinx_target(man dsymutil)
endif()
endif()

View File

@ -167,10 +167,9 @@ Other Types
Variables that are cached or specified on the command line can have types
associated with them. The variable's type is used by CMake's UI tool to display
the right input field. The variable's type generally doesn't impact evaluation.
One of the few examples is PATH variables, which CMake does have some special
handling for. You can read more about the special handling in `CMake's set
documentation
the right input field. A variable's type generally doesn't impact evaluation,
however CMake does have special handling for some variables such as PATH.
You can read more about the special handling in `CMake's set documentation
<https://cmake.org/cmake/help/v3.5/command/set.html#set-cache-entry>`_.
Scope
@ -203,7 +202,7 @@ Control Flow
============
CMake features the same basic control flow constructs you would expect in any
scripting language, but there are a few quarks because, as with everything in
scripting language, but there are a few quirks because, as with everything in
CMake, control flow constructs are commands.
If, ElseIf, Else
@ -334,21 +333,23 @@ When defining a CMake command handling arguments is very useful. The examples
in this section will all use the CMake ``function`` block, but this all applies
to the ``macro`` block as well.
CMake commands can have named arguments, but all commands are implicitly
variable argument. If the command has named arguments they are required and must
be specified at every call site. Below is a trivial example of providing a
wrapper function for CMake's built in function ``add_dependencies``.
CMake commands can have named arguments that are requried at every call site. In
addition, all commands will implicitly accept a variable number of extra
arguments (In C parlance, all commands are varargs functions). When a command is
invoked with extra arguments (beyond the named ones) CMake will store the full
list of arguments (both named and unnamed) in a list named ``ARGV``, and the
sublist of unnamed arguments in ``ARGN``. Below is a trivial example of
providing a wrapper function for CMake's built in function ``add_dependencies``.
.. code-block:: cmake
function(add_deps target)
add_dependencies(${target} ${ARGV})
add_dependencies(${target} ${ARGN})
endfunction()
This example defines a new macro named ``add_deps`` which takes a required first
argument, and just calls another function passing through the first argument and
all trailing arguments. When variable arguments are present CMake defines them
in a list named ``ARGV``, and the count of the arguments is defined in ``ARGN``.
all trailing arguments.
CMake provides a module ``CMakeParseArguments`` which provides an implementation
of advanced argument parsing. We use this all over LLVM, and it is recommended

View File

@ -1578,6 +1578,17 @@ 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.
Emitting function stack size information
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A section containing metadata on function stack sizes will be emitted when
``TargetLoweringObjectFile::StackSizesSection`` is not null, and
``TargetOptions::EmitStackSizeSection`` is set (-stack-size-section). The
section will contain an array of pairs of function symbol references (8 byte)
and stack sizes (unsigned LEB128). The stack size values only include the space
allocated in the function prologue. Functions with dynamic stack allocations are
not included.
VLIW Packetizer
---------------

View File

@ -203,7 +203,7 @@ this means are `Effective Go`_ and `Go Code Review Comments`_.
https://golang.org/doc/effective_go.html
.. _Go Code Review Comments:
https://code.google.com/p/go-wiki/wiki/CodeReviewComments
https://github.com/golang/go/wiki/CodeReviewComments
Mechanical Source Issues
========================
@ -811,6 +811,21 @@ As a rule of thumb, use ``auto &`` unless you need to copy the result, and use
for (const auto *Ptr : Container) { observe(*Ptr); }
for (auto *Ptr : Container) { Ptr->change(); }
Beware of non-determinism due to ordering of pointers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In general, there is no relative ordering among pointers. As a result,
when unordered containers like sets and maps are used with pointer keys
the iteration order is undefined. Hence, iterating such containers may
result in non-deterministic code generation. While the generated code
might not necessarily be "wrong code", this non-determinism might result
in unexpected runtime crashes or simply hard to reproduce bugs on the
customer side making it harder to debug and fix.
As a rule of thumb, in case an ordered result is expected, remember to
sort an unordered container before iteration. Or use ordered containers
like vector/MapVector/SetVector if you want to iterate pointer keys.
Style Issues
============
@ -941,8 +956,8 @@ loops. A silly example is something like this:
.. code-block:: c++
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) {
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(II)) {
for (Instruction &I : BB) {
if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
Value *LHS = BO->getOperand(0);
Value *RHS = BO->getOperand(1);
if (LHS != RHS) {
@ -961,8 +976,8 @@ It is strongly preferred to structure the loop like this:
.. code-block:: c++
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) {
BinaryOperator *BO = dyn_cast<BinaryOperator>(II);
for (Instruction &I : BB) {
auto *BO = dyn_cast<BinaryOperator>(&I);
if (!BO) continue;
Value *LHS = BO->getOperand(0);
@ -1232,6 +1247,12 @@ builds), ``llvm_unreachable`` becomes a hint to compilers to skip generating
code for this branch. If the compiler does not support this, it will fall back
to the "abort" implementation.
Neither assertions or ``llvm_unreachable`` will abort the program on a release
build. If the error condition can be triggered by user input then the
recoverable error mechanism described in :doc:`ProgrammersManual` should be
used instead. In cases where this is not practical, ``report_fatal_error`` may
be used.
Another issue is that values used only by assertions will produce an "unused
value" warning when assertions are disabled. For example, this code will warn:
@ -1316,19 +1337,31 @@ 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.
Don't evaluate ``end()`` every time through a loop
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use range-based ``for`` loops wherever possible
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Because C++ doesn't have a standard "``foreach``" loop (though it can be
emulated with macros and may be coming in C++'0x) we end up writing a lot of
loops that manually iterate from begin to end on a variety of containers or
through other data structures. One common mistake is to write a loop in this
style:
The introduction of range-based ``for`` loops in C++11 means that explicit
manipulation of iterators is rarely necessary. We use range-based ``for``
loops wherever possible for all newly added code. For example:
.. code-block:: c++
BasicBlock *BB = ...
for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
for (Instruction &I : *BB)
... use I ...
Don't evaluate ``end()`` every time through a loop
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In cases where range-based ``for`` loops can't be used and it is necessary
to write an explicit iterator-based loop, pay close attention to whether
``end()`` is re-evaluted on each loop iteration. One common mistake is to
write a loop in this style:
.. code-block:: c++
BasicBlock *BB = ...
for (auto I = BB->begin(); I != BB->end(); ++I)
... use I ...
The problem with this construct is that it evaluates "``BB->end()``" every time
@ -1339,7 +1372,7 @@ convenient way to do this is like so:
.. code-block:: c++
BasicBlock *BB = ...
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
for (auto I = BB->begin(), E = BB->end(); I != E; ++I)
... use I ...
The observant may quickly point out that these two loops may have different

View File

@ -86,6 +86,11 @@ OPTIONS
All other variables get undefined after each encountered ``CHECK-LABEL``.
.. option:: -D<VAR=VALUE>
Sets a filecheck variable ``VAR`` with value ``VALUE`` that can be used in
``CHECK:`` lines.
.. option:: -version
Show the version number of this program.
@ -397,10 +402,11 @@ 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,
surrounded by double braces: ``{{yourregex}}``. Because we want to use fixed
string matching for a majority of what we do, FileCheck has been designed to
support mixing and matching fixed string matching with regular expressions.
This allows you to write things like this:
surrounded by double braces: ``{{yourregex}}``. FileCheck implements a POSIX
regular expression matcher; it supports Extended POSIX regular expressions
(ERE). Because we want to use fixed string matching for a majority of what we
do, FileCheck has been designed to support mixing and matching fixed string
matching with regular expressions. This allows you to write things like this:
.. code-block:: llvm
@ -434,7 +440,7 @@ The first check line matches a regex ``%[a-z]+`` and captures it into the
variable ``REGISTER``. The second line verifies that whatever is in
``REGISTER`` occurs later in the file after an "``andw``". :program:`FileCheck`
variable references are always contained in ``[[ ]]`` pairs, and their names can
be formed with the regex ``[a-zA-Z][a-zA-Z0-9]*``. If a colon follows the name,
be formed with the regex ``[a-zA-Z_][a-zA-Z0-9_]*``. If a colon follows the name,
then it is a definition of the variable; otherwise, it is a use.
:program:`FileCheck` variables can be defined multiple times, and uses always

View File

@ -0,0 +1,89 @@
dsymutil - manipulate archived DWARF debug symbol files
=======================================================
SYNOPSIS
--------
| :program:`dsymutil` [*options*] *executable*
DESCRIPTION
-----------
:program:`dsymutil` links the DWARF debug information found in the object files
for an executable *executable* by using debug symbols information contained in
its symbol table. By default, the linked debug information is placed in a
``.dSYM`` bundle with the same name as the executable.
OPTIONS
-------
.. option:: --arch=<arch>
Link DWARF debug information only for specified CPU architecture types.
Architectures may be specified by name. When using this option, an error will
be returned if any architectures can not be properly linked. This option can
be specified multiple times, once for each desired architecture. All CPU
architectures will be linked by default and any architectures that can't be
properly linked will cause :program:`dsymutil` to return an error.
.. option:: --dump-debug-map
Dump the *executable*'s debug-map (the list of the object files containing the
debug information) in YAML format and exit. Not DWARF link will take place.
.. option:: -f, --flat
Produce a flat dSYM file. A ``.dwarf`` extension will be appended to the
executable name unless the output file is specified using the -o option.
.. option:: --no-odr
Do not use ODR (One Definition Rule) for uniquing C++ types.
.. option:: --no-output
Do the link in memory, but do not emit the result file.
.. option:: --no-swiftmodule-timestamp
Don't check the timestamp for swiftmodule files.
.. option:: -j <n>, --num-threads=<n>
Specifies the maximum number (``n``) of simultaneous threads to use when
linking multiple architectures.
.. option:: -o <filename>
Specifies an alternate ``path`` to place the dSYM bundle. The default dSYM
bundle path is created by appending ``.dSYM`` to the executable name.
.. option:: --oso-prepend-path=<path>
Specifies a ``path`` to prepend to all debug symbol object file paths.
.. option:: -s, --symtab
Dumps the symbol table found in *executable* or object file(s) and exits.
.. option:: -v, --verbose
Display verbose information when linking.
.. option:: --version
Display the version of the tool.
.. option:: -y
Treat *executable* as a YAML debug-map rather than an executable.
EXIT STATUS
-----------
:program:`dsymutil` returns 0 if the DWARF debug information was linked
successfully. Otherwise, it returns 1.
SEE ALSO
--------
:manpage:`llvm-dwarfdump(1)`

View File

@ -30,6 +30,7 @@ Basic Commands
llvm-stress
llvm-symbolizer
llvm-dwarfdump
dsymutil
Debugging Tools
~~~~~~~~~~~~~~~
@ -51,4 +52,5 @@ Developer Tools
tblgen
lit
llvm-build
llvm-pdbutil
llvm-readobj

View File

@ -132,6 +132,14 @@ End-user Options
Specify which EABI version should conform to. Valid EABI versions are *gnu*,
*4* and *5*. Default value (*default*) depends on the triple.
.. option:: -stack-size-section
Emit the .stack_sizes section which contains stack size metadata. The section
contains an array of pairs of function symbol references (8 byte) and stack
sizes (unsigned LEB128). The stack size values only include the space allocated
in the function prologue. Functions with dynamic stack allocations are not
included.
Tuning/Configuration Options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -122,7 +122,7 @@ CODE GENERATION OPTIONS
Choose the code model from:
.. code-block:: perl
.. code-block:: text
default: Target default code model
small: Small code model
@ -154,7 +154,7 @@ CODE GENERATION OPTIONS
Instruction schedulers available (before register allocation):
.. code-block:: perl
.. code-block:: text
=default: Best scheduler for the target
=none: No scheduling: breadth first sequencing
@ -168,7 +168,7 @@ CODE GENERATION OPTIONS
Register allocator to use (default=linearscan)
.. code-block:: perl
.. code-block:: text
=bigblock: Big-block register allocator
=linearscan: linear scan register allocator =local - local register allocator
@ -178,7 +178,7 @@ CODE GENERATION OPTIONS
Choose relocation model from:
.. code-block:: perl
.. code-block:: text
=default: Target default relocation model
=static: Non-relocatable code =pic - Fully relocatable, position independent code
@ -188,7 +188,7 @@ CODE GENERATION OPTIONS
Spiller to use (default=local)
.. code-block:: perl
.. code-block:: text
=simple: simple spiller
=local: local spiller
@ -197,7 +197,7 @@ CODE GENERATION OPTIONS
Choose style of code to emit from X86 backend:
.. code-block:: perl
.. code-block:: text
=att: Emit AT&T-style assembly
=intel: Emit Intel-style assembly

View File

@ -195,44 +195,53 @@ OPTIONS
.. option:: -show-line-counts
Show the execution counts for each line. This is enabled by default, unless
another ``-show`` option is used.
Show the execution counts for each line. Defaults to true, 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.
in the display of the source file. Defaults to false.
.. 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.
Defaults to true.
.. option:: -show-regions
Show the execution counts for each region by displaying a caret that points to
the character where the region starts.
the character where the region starts. Defaults to false.
.. 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.
Defaults to false.
.. option:: -use-color[=VALUE]
.. option:: -use-color
Enable or disable color output. By default this is autodetected.
.. option:: -arch=<name>
.. option:: -arch=[*NAMES*]
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.
Specify a list of architectures such that the Nth entry in the list
corresponds to the Nth specified binary. If the covered object is a universal
binary, this specifies 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-whitelist=<FILE>
Show code coverage only for functions listed in the given file. Each line in
the file should start with `whitelist_fun:`, immediately followed by the name
of the function to accept. This name can be a wildcard expression.
.. option:: -name-regex=<PATTERN>
Show code coverage only for functions that match the given regular expression.
@ -288,6 +297,12 @@ OPTIONS
Show code coverage only for functions with region coverage less than the given
threshold.
.. option:: -path-equivalence=<from>,<to>
Map the paths in the coverage data to local source file paths. This allows you
to generate the coverage data on one machine, and then use llvm-cov on a
different machine where you have the same files on a different path.
.. program:: llvm-cov report
.. _llvm-cov-report:
@ -330,7 +345,11 @@ OPTIONS
.. option:: -show-functions
Show coverage summaries for each function.
Show coverage summaries for each function. Defaults to false.
.. option:: -show-instantiation-summary
Show statistics for all function instantiations. Defaults to false.
.. program:: llvm-cov export
@ -363,3 +382,10 @@ OPTIONS
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:: -summary-only
Export only summary information for each file in the coverage data. This mode
will not export coverage information for smaller units such as individual
functions or regions. The result will be the same as produced by :program:
`llvm-cov report` command, but presented in JSON format rather than text.

View File

@ -1,30 +1,142 @@
llvm-dwarfdump - print contents of DWARF sections
=================================================
llvm-dwarfdump - dump and verify DWARF debug information
========================================================
SYNOPSIS
--------
:program:`llvm-dwarfdump` [*options*] [*filenames...*]
:program:`llvm-dwarfdump` [*options*] [*filename ...*]
DESCRIPTION
-----------
:program:`llvm-dwarfdump` parses DWARF sections in the object files
and prints their contents in human-readable form.
:program:`llvm-dwarfdump` parses DWARF sections in object files,
archives, and `.dSYM` bundles and prints their contents in
human-readable form. Only the .debug_info section is printed unless one of
the section-specific options or :option:`--all` is specified.
OPTIONS
-------
.. option:: -debug-dump=section
.. option:: -a, --all
Specify the DWARF section to dump.
For example, use ``abbrev`` to dump the contents of ``.debug_abbrev`` section,
``loc.dwo`` to dump the contents of ``.debug_loc.dwo`` etc.
See ``llvm-dwarfdump --help`` for the complete list of supported sections.
Use ``all`` to dump all DWARF sections. It is the default.
Disassemble all supported DWARF sections.
.. option:: --arch=<arch>
Dump DWARF debug information for the specified CPU architecture.
Architectures may be specified by name or by number. This
option can be specified multiple times, once for each desired
architecture. All CPU architectures will be printed by
default.
.. option:: -c, --show-children
Show a debug info entry's children when using
the :option:`--debug-info`, :option:`--find`,
and :option:`--name` options.
.. option:: -f <name>, --find=<name>
Search for the exact text <name> in the accelerator tables
and print the matching debug information entries.
When there is no accelerator tables or the name of the DIE
you are looking for is not found in the accelerator tables,
try using the slower but more complete :option:`--name` option.
.. option:: -F, --show-form
Show DWARF form types after the DWARF attribute types.
.. option:: -h, --help
Show help and usage for this command.
.. option:: -i, --ignore-case
Ignore case distinctions in when searching entries by name
or by regular expression.
.. option:: -n <pattern>, --name=<pattern>
Find and print all debug info entries whose name
(`DW_AT_name` attribute) matches the exact text in
<pattern>. Use the :option:`--regex` option to have
<pattern> become a regular expression for more flexible
pattern matching.
.. option:: --lookup=<address>
Lookup <address> in the debug information and print out the file,
function, block, and line table details.
.. option:: -o <path>, --out-file=<path>
Redirect output to a file specified by <path>.
.. option:: -p, --show-parents
Show a debug info entry's parent objects when using the
:option:`--debug-info`, :option:`--find`, and
:option:`--name` options.
.. option:: -r <n>, --recurse-depth=<n>
Only recurse to a maximum depth of <n> when dumping debug info
entries.
.. option:: --statistics
Collect debug info quality metrics and print the results
as machine-readable single-line JSON output.
.. option:: -x, --regex
Treat any <pattern> strings as regular expressions when searching
instead of just as an exact string match.
.. option:: -u, --uuid
Show the UUID for each architecture.
.. option:: --diff
Dump the output in a format that is more friendly for comparing
DWARF output from two different files.
.. option:: -v, --verbose
Display verbose information when dumping. This can help to debug
DWARF issues.
.. option:: --verify
Verify the structure of the DWARF information by verifying the
compile unit chains, DIE relationships graph, address
ranges, and more.
.. option:: --version
Display the version of the tool.
.. option:: --debug-abbrev, --debug-aranges, --debug-cu-index, --debug-frame [=<offset>], --debug-gnu-pubnames, --debug-gnu-pubtypes, --debug-info [=<offset>], --debug-line [=<offset>], --debug-loc [=<offset>], --debug-macro, --debug-pubnames, --debug-pubtypes, --debug-ranges, --debug-str, --debug-str-offsets, --debug-tu-index, --debug-types, --eh-frame, --gdb-index, --apple-names, --apple-types, --apple-namespaces, --apple-objc
Dump the specified DWARF section by name. Only the
`.debug_info` section is shown by default. Some entries
support adding an `=<offset>` as a way to provide an
optional offset of the exact entry to dump within the
respective section. When an offset is provided, only the
entry at that offset will be dumped, else the entire
section will be dumped. Children of items at a specific
offset can be dumped by also using the
:option:`--show-children` option where applicable.
EXIT STATUS
-----------
:program:`llvm-dwarfdump` returns 0 if the input files were parsed and dumped
successfully. Otherwise, it returns 1.
SEE ALSO
--------
:manpage:`dsymutil(1)`

View File

@ -0,0 +1,585 @@
llvm-pdbutil - PDB File forensics and diagnostics
=================================================
.. contents::
:local:
Synopsis
--------
:program:`llvm-pdbutil` [*subcommand*] [*options*]
Description
-----------
Display types, symbols, CodeView records, and other information from a
PDB file, as well as manipulate and create PDB files. :program:`llvm-pdbutil`
is normally used by FileCheck-based tests to test LLVM's PDB reading and
writing functionality, but can also be used for general PDB file investigation
and forensics, or as a replacement for cvdump.
Subcommands
-----------
:program:`llvm-pdbutil` is separated into several subcommands each tailored to
a different purpose. A brief summary of each command follows, with more detail
in the sections that follow.
* :ref:`pretty_subcommand` - Dump symbol and type information in a format that
tries to look as much like the original source code as possible.
* :ref:`dump_subcommand` - Dump low level types and structures from the PDB
file, including CodeView records, hash tables, PDB streams, etc.
* :ref:`bytes_subcommand` - Dump data from the PDB file's streams, records,
types, symbols, etc as raw bytes.
* :ref:`yaml2pdb_subcommand` - Given a yaml description of a PDB file, produce
a valid PDB file that matches that description.
* :ref:`pdb2yaml_subcommand` - For a given PDB file, produce a YAML
description of some or all of the file in a way that the PDB can be
reconstructed.
* :ref:`merge_subcommand` - Given two PDBs, produce a third PDB that is the
result of merging the two input PDBs.
.. _pretty_subcommand:
pretty
~~~~~~
.. program:: llvm-pdbutil pretty
.. important::
The **pretty** subcommand is built on the Windows DIA SDK, and as such is not
supported on non-Windows platforms.
USAGE: :program:`llvm-pdbutil` pretty [*options*] <input PDB file>
Summary
^^^^^^^^^^^
The *pretty* subcommand displays a very high level representation of your
program's debug info. Since it is built on the Windows DIA SDK which is the
standard API that Windows tools and debuggers query debug information, it
presents a more authoritative view of how a debugger is going to interpret your
debug information than a mode which displays low-level CodeView records.
Options
^^^^^^^
Filtering and Sorting Options
+++++++++++++++++++++++++++++
.. note::
*exclude* filters take priority over *include* filters. So if a filter
matches both an include and an exclude rule, then it is excluded.
.. option:: -exclude-compilands=<string>
When dumping compilands, compiland source-file contributions, or per-compiland
symbols, this option instructs **llvm-pdbutil** to omit any compilands that
match the specified regular expression.
.. option:: -exclude-symbols=<string>
When dumping global, public, or per-compiland symbols, this option instructs
**llvm-pdbutil** to omit any symbols that match the specified regular
expression.
.. option:: -exclude-types=<string>
When dumping types, this option instructs **llvm-pdbutil** to omit any types
that match the specified regular expression.
.. option:: -include-compilands=<string>
When dumping compilands, compiland source-file contributions, or per-compiland
symbols, limit the initial search to only those compilands that match the
specified regular expression.
.. option:: -include-symbols=<string>
When dumping global, public, or per-compiland symbols, limit the initial
search to only those symbols that match the specified regular expression.
.. option:: -include-types=<string>
When dumping types, limit the initial search to only those types that match
the specified regular expression.
.. option:: -min-class-padding=<uint>
Only display types that have at least the specified amount of alignment
padding, accounting for padding in base classes and aggregate field members.
.. option:: -min-class-padding-imm=<uint>
Only display types that have at least the specified amount of alignment
padding, ignoring padding in base classes and aggregate field members.
.. option:: -min-type-size=<uint>
Only display types T where sizeof(T) is greater than or equal to the specified
amount.
.. option:: -no-compiler-generated
Don't show compiler generated types and symbols
.. option:: -no-enum-definitions
When dumping an enum, don't show the full enum (e.g. the individual enumerator
values).
.. option:: -no-system-libs
Don't show symbols from system libraries
Symbol Type Options
+++++++++++++++++++
.. option:: -all
Implies all other options in this category.
.. option:: -class-definitions=<format>
Displays class definitions in the specified format.
.. code-block:: text
=all - Display all class members including data, constants, typedefs, functions, etc (default)
=layout - Only display members that contribute to class size.
=none - Don't display class definitions (e.g. only display the name and base list)
.. option:: -class-order
Displays classes in the specified order.
.. code-block:: text
=none - Undefined / no particular sort order (default)
=name - Sort classes by name
=size - Sort classes by size
=padding - Sort classes by amount of padding
=padding-pct - Sort classes by percentage of space consumed by padding
=padding-imm - Sort classes by amount of immediate padding
=padding-pct-imm - Sort classes by percentage of space consumed by immediate padding
.. option:: -class-recurse-depth=<uint>
When dumping class definitions, stop after recursing the specified number of times. The
default is 0, which is no limit.
.. option:: -classes
Display classes
.. option:: -compilands
Display compilands (e.g. object files)
.. option:: -enums
Display enums
.. option:: -externals
Dump external (e.g. exported) symbols
.. option:: -globals
Dump global symbols
.. option:: -lines
Dump the mappings between source lines and code addresses.
.. option:: -module-syms
Display symbols (variables, functions, etc) for each compiland
.. option:: -sym-types=<types>
Type of symbols to dump when -globals, -externals, or -module-syms is
specified. (default all)
.. code-block:: text
=thunks - Display thunk symbols
=data - Display data symbols
=funcs - Display function symbols
=all - Display all symbols (default)
.. option:: -symbol-order=<order>
For symbols dumped via the -module-syms, -globals, or -externals options, sort
the results in specified order.
.. code-block:: text
=none - Undefined / no particular sort order
=name - Sort symbols by name
=size - Sort symbols by size
.. option:: -typedefs
Display typedef types
.. option:: -types
Display all types (implies -classes, -enums, -typedefs)
Other Options
+++++++++++++
.. option:: -color-output
Force color output on or off. By default, color if used if outputting to a
terminal.
.. option:: -load-address=<uint>
When displaying relative virtual addresses, assume the process is loaded at the
given address and display what would be the absolute address.
.. _dump_subcommand:
dump
~~~~
USAGE: :program:`llvm-pdbutil` dump [*options*] <input PDB file>
.. program:: llvm-pdbutil dump
Summary
^^^^^^^^^^^
The **dump** subcommand displays low level information about the structure of a
PDB file. It is used heavily by LLVM's testing infrastructure, but can also be
used for PDB forensics. It serves a role similar to that of Microsoft's
`cvdump` tool.
.. note::
The **dump** subcommand exposes internal details of the file format. As
such, the reader should be familiar with :doc:`/PDB/index` before using this
command.
Options
^^^^^^^
MSF Container Options
+++++++++++++++++++++
.. option:: -streams
dump a summary of all of the streams in the PDB file.
.. option:: -stream-blocks
In conjunction with :option:`-streams`, add information to the output about
what blocks the specified stream occupies.
.. option:: -summary
Dump MSF and PDB header information.
Module & File Options
+++++++++++++++++++++
.. option:: -modi=<uint>
For all options that dump information from each module/compiland, limit to
the specified module.
.. option:: -files
Dump the source files that contribute to each displayed module.
.. option:: -il
Dump inlinee line information (DEBUG_S_INLINEELINES CodeView subsection)
.. option:: -l
Dump line information (DEBUG_S_LINES CodeView subsection)
.. option:: -modules
Dump compiland information
.. option:: -xme
Dump cross module exports (DEBUG_S_CROSSSCOPEEXPORTS CodeView subsection)
.. option:: -xmi
Dump cross module imports (DEBUG_S_CROSSSCOPEIMPORTS CodeView subsection)
Symbol Options
++++++++++++++
.. option:: -globals
dump global symbol records
.. option:: -global-extras
dump additional information about the globals, such as hash buckets and hash
values.
.. option:: -publics
dump public symbol records
.. option:: -public-extras
dump additional information about the publics, such as hash buckets and hash
values.
.. option:: -symbols
dump symbols (functions, variables, etc) for each module dumped.
.. option:: -sym-data
For each symbol record dumped as a result of the :option:`-symbols` option,
display the full bytes of the record in binary as well.
Type Record Options
+++++++++++++++++++
.. option:: -types
Dump CodeView type records from TPI stream
.. option:: -type-extras
Dump additional information from the TPI stream, such as hashes and the type
index offsets array.
.. option:: -type-data
For each type record dumped, display the full bytes of the record in binary as
well.
.. option:: -type-index=<uint>
Only dump types with the specified type index.
.. option:: -ids
Dump CodeView type records from IPI stream.
.. option:: -id-extras
Dump additional information from the IPI stream, such as hashes and the type
index offsets array.
.. option:: -id-data
For each ID record dumped, display the full bytes of the record in binary as
well.
.. option:: -id-index=<uint>
only dump ID records with the specified hexadecimal type index.
.. option:: -dependents
When used in conjunction with :option:`-type-index` or :option:`-id-index`,
dumps the entire dependency graph for the specified index instead of just the
single record with the specified index. For example, if type index 0x4000 is
a function whose return type has index 0x3000, and you specify
`-dependents=0x4000`, then this would dump both records (as well as any other
dependents in the tree).
Miscellaneous Options
+++++++++++++++++++++
.. option:: -all
Implies most other options.
.. option:: -section-contribs
Dump section contributions.
.. option:: -section-headers
Dump image section headers.
.. option:: -section-map
Dump section map.
.. option:: -string-table
Dump PDB string table.
.. _bytes_subcommand:
bytes
~~~~~
USAGE: :program:`llvm-pdbutil` bytes [*options*] <input PDB file>
.. program:: llvm-pdbutil bytes
Summary
^^^^^^^
Like the **dump** subcommand, the **bytes** subcommand displays low level
information about the structure of a PDB file, but it is used for even deeper
forensics. The **bytes** subcommand finds various structures in a PDB file
based on the command line options specified, and dumps them in hex. Someone
working on support for emitting PDBs would use this heavily, for example, to
compare one PDB against another PDB to ensure byte-for-byte compatibility. It
is not enough to simply compare the bytes of an entire file, or an entire stream
because it's perfectly fine for the same structure to exist at different
locations in two different PDBs, and "finding" the structure is half the battle.
Options
^^^^^^^
MSF File Options
++++++++++++++++
.. option:: -block-range=<start[-end]>
Dump binary data from specified range of MSF file blocks.
.. option:: -byte-range=<start[-end]>
Dump binary data from specified range of bytes in the file.
.. option:: -fpm
Dump the MSF free page map.
.. option:: -stream-data=<string>
Dump binary data from the specified streams. Format is SN[:Start][@Size].
For example, `-stream-data=7:3@12` dumps 12 bytes from stream 7, starting
at offset 3 in the stream.
PDB Stream Options
++++++++++++++++++
.. option:: -name-map
Dump bytes of PDB Name Map
DBI Stream Options
++++++++++++++++++
.. option:: -ec
Dump the edit and continue map substream of the DBI stream.
.. option:: -files
Dump the file info substream of the DBI stream.
.. option:: -modi
Dump the modi substream of the DBI stream.
.. option:: -sc
Dump section contributions substream of the DBI stream.
.. option:: -sm
Dump the section map from the DBI stream.
.. option:: -type-server
Dump the type server map from the DBI stream.
Module Options
++++++++++++++
.. option:: -mod=<uint>
Limit all options in this category to the specified module index. By default,
options in this category will dump bytes from all modules.
.. option:: -chunks
Dump the bytes of each module's C13 debug subsection.
.. option:: -split-chunks
When specified with :option:`-chunks`, split the C13 debug subsection into a
separate chunk for each subsection type, and dump them separately.
.. option:: -syms
Dump the symbol record substream from each module.
Type Record Options
+++++++++++++++++++
.. option:: -id=<uint>
Dump the record from the IPI stream with the given type index.
.. option:: -type=<uint>
Dump the record from the TPI stream with the given type index.
.. _pdb2yaml_subcommand:
pdb2yaml
~~~~~~~~
USAGE: :program:`llvm-pdbutil` pdb2yaml [*options*] <input PDB file>
.. program:: llvm-pdbutil pdb2yaml
Summary
^^^^^^^
Options
^^^^^^^
.. _yaml2pdb_subcommand:
yaml2pdb
~~~~~~~~
USAGE: :program:`llvm-pdbutil` yaml2pdb [*options*] <input YAML file>
.. program:: llvm-pdbutil yaml2pdb
Summary
^^^^^^^
Generate a PDB file from a YAML description. The YAML syntax is not described
here. Instead, use :ref:`llvm-pdbutil pdb2yaml <pdb2yaml_subcommand>` and
examine the output for an example starting point.
Options
^^^^^^^
.. option:: -pdb=<file-name>
Write the resulting PDB to the specified file.
.. _merge_subcommand:
merge
~~~~~
USAGE: :program:`llvm-pdbutil` merge [*options*] <input PDB file 1> <input PDB file 2>
.. program:: llvm-pdbutil merge
Summary
^^^^^^^
Merge two PDB files into a single file.
Options
^^^^^^^
.. option:: -pdb=<file-name>
Write the resulting PDB to the specified file.

View File

@ -1251,9 +1251,7 @@ Unices have a relatively low limit on command-line length. It is therefore
customary to use the so-called 'response files' to circumvent this
restriction. These files are mentioned on the command-line (using the "@file")
syntax. The program reads these files and inserts the contents into argv,
thereby working around the command-line length limits. Response files are
enabled by an optional fourth argument to `cl::ParseEnvironmentOptions`_ and
`cl::ParseCommandLineOptions`_.
thereby working around the command-line length limits.
Top-Level Classes and Functions
-------------------------------
@ -1324,8 +1322,7 @@ option variables once ``argc`` and ``argv`` are available.
The ``cl::ParseCommandLineOptions`` function requires two parameters (``argc``
and ``argv``), but may also take an optional third parameter which holds
`additional extra text`_ to emit when the ``-help`` option is invoked, and a
fourth boolean parameter that enables `response files`_.
`additional extra text`_ to emit when the ``-help`` option is invoked.
.. _cl::ParseEnvironmentOptions:
@ -1340,9 +1337,8 @@ command line option variables just like `cl::ParseCommandLineOptions`_ does.
It takes four parameters: the name of the program (since ``argv`` may not be
available, it can't just look in ``argv[0]``), the name of the environment
variable to examine, the optional `additional extra text`_ to emit when the
``-help`` option is invoked, and the boolean switch that controls whether
`response files`_ should be read.
variable to examine, and the optional `additional extra text`_ to emit when the
``-help`` option is invoked.
``cl::ParseEnvironmentOptions`` will break the environment variable's value up
into words and then process them using `cl::ParseCommandLineOptions`_.

View File

@ -119,7 +119,7 @@ ABI
===
* `System V Application Binary Interface <http://www.sco.com/developers/gabi/latest/contents.html>`_
* `Itanium C++ ABI <http://mentorembedded.github.io/cxx-abi/>`_
* `Itanium C++ ABI <http://itanium-cxx-abi.github.io/cxx-abi/>`_
Linux
-----

View File

@ -258,7 +258,7 @@ The coverage mapping variable generated by Clang has 3 fields:
i32 2, ; The number of function records
i32 20, ; The length of the string that contains the encoded translation unit filenames
i32 20, ; The length of the string that contains the encoded coverage mapping data
i32 1, ; Coverage mapping format version
i32 2, ; Coverage mapping format version
},
[2 x { i64, i32, i64 }] [ ; Function records
{ i64, i32, i64 } {
@ -274,6 +274,8 @@ The coverage mapping variable generated by Clang has 3 fields:
[40 x i8] c"..." ; Encoded data (dissected later)
}, section "__llvm_covmap", align 8
The current version of the format is version 3. The only difference from version 2 is that a special encoding for column end locations was introduced to indicate gap regions.
The function record layout has evolved since version 1. In version 1, the function record for *foo* is defined as follows:
.. code-block:: llvm
@ -296,7 +298,7 @@ The coverage mapping header has the following fields:
* The length of the string in the third field of *__llvm_coverage_mapping* that contains the encoded coverage mapping data.
* The format version. The current version is 2 (encoded as a 1).
* The format version. The current version is 3 (encoded as a 2).
.. _function records:
@ -602,4 +604,6 @@ The source range record contains the following fields:
* *numLines*: The difference between the ending line and the starting line
of the current mapping region.
* *columnEnd*: The ending column of the mapping region.
* *columnEnd*: The ending column of the mapping region. If the high bit is set,
the current mapping region is a gap area. A count for a gap area is only used
as the line execution count if there are no other regions on a line.

View File

@ -188,7 +188,7 @@ problem, we have a notion of an 'owner' for a piece of the code. The sole
responsibility of a code owner is to ensure that a commit to their area of the
code is appropriately reviewed, either by themself or by someone else. The list
of current code owners can be found in the file
`CODE_OWNERS.TXT <http://llvm.org/klaus/llvm/blob/master/CODE_OWNERS.TXT>`_
`CODE_OWNERS.TXT <http://git.llvm.org/klaus/llvm/blob/master/CODE_OWNERS.TXT>`_
in the root of the LLVM source tree.
Note that code ownership is completely different than reviewers: anyone can

View File

@ -32,13 +32,13 @@ execution of an application.
A more complete description of the Itanium ABI exception handling runtime
support of can be found at `Itanium C++ ABI: Exception Handling
<http://mentorembedded.github.com/cxx-abi/abi-eh.html>`_. A description of the
<http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html>`_. A description of the
exception frame format can be found at `Exception Frames
<http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html>`_,
with details of the DWARF 4 specification at `DWARF 4 Standard
<http://dwarfstd.org/Dwarf4Std.php>`_. A description for the C++ exception
table formats can be found at `Exception Handling Tables
<http://mentorembedded.github.com/cxx-abi/exceptions.pdf>`_.
<http://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf>`_.
Setjmp/Longjmp Exception Handling
---------------------------------

274
docs/FuzzingLLVM.rst Normal file
View File

@ -0,0 +1,274 @@
================================
Fuzzing LLVM libraries and tools
================================
.. contents::
:local:
:depth: 2
Introduction
============
The LLVM tree includes a number of fuzzers for various components. These are
built on top of :doc:`LibFuzzer <LibFuzzer>`.
Available Fuzzers
=================
clang-fuzzer
------------
A |generic fuzzer| that tries to compile textual input as C++ code. Some of the
bugs this fuzzer has reported are `on bugzilla`__ and `on OSS Fuzz's
tracker`__.
__ https://llvm.org/pr23057
__ https://bugs.chromium.org/p/oss-fuzz/issues/list?q=proj-llvm+clang-fuzzer
clang-proto-fuzzer
------------------
A |protobuf fuzzer| that compiles valid C++ programs generated from a protobuf
class that describes a subset of the C++ language.
This fuzzer accepts clang command line options after `ignore_remaining_args=1`.
For example, the following command will fuzz clang with a higher optimization
level:
.. code-block:: shell
% bin/clang-proto-fuzzer <corpus-dir> -ignore_remaining_args=1 -O3
clang-format-fuzzer
-------------------
A |generic fuzzer| that runs clang-format_ on C++ text fragments. Some of the
bugs this fuzzer has reported are `on bugzilla`__
and `on OSS Fuzz's tracker`__.
.. _clang-format: https://clang.llvm.org/docs/ClangFormat.html
__ https://llvm.org/pr23052
__ https://bugs.chromium.org/p/oss-fuzz/issues/list?q=proj-llvm+clang-format-fuzzer
llvm-as-fuzzer
--------------
A |generic fuzzer| that tries to parse text as :doc:`LLVM assembly <LangRef>`.
Some of the bugs this fuzzer has reported are `on bugzilla`__.
__ https://llvm.org/pr24639
llvm-dwarfdump-fuzzer
---------------------
A |generic fuzzer| that interprets inputs as object files and runs
:doc:`llvm-dwarfdump <CommandGuide/llvm-dwarfdump>` on them. Some of the bugs
this fuzzer has reported are `on OSS Fuzz's tracker`__
__ https://bugs.chromium.org/p/oss-fuzz/issues/list?q=proj-llvm+llvm-dwarfdump-fuzzer
llvm-demangle-fuzzer
---------------------
A |generic fuzzer| for the Itanium demangler used in various LLVM tools. We've
fuzzed __cxa_demangle to death, why not fuzz LLVM's implementation of the same
function!
llvm-isel-fuzzer
----------------
A |LLVM IR fuzzer| aimed at finding bugs in instruction selection.
This fuzzer accepts flags after `ignore_remaining_args=1`. The flags match
those of :doc:`llc <CommandGuide/llc>` and the triple is required. For example,
the following command would fuzz AArch64 with :doc:`GlobalISel`:
.. code-block:: shell
% bin/llvm-isel-fuzzer <corpus-dir> -ignore_remaining_args=1 -mtriple aarch64 -global-isel -O0
Some flags can also be specified in the binary name itself in order to support
OSS Fuzz, which has trouble with required arguments. To do this, you can copy
or move ``llvm-isel-fuzzer`` to ``llvm-isel-fuzzer--x-y-z``, separating options
from the binary name using "--". The valid options are architecture names
(``aarch64``, ``x86_64``), optimization levels (``O0``, ``O2``), or specific
keywords, like ``gisel`` for enabling global instruction selection. In this
mode, the same example could be run like so:
.. code-block:: shell
% bin/llvm-isel-fuzzer--aarch64-O0-gisel <corpus-dir>
llvm-opt-fuzzer
---------------
A |LLVM IR fuzzer| aimed at finding bugs in optimization passes.
It receives optimzation pipeline and runs it for each fuzzer input.
Interface of this fuzzer almost directly mirrors ``llvm-isel-fuzzer``. Both
``mtriple`` and ``passes`` arguments are required. Passes are specified in a
format suitable for the new pass manager.
.. code-block:: shell
% bin/llvm-opt-fuzzer <corpus-dir> -ignore_remaining_args=1 -mtriple x86_64 -passes instcombine
Similarly to the ``llvm-isel-fuzzer`` arguments in some predefined configurations
might be embedded directly into the binary file name:
.. code-block:: shell
% bin/llvm-opt-fuzzer--x86_64-instcombine <corpus-dir>
llvm-mc-assemble-fuzzer
-----------------------
A |generic fuzzer| that fuzzes the MC layer's assemblers by treating inputs as
target specific assembly.
Note that this fuzzer has an unusual command line interface which is not fully
compatible with all of libFuzzer's features. Fuzzer arguments must be passed
after ``--fuzzer-args``, and any ``llc`` flags must use two dashes. For
example, to fuzz the AArch64 assembler you might use the following command:
.. code-block:: console
llvm-mc-fuzzer --triple=aarch64-linux-gnu --fuzzer-args -max_len=4
This scheme will likely change in the future.
llvm-mc-disassemble-fuzzer
--------------------------
A |generic fuzzer| that fuzzes the MC layer's disassemblers by treating inputs
as assembled binary data.
Note that this fuzzer has an unusual command line interface which is not fully
compatible with all of libFuzzer's features. See the notes above about
``llvm-mc-assemble-fuzzer`` for details.
.. |generic fuzzer| replace:: :ref:`generic fuzzer <fuzzing-llvm-generic>`
.. |protobuf fuzzer|
replace:: :ref:`libprotobuf-mutator based fuzzer <fuzzing-llvm-protobuf>`
.. |LLVM IR fuzzer|
replace:: :ref:`structured LLVM IR fuzzer <fuzzing-llvm-ir>`
Mutators and Input Generators
=============================
The inputs for a fuzz target are generated via random mutations of a
:ref:`corpus <libfuzzer-corpus>`. There are a few options for the kinds of
mutations that a fuzzer in LLVM might want.
.. _fuzzing-llvm-generic:
Generic Random Fuzzing
----------------------
The most basic form of input mutation is to use the built in mutators of
LibFuzzer. These simply treat the input corpus as a bag of bits and make random
mutations. This type of fuzzer is good for stressing the surface layers of a
program, and is good at testing things like lexers, parsers, or binary
protocols.
Some of the in-tree fuzzers that use this type of mutator are `clang-fuzzer`_,
`clang-format-fuzzer`_, `llvm-as-fuzzer`_, `llvm-dwarfdump-fuzzer`_,
`llvm-mc-assemble-fuzzer`_, and `llvm-mc-disassemble-fuzzer`_.
.. _fuzzing-llvm-protobuf:
Structured Fuzzing using ``libprotobuf-mutator``
------------------------------------------------
We can use libprotobuf-mutator_ in order to perform structured fuzzing and
stress deeper layers of programs. This works by defining a protobuf class that
translates arbitrary data into structurally interesting input. Specifically, we
use this to work with a subset of the C++ language and perform mutations that
produce valid C++ programs in order to exercise parts of clang that are more
interesting than parser error handling.
To build this kind of fuzzer you need `protobuf`_ and its dependencies
installed, and you need to specify some extra flags when configuring the build
with :doc:`CMake <CMake>`. For example, `clang-proto-fuzzer`_ can be enabled by
adding ``-DCLANG_ENABLE_PROTO_FUZZER=ON`` to the flags described in
:ref:`building-fuzzers`.
The only in-tree fuzzer that uses ``libprotobuf-mutator`` today is
`clang-proto-fuzzer`_.
.. _libprotobuf-mutator: https://github.com/google/libprotobuf-mutator
.. _protobuf: https://github.com/google/protobuf
.. _fuzzing-llvm-ir:
Structured Fuzzing of LLVM IR
-----------------------------
We also use a more direct form of structured fuzzing for fuzzers that take
:doc:`LLVM IR <LangRef>` as input. This is achieved through the ``FuzzMutate``
library, which was `discussed at EuroLLVM 2017`_.
The ``FuzzMutate`` library is used to structurally fuzz backends in
`llvm-isel-fuzzer`_.
.. _discussed at EuroLLVM 2017: https://www.youtube.com/watch?v=UBbQ_s6hNgg
Building and Running
====================
.. _building-fuzzers:
Configuring LLVM to Build Fuzzers
---------------------------------
Fuzzers will be built and linked to libFuzzer by default as long as you build
LLVM with sanitizer coverage enabled. You would typically also enable at least
one sanitizer to find bugs faster. The most common way to build the fuzzers is
by adding the following two flags to your CMake invocation:
``-DLLVM_USE_SANITIZER=Address -DLLVM_USE_SANITIZE_COVERAGE=On``.
.. note:: If you have ``compiler-rt`` checked out in an LLVM tree when building
with sanitizers, you'll want to specify ``-DLLVM_BUILD_RUNTIME=Off``
to avoid building the sanitizers themselves with sanitizers enabled.
Continuously Running and Finding Bugs
-------------------------------------
There used to be a public buildbot running LLVM fuzzers continuously, and while
this did find issues, it didn't have a very good way to report problems in an
actionable way. Because of this, we're moving towards using `OSS Fuzz`_ more
instead.
You can browse the `LLVM project issue list`_ for the bugs found by
`LLVM on OSS Fuzz`_. These are also mailed to the `llvm-bugs mailing
list`_.
.. _OSS Fuzz: https://github.com/google/oss-fuzz
.. _LLVM project issue list:
https://bugs.chromium.org/p/oss-fuzz/issues/list?q=Proj-llvm
.. _LLVM on OSS Fuzz:
https://github.com/google/oss-fuzz/blob/master/projects/llvm
.. _llvm-bugs mailing list:
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs
Utilities for Writing Fuzzers
=============================
There are some utilities available for writing fuzzers in LLVM.
Some helpers for handling the command line interface are available in
``include/llvm/FuzzMutate/FuzzerCLI.h``, including functions to parse command
line options in a consistent way and to implement standalone main functions so
your fuzzer can be built and tested when not built against libFuzzer.
There is also some handling of the CMake config for fuzzers, where you should
use the ``add_llvm_fuzzer`` to set up fuzzer targets. This function works
similarly to functions such as ``add_llvm_tool``, but they take care of linking
to LibFuzzer when appropriate and can be passed the ``DUMMY_MAIN`` argument to
enable standalone testing.

View File

@ -52,6 +52,12 @@ Here's the short story for getting up and running quickly with LLVM:
* ``cd llvm/tools``
* ``svn co http://llvm.org/svn/llvm-project/cfe/trunk clang``
#. Checkout Extra Clang Tools **[Optional]**:
* ``cd where-you-want-llvm-to-live``
* ``cd llvm/tools/clang/tools``
* ``svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra``
#. Checkout LLD linker **[Optional]**:
* ``cd where-you-want-llvm-to-live``
@ -91,9 +97,9 @@ Here's the short story for getting up and running quickly with LLVM:
#. Configure and build LLVM and Clang:
*Warning:* Make sure you've checked out *all of* the source code
*Warning:* Make sure you've checked out *all of* the source code
before trying to configure with cmake. cmake does not pickup newly
added source directories in incremental builds.
added source directories in incremental builds.
The build uses `CMake <CMake.html>`_. LLVM requires CMake 3.4.3 to build. It
is generally recommended to use a recent CMake, especially if you're
@ -137,8 +143,8 @@ Here's the short story for getting up and running quickly with LLVM:
* CMake will generate build targets for each tool and library, and most
LLVM sub-projects generate their own ``check-<project>`` target.
* Running a serial build will be *slow*. Make sure you run a
parallel build; for ``make``, use ``make -j``.
* Running a serial build will be *slow*. Make sure you run a
parallel build; for ``make``, use ``make -j``.
* For more information see `CMake <CMake.html>`_
@ -146,7 +152,7 @@ Here's the short story for getting up and running quickly with LLVM:
`below`_.
Consult the `Getting Started with LLVM`_ section for detailed information on
configuring and compiling LLVM. Go to `Directory Layout`_ to learn about the
configuring and compiling LLVM. Go to `Directory Layout`_ to learn about the
layout of the source code tree.
Requirements
@ -191,10 +197,10 @@ Windows x64 x86-64 Visual Studio
Note that Debug builds require a lot of time and disk space. An LLVM-only build
will need about 1-3 GB of space. A full build of LLVM and Clang will need around
15-20 GB of disk space. The exact space requirements will vary by system. (It
is so large because of all the debugging information and the fact that the
libraries are statically linked into multiple tools).
is so large because of all the debugging information and the fact that the
libraries are statically linked into multiple tools).
If you you are space-constrained, you can build only selected tools or only
If you you are space-constrained, you can build only selected tools or only
selected targets. The Release build requires considerably less space.
The LLVM suite *may* compile on other platforms, but it is not guaranteed to do
@ -460,34 +466,13 @@ populate it with the LLVM source code, Makefiles, test directories, and local
copies of documentation files.
If you want to get a specific release (as opposed to the most recent revision),
you can checkout it from the '``tags``' directory (instead of '``trunk``'). The
you can check it out from the '``tags``' directory (instead of '``trunk``'). The
following releases are located in the following subdirectories of the '``tags``'
directory:
* Release 3.4: **RELEASE_34/final**
* Release 3.3: **RELEASE_33/final**
* Release 3.2: **RELEASE_32/final**
* Release 3.1: **RELEASE_31/final**
* Release 3.0: **RELEASE_30/final**
* Release 2.9: **RELEASE_29/final**
* Release 2.8: **RELEASE_28**
* Release 2.7: **RELEASE_27**
* Release 2.6: **RELEASE_26**
* Release 2.5: **RELEASE_25**
* Release 2.4: **RELEASE_24**
* Release 2.3: **RELEASE_23**
* Release 2.2: **RELEASE_22**
* Release 2.1: **RELEASE_21**
* Release 2.0: **RELEASE_20**
* Release 1.9: **RELEASE_19**
* Release 1.8: **RELEASE_18**
* Release 1.7: **RELEASE_17**
* Release 1.6: **RELEASE_16**
* Release 1.5: **RELEASE_15**
* Release 1.4: **RELEASE_14**
* Release 1.3: **RELEASE_13**
* Release 1.2: **RELEASE_12**
* Release 1.1: **RELEASE_11**
* Release 3.5.0 and later: **RELEASE_350/final** and so on
* Release 2.9 through 3.4: **RELEASE_29/final** and so on
* Release 1.1 through 2.8: **RELEASE_11** and so on
* Release 1.0: **RELEASE_1**
If you would like to get the LLVM test suite (a separate package as of 1.4), you
@ -512,43 +497,43 @@ clone of LLVM via:
.. code-block:: console
% git clone http://llvm.org/git/llvm.git
% git clone https://git.llvm.org/git/llvm.git/
If you want to check out clang too, run:
.. code-block:: console
% cd llvm/tools
% git clone http://llvm.org/git/clang.git
% git clone https://git.llvm.org/git/clang.git/
If you want to check out compiler-rt (required to build the sanitizers), run:
.. code-block:: console
% cd llvm/projects
% git clone http://llvm.org/git/compiler-rt.git
% git clone https://git.llvm.org/git/compiler-rt.git/
If you want to check out libomp (required for OpenMP support), run:
.. code-block:: console
% cd llvm/projects
% git clone http://llvm.org/git/openmp.git
% git clone https://git.llvm.org/git/openmp.git/
If you want to check out libcxx and libcxxabi (optional), run:
.. code-block:: console
% cd llvm/projects
% git clone http://llvm.org/git/libcxx.git
% git clone http://llvm.org/git/libcxxabi.git
% git clone https://git.llvm.org/git/libcxx.git/
% git clone https://git.llvm.org/git/libcxxabi.git/
If you want to check out the Test Suite Source Code (optional), run:
.. code-block:: console
% cd llvm/projects
% git clone http://llvm.org/git/test-suite.git
% git clone https://git.llvm.org/git/test-suite.git/
Since the upstream repository is in Subversion, you should use ``git
pull --rebase`` instead of ``git pull`` to avoid generating a non-linear history
@ -622,7 +607,7 @@ To set up clone from which you can submit code using ``git-svn``, run:
.. code-block:: console
% git clone http://llvm.org/git/llvm.git
% git clone https://git.llvm.org/git/llvm.git/
% cd llvm
% git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username>
% git config svn-remote.svn.fetch :refs/remotes/origin/master
@ -630,7 +615,7 @@ To set up clone from which you can submit code using ``git-svn``, run:
# If you have clang too:
% cd tools
% git clone http://llvm.org/git/clang.git
% git clone https://git.llvm.org/git/clang.git/
% cd clang
% git svn init https://llvm.org/svn/llvm-project/cfe/trunk --username=<username>
% git config svn-remote.svn.fetch :refs/remotes/origin/master
@ -1010,7 +995,7 @@ Directory Layout
================
One useful source of information about the LLVM source base is the LLVM `doxygen
<http://www.doxygen.org/>`_ documentation available at
<http://www.doxygen.org/>`_ documentation available at
`<http://llvm.org/doxygen/>`_. The following is a brief introduction to code
layout:
@ -1026,13 +1011,13 @@ Public header files exported from the LLVM library. The three main subdirectorie
``llvm/include/llvm``
All LLVM-specific header files, and subdirectories for different portions of
All LLVM-specific header files, and subdirectories for different portions of
LLVM: ``Analysis``, ``CodeGen``, ``Target``, ``Transforms``, etc...
``llvm/include/llvm/Support``
Generic support libraries provided with LLVM but not necessarily specific to
LLVM. For example, some C++ STL utilities and a Command Line option processing
Generic support libraries provided with LLVM but not necessarily specific to
LLVM. For example, some C++ STL utilities and a Command Line option processing
library store header files here.
``llvm/include/llvm/Config``
@ -1045,12 +1030,12 @@ Public header files exported from the LLVM library. The three main subdirectorie
``llvm/lib``
------------
Most source files are here. By putting code in libraries, LLVM makes it easy to
Most source files are here. By putting code in libraries, LLVM makes it easy to
share code among the `tools`_.
``llvm/lib/IR/``
Core LLVM source files that implement core classes like Instruction and
Core LLVM source files that implement core classes like Instruction and
BasicBlock.
``llvm/lib/AsmParser/``
@ -1063,23 +1048,23 @@ share code among the `tools`_.
``llvm/lib/Analysis/``
A variety of program analyses, such as Call Graphs, Induction Variables,
A variety of program analyses, such as Call Graphs, Induction Variables,
Natural Loop Identification, etc.
``llvm/lib/Transforms/``
IR-to-IR program transformations, such as Aggressive Dead Code Elimination,
Sparse Conditional Constant Propagation, Inlining, Loop Invariant Code Motion,
IR-to-IR program transformations, such as Aggressive Dead Code Elimination,
Sparse Conditional Constant Propagation, Inlining, Loop Invariant Code Motion,
Dead Global Elimination, and many others.
``llvm/lib/Target/``
Files describing target architectures for code generation. For example,
Files describing target architectures for code generation. For example,
``llvm/lib/Target/X86`` holds the X86 machine description.
``llvm/lib/CodeGen/``
The major parts of the code generator: Instruction Selector, Instruction
The major parts of the code generator: Instruction Selector, Instruction
Scheduling, and Register Allocation.
``llvm/lib/MC/``
@ -1088,7 +1073,7 @@ share code among the `tools`_.
``llvm/lib/ExecutionEngine/``
Libraries for directly executing bitcode at runtime in interpreted and
Libraries for directly executing bitcode at runtime in interpreted and
JIT-compiled scenarios.
``llvm/lib/Support/``
@ -1099,7 +1084,7 @@ share code among the `tools`_.
``llvm/projects``
-----------------
Projects not strictly part of LLVM but shipped with LLVM. This is also the
Projects not strictly part of LLVM but shipped with LLVM. This is also the
directory for creating your own LLVM-based projects which leverage the LLVM
build system.
@ -1112,8 +1097,8 @@ are intended to run quickly and cover a lot of territory without being exhaustiv
``test-suite``
--------------
A comprehensive correctness, performance, and benchmarking test suite for LLVM.
Comes in a separate Subversion module because not every LLVM user is interested
A comprehensive correctness, performance, and benchmarking test suite for LLVM.
Comes in a separate Subversion module because not every LLVM user is interested
in such a comprehensive suite. For details see the :doc:`Testing Guide
<TestingGuide>` document.
@ -1194,7 +1179,7 @@ because they are code generators for parts of the infrastructure.
``emacs/``
Emacs and XEmacs syntax highlighting for LLVM assembly files and TableGen
Emacs and XEmacs syntax highlighting for LLVM assembly files and TableGen
description files. See the ``README`` for information on using them.
``getsrcs.sh``

View File

@ -76,6 +76,11 @@ Here's the short story for getting up and running quickly with LLVM:
* With anonymous Subversion access:
*Note:* some regression tests require Unix-style line ending (``\n``). To
pass all regression tests, please add two lines *enable-auto-props = yes*
and *\* = svn:mime-type=application/octet-stream* to
``C:\Users\<username>\AppData\Roaming\Subversion\config``.
1. ``cd <where-you-want-llvm-to-live>``
2. ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm``
3. ``cd llvm``

View File

@ -304,10 +304,13 @@ As opposed to SelectionDAG, there are no legalization phases. In particular,
Legalization is iterative, and all state is contained in GMIR. To maintain the
validity of the intermediate code, instructions are introduced:
* ``G_SEQUENCE`` --- concatenate multiple registers into a single wider
register.
* ``G_MERGE_VALUES`` --- concatenate multiple registers of the same
size into a single wider register.
* ``G_EXTRACT`` --- extract multiple registers (as contiguous sequences of bits)
* ``G_UNMERGE_VALUES`` --- extract multiple registers of the same size
from a single wider register.
* ``G_EXTRACT`` --- extract a simple register (as contiguous sequences of bits)
from a single wider register.
As they are expected to be temporary byproducts of the legalization process,
@ -500,16 +503,69 @@ The simple API consists of:
This target-provided method is responsible for mutating (or replacing) a
possibly-generic MI into a fully target-specific equivalent.
It is also responsible for doing the necessary constraining of gvregs into the
appropriate register classes.
appropriate register classes as well as passing through COPY instructions to
the register allocator.
The ``InstructionSelector`` can fold other instructions into the selected MI,
by walking the use-def chain of the vreg operands.
As GlobalISel is Global, this folding can occur across basic blocks.
``TODO``:
Currently, the Select pass is implemented with hand-written c++, similar to
FastISel, rather than backed by tblgen'erated pattern-matching.
We intend to eventually reuse SelectionDAG patterns.
SelectionDAG Rule Imports
^^^^^^^^^^^^^^^^^^^^^^^^^
TableGen will import SelectionDAG rules and provide the following function to
execute them:
.. code-block:: c++
bool selectImpl(MachineInstr &MI)
The ``--stats`` option can be used to determine what proportion of rules were
successfully imported. The easiest way to use this is to copy the
``-gen-globalisel`` tablegen command from ``ninja -v`` and modify it.
Similarly, the ``--warn-on-skipped-patterns`` option can be used to obtain the
reasons that rules weren't imported. This can be used to focus on the most
important rejection reasons.
PatLeaf Predicates
^^^^^^^^^^^^^^^^^^
PatLeafs cannot be imported because their C++ is implemented in terms of
``SDNode`` objects. PatLeafs that handle immediate predicates should be
replaced by ``ImmLeaf``, ``IntImmLeaf``, or ``FPImmLeaf`` as appropriate.
There's no standard answer for other PatLeafs. Some standard predicates have
been baked into TableGen but this should not generally be done.
Custom SDNodes
^^^^^^^^^^^^^^
Custom SDNodes should be mapped to Target Pseudos using ``GINodeEquiv``. This
will cause the instruction selector to import them but you will also need to
ensure the target pseudo is introduced to the MIR before the instruction
selector. Any preceeding pass is suitable but the legalizer will be a
particularly common choice.
ComplexPatterns
^^^^^^^^^^^^^^^
ComplexPatterns cannot be imported because their C++ is implemented in terms of
``SDNode`` objects. GlobalISel versions should be defined with
``GIComplexOperandMatcher`` and mapped to ComplexPattern with
``GIComplexPatternEquiv``.
The following predicates are useful for porting ComplexPattern:
* isBaseWithConstantOffset() - Check for base+offset structures
* isOperandImmEqual() - Check for a particular constant
* isObviouslySafeToFold() - Check for reasons an instruction can't be sunk and folded into another.
There are some important points for the C++ implementation:
* Don't modify MIR in the predicate
* Renderer lambdas should capture by value to avoid use-after-free. They will be used after the predicate returns.
* Only create instructions in a renderer lambda. GlobalISel won't clean up things you create but don't use.
.. _maintainability:
@ -633,5 +689,14 @@ Additionally:
* ``TargetPassConfig`` --- create the passes constituting the pipeline,
including additional passes not included in the :ref:`pipeline`.
* ``GISelAccessor`` --- setup the various subtarget-provided classes, with a
graceful fallback to no-op when GlobalISel isn't enabled.
.. _other_resources:
Resources
=========
* `Global Instruction Selection - A Proposal by Quentin Colombet @LLVMDevMeeting 2015 <https://www.youtube.com/watch?v=F6GGbYtae3g>`_
* `Global Instruction Selection - Status by Quentin Colombet, Ahmed Bougacha, and Tim Northover @LLVMDevMeeting 2016 <https://www.youtube.com/watch?v=6tfb344A7w8>`_
* `GlobalISel - LLVM's Latest Instruction Selection Framework by Diana Picus @FOSDEM17 <https://www.youtube.com/watch?v=d6dF6E4BPeU>`_
* GlobalISel: Past, Present, and Future by Quentin Colombet and Ahmed Bougacha @LLVMDevMeeting 2017
* Head First into GlobalISel by Daniel Sanders, Aditya Nandakumar, and Justin Bogner @LLVMDevMeeting 2017

View File

@ -0,0 +1,201 @@
===================================================================
How to Cross Compile Compiler-rt Builtins For Arm
===================================================================
Introduction
============
This document contains information about building and testing the builtins part
of compiler-rt for an Arm target, from an x86_64 Linux machine.
While this document concentrates on Arm and Linux the general principles should
apply to other targets supported by compiler-rt. Further contributions for other
targets are welcome.
The instructions in this document depend on libraries and programs external to
LLVM, there are many ways to install and configure these dependencies so you
may need to adapt the instructions here to fit your own local situation.
Prerequisites
=============
In this use case we'll be using CMake on a Debian-based Linux system,
cross-compiling from an x86_64 host to a hard-float Armv7-A target. We'll be
using as many of the LLVM tools as we can, but it is possible to use GNU
equivalents.
* ``A build of LLVM/clang for the llvm-tools and llvm-config``
* ``The qemu-arm user mode emulator``
* ``An arm-linux-gnueabihf sysroot``
See https://compiler-rt.llvm.org/ for more information about the dependencies
on clang and LLVM.
``qemu-arm`` should be available as a package for your Linux distribution.
The most complicated of the prequisites to satisfy is the arm-linux-gnueabihf
sysroot. The :doc:`HowToCrossCompileLLVM` has information about how to use the
Linux distributions multiarch support to fulfill the dependencies for building
LLVM. Alternatively, as building and testing just the compiler-rt builtins
requires fewer dependencies than LLVM, it is possible to use the Linaro
arm-linux-gnueabihf gcc installation as our sysroot.
Building compiler-rt builtins for Arm
=====================================
We will be doing a standalone build of compiler-rt using the following cmake
options.
* ``path/to/llvm/projects/compiler-rt``
* ``-DCOMPILER_RT_BUILD_BUILTINS=ON``
* ``-DCOMPILER_RT_BUILD_SANITIZERS=OFF``
* ``-DCOMPILER_RT_BUILD_XRAY=OFF``
* ``-DCOMPILER_RT_BUILD_LIBFUZZER=OFF``
* ``-DCOMPILER_RT_BUILD_PROFILE=OFF``
* ``-DCMAKE_C_COMPILER=/path/to/clang``
* ``-DCMAKE_AR=/path/to/llvm-ar``
* ``-DCMAKE_NM=/path/to/llvm-nm``
* ``-DCMAKE_RANLIB=/path/to/llvm-ranlib``
* ``-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld"``
* ``-DCMAKE_C_COMPILER_TARGET="arm-linux-gnueabihf"``
* ``-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON``
* ``-DLLVM_CONFIG_PATH=/path/to/llvm-config``
* ``-DCMAKE_C_FLAGS="build-c-flags"``
The build-c-flags need to be sufficient to pass the C-make compiler check and
to compile compiler-rt. When using a GCC 7 Linaro arm-linux-gnueabihf
installation the following flags are needed:
* ``--target=arm-linux-gnueabihf``
* ``--march=armv7a``
* ``--gcc-toolchain=/path/to/dir/toolchain``
* ``--sysroot=/path/to/toolchain/arm-linux-gnueabihf/libc``
Depending on how your sysroot is laid out, you may not need ``--gcc-toolchain``.
For example if you have added armhf as an architecture using your Linux
distributions multiarch support then you should be able to use ``--sysroot=/``.
Once cmake has completed the builtins can be built with ``ninja builtins``
Testing compiler-rt builtins using qemu-arm
===========================================
To test the builtins library we need to add a few more cmake flags to enable
testing and set up the compiler and flags for test case. We must also tell
cmake that we wish to run the tests on ``qemu-arm``.
* ``-DCOMPILER_RT_EMULATOR="qemu-arm -L /path/to/armhf/sysroot``
* ``-DCOMPILER_RT_INCLUDE_TESTS=ON``
* ``-DCOMPILER_RT_TEST_COMPILER="/path/to/clang"``
* ``-DCOMPILER_RT_TEST_COMPILER_CFLAGS="test-c-flags"``
The ``/path/to/armhf/sysroot`` should be the same as the one passed to
``--sysroot`` in the "build-c-flags".
The "test-c-flags" can be the same as the "build-c-flags", with the addition
of ``"-fuse-ld=lld`` if you wish to use lld to link the tests.
Once cmake has completed the tests can be built and run using
``ninja check-builtins``
Modifications for other Targets
===============================
Arm Soft-Float Target
---------------------
The instructions for the Arm hard-float target can be used for the soft-float
target by substituting soft-float equivalents for the sysroot and target. The
target to use is:
* ``-DCMAKE_C_COMPILER_TARGET=arm-linux-gnueabi``
Depending on whether you want to use floating point instructions or not you
may need extra c-flags such as ``-mfloat-abi=softfp`` for use of floating-point
instructions, and ``-mfloat-abi=soft -mfpu=none`` for software floating-point
emulation.
AArch64 Target
--------------
The instructions for Arm can be used for AArch64 by substituting AArch64
equivalents for the sysroot, emulator and target.
* ``-DCMAKE_C_COMPILER_TARGET=aarch64-linux-gnu``
* ``-DCOMPILER_RT_EMULATOR="qemu-aarch64 -L /path/to/aarch64/sysroot``
The CMAKE_C_FLAGS and COMPILER_RT_TEST_COMPILER_CFLAGS may also need:
``"--sysroot=/path/to/aarch64/sysroot --gcc-toolchain=/path/to/gcc-toolchain"``
Armv6-m, Armv7-m and Armv7E-M targets
-------------------------------------
If you wish to build, but not test compiler-rt for Armv6-M, Armv7-M or Armv7E-M
then the easiest way is to use the BaremetalARM.cmake recipe in
clang/cmake/caches.
You will need a bare metal sysroot such as that provided by the GNU ARM
Embedded toolchain.
The libraries can be built with the cmake options:
* ``-DBAREMETAL_ARMV6M_SYSROOT=/path/to/bare/metal/sysroot``
* ``-DBAREMETAL_ARMV7M_SYSROOT=/path/to/bare/metal/sysroot``
* ``-DBAREMETAL_ARMV7EM_SYSROOT=/path/to/bare/metal/sysroot``
* ``-C /path/to/llvm/source/tools/clang/cmake/caches/BaremetalARM.cmake``
**Note** that for the recipe to work the compiler-rt source must be checked out
into the directory llvm/runtimes and not llvm/projects.
To build and test the libraries using a similar method to Armv7-A is possible
but more difficult. The main problems are:
* There isn't a ``qemu-arm`` user-mode emulator for bare-metal systems. The ``qemu-system-arm`` can be used but this is significantly more difficult to setup.
* The target to compile compiler-rt have the suffix -none-eabi. This uses the BareMetal driver in clang and by default won't find the libraries needed to pass the cmake compiler check.
As the Armv6-M, Armv7-M and Armv7E-M builds of compiler-rt only use instructions
that are supported on Armv7-A we can still get most of the value of running the
tests using the same ``qemu-arm`` that we used for Armv7-A by building and
running the test cases for Armv7-A but using the builtins compiled for
Armv6-M, Armv7-M or Armv7E-M. This will not catch instructions that are
supported on Armv7-A but not Armv6-M, Armv7-M and Armv7E-M.
To get the cmake compile test to pass the libraries needed to successfully link
the test application will need to be manually added to ``CMAKE_CFLAGS``.
Alternatively if you are using version 3.6 or above of cmake you can use
``CMAKE_TRY_COMPILE_TARGET=STATIC_LIBRARY`` to skip the link step.
* ``-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY``
* ``-DCOMPILER_RT_OS_DIR="baremetal"``
* ``-DCOMPILER_RT_BUILD_BUILTINS=ON``
* ``-DCOMPILER_RT_BUILD_SANITIZERS=OFF``
* ``-DCOMPILER_RT_BUILD_XRAY=OFF``
* ``-DCOMPILER_RT_BUILD_LIBFUZZER=OFF``
* ``-DCOMPILER_RT_BUILD_PROFILE=OFF``
* ``-DCMAKE_C_COMPILER=${host_install_dir}/bin/clang``
* ``-DCMAKE_C_COMPILER_TARGET="your *-none-eabi target"``
* ``-DCMAKE_AR=/path/to/llvm-ar``
* ``-DCMAKE_NM=/path/to/llvm-nm``
* ``-DCMAKE_RANLIB=/path/to/llvm-ranlib``
* ``-DCOMPILER_RT_BAREMETAL_BUILD=ON``
* ``-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON``
* ``-DLLVM_CONFIG_PATH=/path/to/llvm-config``
* ``-DCMAKE_C_FLAGS="build-c-flags"``
* ``-DCMAKE_ASM_FLAGS="${arm_cflags}"``
* ``-DCOMPILER_RT_EMULATOR="qemu-arm -L /path/to/armv7-A/sysroot"``
* ``-DCOMPILER_RT_INCLUDE_TESTS=ON``
* ``-DCOMPILER_RT_TEST_COMPILER="/path/to/clang"``
* ``-DCOMPILER_RT_TEST_COMPILER_CFLAGS="test-c-flags"``
The Armv6-M builtins will use the soft-float ABI. When compiling the tests for
Armv7-A we must include ``"-mthumb -mfloat-abi=soft -mfpu=none"`` in the
test-c-flags. We must use an Armv7-A soft-float abi sysroot for ``qemu-arm``.
Unfortunately at time of writing the Armv7-M and Armv7E-M builds of
compiler-rt will always include assembler files including floating point
instructions. This means that building for a cpu without a floating point unit
requires something like removing the arm_Thumb1_VFPv2_SOURCES from the
arm_Thumb1_SOURCES in builtins/CMakeLists.txt. The float-abi of the compiler-rt
library must be matched by the float abi of the Armv7-A sysroot used by
qemu-arm.
Depending on the linker used for the test cases you may encounter BuildAttribute
mismatches between the M-profile objects from compiler-rt and the A-profile
objects from the test. The lld linker does not check the BuildAttributes so it
can be used to link the tests by adding -fuse-ld=lld to the
``COMPILER_RT_TEST_COMPILER_CFLAGS``.

View File

@ -256,6 +256,28 @@ If a bug can't be reproduced, or stops being a blocker, it should be removed
from the Meta and its priority decreased to *normal*. Debugging can continue,
but on trunk.
Merge Requests
--------------
You can use any of the following methods to request that a revision from trunk
be merged into a release branch:
#. Use the ``utils/release/merge-request.sh`` script which will automatically
file a bug_ requesting that the patch be merged. e.g. To request revision
12345 be merged into the branch for the 5.0.1 release:
``llvm.src/utils/release/merge-request.sh -stable-version 5.0 -r 12345 -user bugzilla@example.com``
#. Manually file a bug_ with the subject: "Merge r12345 into the X.Y branch",
enter the commit(s) that you want merged in the "Fixed by Commit(s)" and mark
it as a blocker of the current release bug. Release bugs are given aliases
in the form of release-x.y.z, so to mark a bug as a blocker for the 5.0.1
release, just enter release-5.0.1 in the "Blocks" field.
#. Reply to the commit email on llvm-commits for the revision to merge and cc
the release manager.
.. _bug: https://bugs.llvm.org/
Release Patch Rules
-------------------

File diff suppressed because it is too large Load Diff

View File

@ -109,6 +109,11 @@ G
Garbage Collection. The practice of using reachability analysis instead of
explicit memory management to reclaim unused memory.
**GEP**
``GetElementPtr``. An LLVM IR instruction that is used to get the address
of a subelement of an aggregate data structure. It is documented in detail
`here <http://llvm.org/docs/GetElementPtr.html>`_.
**GVN**
Global Value Numbering. GVN is a pass that partitions values computed by a
function into congruence classes. Values ending up in the same congruence

View File

@ -24,28 +24,9 @@ Versions
========
LibFuzzer is under active development so you will need the current
(or at least a very recent) version of the Clang compiler.
(or at least a very recent) version of the Clang compiler (see `building Clang from trunk`_)
(If `building Clang from trunk`_ is too time-consuming or difficult, then
the Clang binaries that the Chromium developers build are likely to be
fairly recent:
.. code-block:: console
mkdir TMP_CLANG
cd TMP_CLANG
git clone https://chromium.googlesource.com/chromium/src/tools/clang
cd ..
TMP_CLANG/clang/scripts/update.py
This installs the Clang binary as
``./third_party/llvm-build/Release+Asserts/bin/clang``)
The libFuzzer code resides in the LLVM repository, and requires a recent Clang
compiler to build (and is used to `fuzz various parts of LLVM itself`_).
However the fuzzer itself does not (and should not) depend on any part of LLVM
infrastructure and can be used for other projects without requiring the rest
of LLVM.
Refer to https://releases.llvm.org/5.0.0/docs/LibFuzzer.html for documentation on the older version.
Getting Started
@ -90,40 +71,33 @@ Some important things to remember about fuzz targets:
Fuzzer Usage
------------
Very recent versions of Clang (> April 20 2017) include libFuzzer,
and no installation is necessary.
In order to fuzz your binary, use the `-fsanitize=fuzzer` flag during the compilation::
Recent versions of Clang (starting from 6.0) include libFuzzer, and no extra installation is necessary.
clang -fsanitize=fuzzer,address mytarget.c
In order to build your fuzzer binary, use the `-fsanitize=fuzzer` flag during the
compilation and linking. In most cases you may want to combine libFuzzer with
AddressSanitizer_ (ASAN), UndefinedBehaviorSanitizer_ (UBSAN), or both::
Otherwise, build the libFuzzer library as a static archive, without any sanitizer
options. Note that the libFuzzer library contains the ``main()`` function:
clang -g -O1 -fsanitize=fuzzer mytarget.c # Builds the fuzz target w/o sanitizers
clang -g -O1 -fsanitize=fuzzer,address mytarget.c # Builds the fuzz target with ASAN
clang -g -O1 -fsanitize=fuzzer,signed-integer-overflow mytarget.c # Builds the fuzz target with a part of UBSAN
.. code-block:: console
This will perform the necessary instrumentation, as well as linking with the libFuzzer library.
Note that ``-fsanitize=fuzzer`` links in the libFuzzer's ``main()`` symbol.
svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer # or git clone https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer
./Fuzzer/build.sh # Produces libFuzzer.a
If modifying ``CFLAGS`` of a large project, which also compiles executables
requiring their own ``main`` symbol, it may be desirable to request just the
instrumentation without linking::
Then build the fuzzing target function and the library under test using
the SanitizerCoverage_ option, which instruments the code so that the fuzzer
can retrieve code coverage information (to guide the fuzzing). Linking with
the libFuzzer code then gives a fuzzer executable.
clang -fsanitize=fuzzer-no-link mytarget.c
You should also enable one or more of the *sanitizers*, which help to expose
latent bugs by making incorrect behavior generate errors at runtime:
Then libFuzzer can be linked to the desired driver by passing in
``-fsanitize=fuzzer`` during the linking stage.
- AddressSanitizer_ (ASAN) detects memory access errors. Use `-fsanitize=address`.
- UndefinedBehaviorSanitizer_ (UBSAN) detects the use of various features of C/C++ that are explicitly
listed as resulting in undefined behavior. Use `-fsanitize=undefined -fno-sanitize-recover=undefined`
or any individual UBSAN check, e.g. `-fsanitize=signed-integer-overflow -fno-sanitize-recover=undefined`.
You may combine ASAN and UBSAN in one build.
- MemorySanitizer_ (MSAN) detects uninitialized reads: code whose behavior relies on memory
contents that have not been initialized to a specific value. Use `-fsanitize=memory`.
MSAN can not be combined with other sanirizers and should be used as a seprate build.
Using MemorySanitizer_ (MSAN) with libFuzzer is possible too, but tricky.
The exact details are out of scope, we expect to simplify this in future
versions.
Finally, link with ``libFuzzer.a``::
clang -fsanitize-coverage=trace-pc-guard -fsanitize=address your_lib.cc fuzz_target.cc libFuzzer.a -o my_fuzzer
.. _libfuzzer-corpus:
Corpus
------
@ -161,7 +135,6 @@ Only the inputs that trigger new coverage will be added to the first corpus.
./my_fuzzer -merge=1 CURRENT_CORPUS_DIR NEW_POTENTIALLY_INTERESTING_INPUTS_DIR
Running
-------
@ -208,6 +181,33 @@ running with ``-jobs=30`` on a 12-core machine would run 6 workers by default,
with each worker averaging 5 bugs by completion of the entire process.
Resuming merge
--------------
Merging large corpora may be time consuming, and it is often desirable to do it
on preemptable VMs, where the process may be killed at any time.
In order to seamlessly resume the merge, use the ``-merge_control_file`` flag
and use ``killall -SIGUSR1 /path/to/fuzzer/binary`` to stop the merge gracefully. Example:
.. code-block:: console
% rm -f SomeLocalPath
% ./my_fuzzer CORPUS1 CORPUS2 -merge=1 -merge_control_file=SomeLocalPath
...
MERGE-INNER: using the control file 'SomeLocalPath'
...
# While this is running, do `killall -SIGUSR1 my_fuzzer` in another console
==9015== INFO: libFuzzer: exiting as requested
# This will leave the file SomeLocalPath with the partial state of the merge.
# Now, you can continue the merge by executing the same command. The merge
# will continue from where it has been interrupted.
% ./my_fuzzer CORPUS1 CORPUS2 -merge=1 -merge_control_file=SomeLocalPath
...
MERGE-OUTER: non-empty control file provided: 'SomeLocalPath'
MERGE-OUTER: control file ok, 32 files total, first not processed file 20
...
Options
=======
@ -246,6 +246,10 @@ The most important command line options are:
the process is treated as a failure case.
The limit is checked in a separate thread every second.
If running w/o ASAN/MSAN, you may use 'ulimit -v' instead.
``-malloc_limit_mb``
If non-zero, the fuzzer will exit if the target tries to allocate this
number of Mb with one malloc call.
If zero (default) same limit as rss_limit_mb is applied.
``-timeout_exitcode``
Exit code (default 77) used if libFuzzer reports a timeout.
``-error_exitcode``
@ -257,6 +261,10 @@ The most important command line options are:
If set to 1, any corpus inputs from the 2nd, 3rd etc. corpus directories
that trigger new code coverage will be merged into the first corpus
directory. Defaults to 0. This flag can be used to minimize a corpus.
``-merge_control_file``
Specify a control file used for the merge proccess.
If a merge process gets killed it tries to leave this file in a state
suitable for resuming the merge. By default a temporary file will be used.
``-minimize_crash``
If 1, minimizes the provided crash input.
Use with -runs=N or -max_total_time=N to limit the number of attempts.
@ -278,6 +286,9 @@ The most important command line options are:
``-use_counters``
Use `coverage counters`_ to generate approximate counts of how often code
blocks are hit; defaults to 1.
``-reduce_inputs``
Try to reduce the size of inputs while preserving their full feature sets;
defaults to 1.
``-use_value_profile``
Use `value profile`_ to guide corpus expansion; defaults to 0.
``-only_ascii``
@ -305,10 +316,6 @@ The most important command line options are:
- 1 : close ``stdout``
- 2 : close ``stderr``
- 3 : close both ``stdout`` and ``stderr``.
``-print_coverage``
If 1, print coverage information as text at exit.
``-dump_coverage``
If 1, dump coverage information as a .sancov file at exit.
For the full list of flags run the fuzzer binary with ``-help=1``.
@ -345,6 +352,9 @@ possible event codes are:
``NEW``
The fuzzer has created a test input that covers new areas of the code
under test. This input will be saved to the primary corpus directory.
``REDUCE``
The fuzzer has found a better (smaller) input that triggers previously
discovered features (set ``-reduce_inputs=0`` to disable).
``pulse``
The fuzzer has generated 2\ :sup:`n` inputs (generated periodically to reassure
the user that the fuzzer is still working).
@ -465,7 +475,7 @@ Tracing CMP instructions
------------------------
With an additional compiler flag ``-fsanitize-coverage=trace-cmp``
(see SanitizerCoverageTraceDataFlow_)
(on by default as part of ``-fsanitize=fuzzer``, see SanitizerCoverageTraceDataFlow_)
libFuzzer will intercept CMP instructions and guide mutations based
on the arguments of intercepted CMP instructions. This may slow down
the fuzzing but is very likely to improve the results.
@ -473,7 +483,6 @@ the fuzzing but is very likely to improve the results.
Value Profile
-------------
*EXPERIMENTAL*.
With ``-fsanitize-coverage=trace-cmp``
and extra run-time flag ``-use_value_profile=1`` the fuzzer will
collect value profiles for the parameters of compare instructions
@ -535,7 +544,7 @@ Periodically restart both fuzzers so that they can use each other's findings.
Currently, there is no simple way to run both fuzzing engines in parallel while sharing the same corpus dir.
You may also use AFL on your target function ``LLVMFuzzerTestOneInput``:
see an example `here <https://github.com/llvm-mirror/llvm/blob/master/lib/Fuzzer/afl/afl_driver.cpp>`__.
see an example `here <https://github.com/llvm-mirror/compiler-rt/tree/master/lib/fuzzer/afl>`__.
How good is my fuzzer?
----------------------
@ -543,28 +552,12 @@ 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:
.. code-block:: console
We recommend to use
`Clang Coverage <http://clang.llvm.org/docs/SourceBasedCodeCoverage.html>`_,
to visualize and study your code coverage
(`example <https://github.com/google/fuzzer-test-suite/blob/master/tutorial/libFuzzerTutorial.md#visualizing-coverage>`_).
./fuzzer CORPUS_DIR -runs=0 -print_coverage=1
This will run all tests in the CORPUS_DIR but will not perform any fuzzing.
At the end of the process it will print text describing what code has been covered and what hasn't.
Alternatively, use
.. code-block:: console
./fuzzer CORPUS_DIR -runs=0 -dump_coverage=1
which will dump a ``.sancov`` file with coverage information.
See SanitizerCoverage_ for details on querying the file using the ``sancov`` tool.
You may also use other ways to visualize coverage,
e.g. using `Clang coverage <http://clang.llvm.org/docs/SourceBasedCodeCoverage.html>`_,
but those will require
you to rebuild the code with different compiler flags.
User-supplied mutators
----------------------
@ -621,75 +614,17 @@ you will eventually run out of RAM (see the ``-rss_limit_mb`` flag).
Developing libFuzzer
====================
Building libFuzzer as a part of LLVM project and running its test requires
fresh clang as the host compiler and special CMake configuration:
LibFuzzer is built as a part of LLVM project by default on macos and Linux.
Users of other operating systems can explicitly request compilation using
``-DLIBFUZZER_ENABLE=YES`` flag.
Tests are run using ``check-fuzzer`` target from the build directory
which was configured with ``-DLIBFUZZER_ENABLE_TESTS=ON`` flag.
.. code-block:: console
cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_USE_SANITIZER=Address -DLLVM_USE_SANITIZE_COVERAGE=YES -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON /path/to/llvm
ninja check-fuzzer
Fuzzing components of LLVM
==========================
.. contents::
:local:
:depth: 1
To build any of the LLVM fuzz targets use the build instructions above.
clang-format-fuzzer
-------------------
The inputs are random pieces of C++-like text.
.. code-block:: console
ninja clang-format-fuzzer
mkdir CORPUS_DIR
./bin/clang-format-fuzzer CORPUS_DIR
Optionally build other kinds of binaries (ASan+Debug, MSan, UBSan, etc).
Tracking bug: https://llvm.org/bugs/show_bug.cgi?id=23052
clang-fuzzer
------------
The behavior is very similar to ``clang-format-fuzzer``.
Tracking bug: https://llvm.org/bugs/show_bug.cgi?id=23057
llvm-as-fuzzer
--------------
Tracking bug: https://llvm.org/bugs/show_bug.cgi?id=24639
llvm-mc-fuzzer
--------------
This tool fuzzes the MC layer. Currently it is only able to fuzz the
disassembler but it is hoped that assembly, and round-trip verification will be
added in future.
When run in dissassembly mode, the inputs are opcodes to be disassembled. The
fuzzer will consume as many instructions as possible and will stop when it
finds an invalid instruction or runs out of data.
Please note that the command line interface differs slightly from that of other
fuzzers. The fuzzer arguments should follow ``--fuzzer-args`` and should have
a single dash, while other arguments control the operation mode and target in a
similar manner to ``llvm-mc`` and should have two dashes. For example:
.. code-block:: console
llvm-mc-fuzzer --triple=aarch64-linux-gnu --disassemble --fuzzer-args -max_len=4 -jobs=10
Buildbot
--------
A buildbot continuously runs the above fuzzers for LLVM components, with results
shown at http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fuzzer .
FAQ
=========================
@ -748,6 +683,8 @@ network, crypto.
Trophies
========
* Thousands of bugs found on OSS-Fuzz: https://opensource.googleblog.com/2017/05/oss-fuzz-five-months-later-and.html
* GLIBC: https://sourceware.org/glibc/wiki/FuzzingLibc
* MUSL LIBC: `[1] <http://git.musl-libc.org/cgit/musl/commit/?id=39dfd58417ef642307d90306e1c7e50aaec5a35c>`__ `[2] <http://www.openwall.com/lists/oss-security/2015/03/30/3>`__
@ -774,6 +711,8 @@ Trophies
* `Linux Kernel's BPF verifier <https://github.com/iovisor/bpf-fuzzer>`_
* `Linux Kernel's Crypto code <https://www.spinics.net/lists/stable/msg199712.html>`_
* Capstone: `[1] <https://github.com/aquynh/capstone/issues/600>`__ `[2] <https://github.com/aquynh/capstone/commit/6b88d1d51eadf7175a8f8a11b690684443b11359>`__
* file:`[1] <http://bugs.gw.com/view.php?id=550>`__ `[2] <http://bugs.gw.com/view.php?id=551>`__ `[3] <http://bugs.gw.com/view.php?id=553>`__ `[4] <http://bugs.gw.com/view.php?id=554>`__
@ -792,6 +731,8 @@ Trophies
* `Wireshark <https://bugs.wireshark.org/bugzilla/buglist.cgi?bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&bug_status=INCOMPLETE&bug_status=RESOLVED&bug_status=VERIFIED&f0=OP&f1=OP&f2=product&f3=component&f4=alias&f5=short_desc&f7=content&f8=CP&f9=CP&j1=OR&o2=substring&o3=substring&o4=substring&o5=substring&o6=substring&o7=matches&order=bug_id%20DESC&query_format=advanced&v2=libfuzzer&v3=libfuzzer&v4=libfuzzer&v5=libfuzzer&v6=libfuzzer&v7=%22libfuzzer%22>`_
* `QEMU <https://researchcenter.paloaltonetworks.com/2017/09/unit42-palo-alto-networks-discovers-new-qemu-vulnerability/>`_
.. _pcre2: http://www.pcre.org/
.. _AFL: http://lcamtuf.coredump.cx/afl/
.. _Radamsa: https://github.com/aoh/radamsa
@ -800,7 +741,7 @@ Trophies
.. _AddressSanitizer: http://clang.llvm.org/docs/AddressSanitizer.html
.. _LeakSanitizer: http://clang.llvm.org/docs/LeakSanitizer.html
.. _Heartbleed: http://en.wikipedia.org/wiki/Heartbleed
.. _FuzzerInterface.h: https://github.com/llvm-mirror/llvm/blob/master/lib/Fuzzer/FuzzerInterface.h
.. _FuzzerInterface.h: https://github.com/llvm-mirror/compiler-rt/blob/master/lib/fuzzer/FuzzerInterface.h
.. _3.7.0: http://llvm.org/releases/3.7.0/docs/LibFuzzer.html
.. _building Clang from trunk: http://clang.llvm.org/get_started.html
.. _MemorySanitizer: http://clang.llvm.org/docs/MemorySanitizer.html
@ -809,4 +750,4 @@ Trophies
.. _`value profile`: #value-profile
.. _`caller-callee pairs`: http://clang.llvm.org/docs/SanitizerCoverage.html#caller-callee-coverage
.. _BoringSSL: https://boringssl.googlesource.com/boringssl/
.. _`fuzz various parts of LLVM itself`: `Fuzzing components of LLVM`_

View File

@ -121,6 +121,8 @@ Tests are more accessible and future proof when simplified:
contains dummy functions (see above). The .mir loader will create the
IR functions automatically in this case.
.. _limitations:
Limitations
-----------
@ -238,6 +240,8 @@ in the block's definition:
The block's name should be identical to the name of the IR block that this
machine block is based on.
.. _block-references:
Block References
^^^^^^^^^^^^^^^^
@ -246,13 +250,25 @@ blocks are referenced using the following syntax:
.. code-block:: text
%bb.<id>[.<name>]
%bb.<id>
Examples:
Example:
.. code-block:: llvm
%bb.0
The following syntax is also supported, but the former syntax is preferred for
block references:
.. code-block:: text
%bb.<id>[.<name>]
Example:
.. code-block:: llvm
%bb.1.then
Successors
@ -418,7 +434,40 @@ immediate machine operand ``-42``:
%eax = MOV32ri -42
.. TODO: Describe the CIMM (Rare) and FPIMM immediate operands.
An immediate operand is also used to represent a subregister index when the
machine instruction has one of the following opcodes:
- ``EXTRACT_SUBREG``
- ``INSERT_SUBREG``
- ``REG_SEQUENCE``
- ``SUBREG_TO_REG``
In case this is true, the Machine Operand is printed according to the target.
For example:
In AArch64RegisterInfo.td:
.. code-block:: text
def sub_32 : SubRegIndex<32>;
If the third operand is an immediate with the value ``15`` (target-dependent
value), based on the instruction's opcode and the operand's index the operand
will be printed as ``%subreg.sub_32``:
.. code-block:: text
%1:gpr64 = SUBREG_TO_REG 0, %0, %subreg.sub_32
For integers > 64bit, we use a special machine operand, ``MO_CImmediate``,
which stores the immediate in a ``ConstantInt`` using an ``APInt`` (LLVM's
arbitrary precision integers).
.. TODO: Describe the FPIMM immediate operands.
.. _register-operands:
@ -484,6 +533,9 @@ corresponding internal ``llvm::RegState`` representation:
* - ``debug-use``
- ``RegState::Debug``
* - ``renamable``
- ``RegState::Renamable``
.. _subregister-indices:
Subregister Indices
@ -501,6 +553,53 @@ lower bits from the 32-bit virtual register 0 to the 8-bit virtual register 1:
The names of the subregister indices are target specific, and are typically
defined in the target's ``*RegisterInfo.td`` file.
Constant Pool Indices
^^^^^^^^^^^^^^^^^^^^^
A constant pool index (CPI) operand is printed using its index in the
function's ``MachineConstantPool`` and an offset.
For example, a CPI with the index 1 and offset 8:
.. code-block:: text
%1:gr64 = MOV64ri %const.1 + 8
For a CPI with the index 0 and offset -12:
.. code-block:: text
%1:gr64 = MOV64ri %const.0 - 12
A constant pool entry is bound to a LLVM IR ``Constant`` or a target-specific
``MachineConstantPoolValue``. When serializing all the function's constants the
following format is used:
.. code-block:: text
constants:
- id: <index>
value: <value>
alignment: <alignment>
isTargetSpecific: <target-specific>
where ``<index>`` is a 32-bit unsigned integer, ``<value>`` is a `LLVM IR Constant
<https://www.llvm.org/docs/LangRef.html#constants>`_, alignment is a 32-bit
unsigned integer, and ``<target-specific>`` is either true or false.
Example:
.. code-block:: text
constants:
- id: 0
value: 'double 3.250000e+00'
alignment: 8
- id: 1
value: 'g-(LPC0+8)'
alignment: 4
isTargetSpecific: true
Global Value Operands
^^^^^^^^^^^^^^^^^^^^^
@ -520,24 +619,91 @@ If the identifier doesn't match the regular expression
The unnamed global values are represented using an unsigned numeric value with
the '@' prefix, like in the following examples: ``@0``, ``@989``.
Target-dependent Index Operands
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A target index operand is a target-specific index and an offset. The
target-specific index is printed using target-specific names and a positive or
negative offset.
For example, the ``amdgpu-constdata-start`` is associated with the index ``0``
in the AMDGPU backend. So if we have a target index operand with the index 0
and the offset 8:
.. code-block:: text
%sgpr2 = S_ADD_U32 _, target-index(amdgpu-constdata-start) + 8, implicit-def _, implicit-def _
Jump-table Index Operands
^^^^^^^^^^^^^^^^^^^^^^^^^
A jump-table index operand with the index 0 is printed as following:
.. code-block:: text
tBR_JTr killed %r0, %jump-table.0
A machine jump-table entry contains a list of ``MachineBasicBlocks``. When serializing all the function's jump-table entries, the following format is used:
.. code-block:: text
jumpTable:
kind: <kind>
entries:
- id: <index>
blocks: [ <bbreference>, <bbreference>, ... ]
where ``<kind>`` is describing how the jump table is represented and emitted (plain address, relocations, PIC, etc.), and each ``<index>`` is a 32-bit unsigned integer and ``blocks`` contains a list of :ref:`machine basic block references <block-references>`.
Example:
.. code-block:: text
jumpTable:
kind: inline
entries:
- id: 0
blocks: [ '%bb.3', '%bb.9', '%bb.4.d3' ]
- id: 1
blocks: [ '%bb.7', '%bb.7', '%bb.4.d3', '%bb.5' ]
External Symbol Operands
^^^^^^^^^^^^^^^^^^^^^^^^^
An external symbol operand is represented using an identifier with the ``$``
prefix. The identifier is surrounded with ""'s and escaped if it has any
special non-printable characters in it.
Example:
.. code-block:: text
CALL64pcrel32 $__stack_chk_fail, csr_64, implicit %rsp, implicit-def %rsp
MCSymbol Operands
^^^^^^^^^^^^^^^^^
A MCSymbol operand is holding a pointer to a ``MCSymbol``. For the limitations
of this operand in MIR, see :ref:`limitations <limitations>`.
The syntax is:
.. code-block:: text
EH_LABEL <mcsymbol Ltmp1>
.. TODO: Describe the parsers default behaviour when optional YAML attributes
are missing.
.. TODO: Describe the syntax for the bundled instructions.
.. TODO: Describe the syntax for virtual register YAML definitions.
.. TODO: Describe the machine function's YAML flag attributes.
.. TODO: Describe the syntax for the external symbol and register
mask machine operands.
.. TODO: Describe the syntax for the register mask machine operands.
.. TODO: Describe the frame information YAML mapping.
.. TODO: Describe the syntax of the stack object machine operands and their
YAML definitions.
.. TODO: Describe the syntax of the constant pool machine operands and their
YAML definitions.
.. TODO: Describe the syntax of the jump table machine operands and their
YAML definitions.
.. TODO: Describe the syntax of the block address machine operands.
.. TODO: Describe the syntax of the CFI index machine operands.
.. TODO: Describe the syntax of the metadata machine operands, and the
instructions debug location attribute.
.. TODO: Describe the syntax of the target index machine operands.
.. TODO: Describe the syntax of the register live out machine operands.
.. TODO: Describe the syntax of the machine memory operands.

View File

@ -499,7 +499,7 @@ The output we get from ``llc`` (as of LLVM 3.4):
.reg .s32 %r<2>;
.reg .s64 %rl<8>;
// BB#0: // %entry
// %bb.0: // %entry
ld.param.u64 %rl1, [kernel_param_0];
mov.u32 %r1, %tid.x;
mul.wide.s32 %rl2, %r1, 4;
@ -897,7 +897,7 @@ This gives us the following PTX (excerpt):
.reg .s32 %r<21>;
.reg .s64 %rl<8>;
// BB#0: // %entry
// %bb.0: // %entry
ld.param.u64 %rl2, [kernel_param_0];
mov.u32 %r3, %tid.x;
ld.param.u64 %rl3, [kernel_param_1];
@ -921,7 +921,7 @@ This gives us the following PTX (excerpt):
abs.f32 %f4, %f1;
setp.gtu.f32 %p4, %f4, 0f7F800000;
@%p4 bra BB0_4;
// BB#3: // %__nv_isnanf.exit5.i
// %bb.3: // %__nv_isnanf.exit5.i
abs.f32 %f5, %f2;
setp.le.f32 %p5, %f5, 0f7F800000;
@%p5 bra BB0_5;
@ -953,7 +953,7 @@ This gives us the following PTX (excerpt):
selp.f32 %f110, 0f7F800000, %f99, %p16;
setp.eq.f32 %p17, %f110, 0f7F800000;
@%p17 bra BB0_28;
// BB#27:
// %bb.27:
fma.rn.f32 %f110, %f110, %f108, %f110;
BB0_28: // %__internal_accurate_powf.exit.i
setp.lt.f32 %p18, %f1, 0f00000000;

View File

@ -441,6 +441,15 @@ the program where they can be handled appropriately. Handling the error may be
as simple as reporting the issue to the user, or it may involve attempts at
recovery.
.. note::
While it would be ideal to use this error handling scheme throughout
LLVM, there are places where this hasn't been practical to apply. In
situations where you absolutely must emit a non-programmatic error and
the ``Error`` model isn't workable you can call ``report_fatal_error``,
which will call installed error handlers, print a message, and exit the
program.
Recoverable errors are modeled using LLVM's ``Error`` scheme. This scheme
represents errors using function return values, similar to classic C integer
error codes, or C++'s ``std::error_code``. However, the ``Error`` class is
@ -486,7 +495,7 @@ that inherits from the ErrorInfo utility, E.g.:
Error printFormattedFile(StringRef Path) {
if (<check for valid format>)
return make_error<InvalidObjectFile>(Path);
return make_error<BadFileFormat>(Path);
// print file contents.
return Error::success();
}
@ -1224,7 +1233,7 @@ Define your DebugCounter like this:
.. code-block:: c++
DEBUG_COUNTER(DeleteAnInstruction, "passname-delete-instruction",
"Controls which instructions get delete").
"Controls which instructions get delete");
The ``DEBUG_COUNTER`` macro defines a static variable, whose name
is specified by the first argument. The name of the counter
@ -2105,7 +2114,7 @@ is stored in the same allocation as the Value of a pair).
StringMap also provides query methods that take byte ranges, so it only ever
copies a string if a value is inserted into the table.
StringMap iteratation order, however, is not guaranteed to be deterministic, so
StringMap iteration order, however, is not guaranteed to be deterministic, so
any uses which require that should instead use a std::map.
.. _dss_indexmap:

View File

@ -82,8 +82,14 @@ The design of VPlan follows several high-level guidelines:
replicated VF*UF times to handle scalarized and predicated instructions.
Innerloops are also modelled as SESE regions.
Low-level Design
================
7. Support instruction-level analysis and transformation, as part of Planning
Step 2.b: During vectorization instructions may need to be traversed, moved,
replaced by other instructions or be created. For example, vector idiom
detection and formation involves searching for and optimizing instruction
patterns.
Definitions
===========
The low-level design of VPlan comprises of the following classes.
:LoopVectorizationPlanner:
@ -139,11 +145,64 @@ The low-level design of VPlan comprises of the following classes.
instructions; e.g., cloned once, replicated multiple times or widened
according to selected VF.
:VPValue:
The base of VPlan's def-use relations class hierarchy. When instantiated, it
models a constant or a live-in Value in VPlan. It has users, which are of type
VPUser, but no operands.
:VPUser:
A VPValue representing a general vertex in the def-use graph of VPlan. It has
operands which are of type VPValue. When instantiated, it represents a
live-out Instruction that exists outside VPlan. VPUser is similar in some
aspects to LLVM's User class.
:VPInstruction:
A VPInstruction is both a VPRecipe and a VPUser. It models a single
VPlan-level instruction to be generated if the VPlan is executed, including
its opcode and possibly additional characteristics. It is the basis for
writing instruction-level analyses and optimizations in VPlan as creating,
replacing or moving VPInstructions record both def-use and scheduling
decisions. VPInstructions also extend LLVM IR's opcodes with idiomatic
operations that enrich the Vectorizer's semantics.
:VPTransformState:
Stores information used for generating output IR, passed from
LoopVectorizationPlanner to its selected VPlan for execution, and used to pass
additional information down to VPBlocks and VPRecipes.
The Planning Process and VPlan Roadmap
======================================
Transforming the Loop Vectorizer to use VPlan follows a staged approach. First,
VPlan is used to record the final vectorization decisions, and to execute them:
the Hierarchical CFG models the planned control-flow, and Recipes capture
decisions taken inside basic-blocks. Next, VPlan will be used also as the basis
for taking these decisions, effectively turning them into a series of
VPlan-to-VPlan algorithms. Finally, VPlan will support the planning process
itself including cost-based analyses for making these decisions, to fully
support compositional and iterative decision making.
Some decisions are local to an instruction in the loop, such as whether to widen
it into a vector instruction or replicate it, keeping the generated instructions
in place. Other decisions, however, involve moving instructions, replacing them
with other instructions, and/or introducing new instructions. For example, a
cast may sink past a later instruction and be widened to handle first-order
recurrence; an interleave group of strided gathers or scatters may effectively
move to one place where they are replaced with shuffles and a common wide vector
load or store; new instructions may be introduced to compute masks, shuffle the
elements of vectors, and pack scalar values into vectors or vice-versa.
In order for VPlan to support making instruction-level decisions and analyses,
it needs to model the relevant instructions along with their def/use relations.
This too follows a staged approach: first, the new instructions that compute
masks are modeled as VPInstructions, along with their induced def/use subgraph.
This effectively models masks in VPlan, facilitating VPlan-based predication.
Next, the logic embedded within each Recipe for generating its instructions at
VPlan execution time, will instead take part in the planning process by modeling
them as VPInstructions. Finally, only logic that applies to instructions as a
group will remain in Recipes, such as interleave groups and potentially other
idiom groups having synergistic cost.
Related LLVM components
-----------------------
1. SLP Vectorizer: one can compare the VPlan model with LLVM's existing SLP
@ -152,6 +211,9 @@ Related LLVM components
2. RegionInfo: one can compare VPlan's H-CFG with the Region Analysis as used by
Polly [7]_.
3. Loop Vectorizer: the Vectorization Plan aims to upgrade the infrastructure of
the Loop Vectorizer and extend it to handle outer loops [8,9]_.
References
----------
.. [1] "Outer-loop vectorization: revisited for short SIMD architectures", Dorit
@ -180,3 +242,6 @@ References
.. [8] "Introducing VPlan to the Loop Vectorizer", Gil Rapaport and Ayal Zaks,
European LLVM Developers' Meeting 2017.
.. [9] "Extending LoopVectorizer: OpenMP4.5 SIMD and Outer Loop
Auto-Vectorization", Intel Vectorizer Team, LLVM Developers' Meeting 2016.

View File

@ -1,10 +1,15 @@
========================
LLVM 5.0.0 Release Notes
LLVM 6.0.0 Release Notes
========================
.. contents::
:local:
.. warning::
These are in-progress notes for the upcoming LLVM 6 release.
Release notes for previous releases can be found on
`the Download Page <http://releases.llvm.org/download.html>`_.
Introduction
============
@ -21,244 +26,97 @@ have questions or comments, the `LLVM Developer's Mailing List
<http://lists.llvm.org/mailman/listinfo/llvm-dev>`_ 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
=================================================
.. 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
point (e.g. maybe you would like to give an example of the
functionality, or simply have a lot to talk about), see the `NOTE` below
for adding a new subsection.
* LLVM's ``WeakVH`` has been renamed to ``WeakTrackingVH`` and a new ``WeakVH``
has been introduced. The new ``WeakVH`` nulls itself out on deletion, but
does not track values across RAUW.
* The ``Redirects`` argument of ``llvm::sys::ExecuteAndWait`` and
``llvm::sys::ExecuteNoWait`` was changed to an ``ArrayRef`` of optional
``StringRef``'s to make it safer and more convenient to use.
* A new library named ``BinaryFormat`` has been created which holds a collection
of code which previously lived in ``Support``. This includes the
``file_magic`` structure and ``identify_magic`` functions, as well as all the
structure and type definitions for DWARF, ELF, COFF, WASM, and MachO file
formats.
* The backend name was added to the Target Registry to allow run-time
information to be fed back into TableGen. Out-of-tree targets will need to add
the name used in the `def X : Target` definition to the call to
`RegisterTarget`.
* The tool ``llvm-pdbdump`` has been renamed ``llvm-pdbutil`` to better reflect
its nature as a general purpose PDB manipulation / diagnostics tool that does
more than just dumping contents.
* The ``Debugify`` pass was added to ``opt`` to facilitate testing of debug
info preservation. This pass attaches synthetic ``DILocations`` and
``DIVariables`` to the instructions in a ``Module``. The ``CheckDebugify``
pass determines how much of the metadata is lost.
* The ``BBVectorize`` pass has been removed. It was fully replaced and no
longer used back in 2014 but we didn't get around to removing it. Now it is
gone. The SLP vectorizer is the suggested non-loop vectorization pass.
* Note..
* A new tool opt-viewer.py has been added to visualize optimization remarks in
HTML. The tool processes the YAML files produced by clang with the
-fsave-optimization-record option.
.. NOTE
If you would like to document a larger change, then you can add a
subsection about it right here. You can copy the following boilerplate
and un-indent it (the indentation causes it to be inside this comment).
* A new CMake macro ``LLVM_REVERSE_ITERATION`` has been added. If enabled, all
supported unordered LLVM containers would be iterated in reverse order. This
is useful for uncovering non-determinism caused by iteration of unordered
containers. Currently, it supports reverse iteration of SmallPtrSet and
DenseMap.
* A new tool ``llvm-dlltool`` has been added to create short import libraries
from GNU style definition files. The tool utilizes the PE COFF SPEC Import
Library Format and PE COFF Auxiliary Weak Externals Format to achieve
compatibility with LLD and MSVC LINK.
Special New Feature
-------------------
Makes programs 10x faster by doing Special New Thing.
Changes to the LLVM IR
----------------------
* The datalayout string may now indicate an address space to use for
the pointer type of ``alloca`` rather than the default of 0.
* Added ``speculatable`` attribute indicating a function which has no
side-effects which could inhibit hoisting of calls.
Changes to the Arm Targets
Changes to the ARM Backend
--------------------------
During this release the AArch64 target has:
During this release ...
* A much improved Global ISel at O0.
* Support for ARMv8.1 8.2 and 8.3 instructions.
* New scheduler information for ThunderX2.
* Some SVE type changes but not much more than that.
* Made instruction fusion more aggressive, resulting in speedups
for code making use of AArch64 AES instructions. AES fusion has been
enabled for most Cortex-A cores and the AArch64MacroFusion pass was moved
to the generic MacroFusion pass.
* Added preferred function alignments for most Cortex-A cores.
* OpenMP "offload-to-self" base support.
During this release the ARM target has:
* Improved, but still mostly broken, Global ISel.
* Scheduling models update, new schedule for Cortex-A57.
* Hardware breakpoint support in LLDB.
* New assembler error handling, with spelling corrections and multiple
suggestions on how to fix problems.
* Improved mixed ARM/Thumb code generation. Some cases in which wrong
relocations were emitted have been fixed.
* Added initial support for mixed ARM/Thumb link-time optimization, using the
thumb-mode target feature.
Changes to the MIPS Target
--------------------------
* The microMIPS64R6 backend is deprecated and will be removed in the next
release.
* The MIPS backend now directly supports vector types for arguments and return
values (previously this required ABI specific LLVM IR).
* Added documentation for how the MIPS backend handles address lowering.
* Added a GCC compatible option -m(no-)madd4 to control the generation of four
operand multiply addition/subtraction instructions.
* Added basic support for the XRay instrumentation system.
* Added support for more assembly aliases and macros.
* Added support for the ``micromips`` and ``nomicromips`` function attributes
which control micromips code generation on a per function basis.
* Added the ``long-calls`` feature for non-pic environments. This feature is
used where the callee is out of range of the caller using a standard call
sequence. It must be enabled specifically.
* Added support for performing microMIPS code generation via function
attributes.
* Added experimental support for the static relocation model for the N64 ABI.
* Added partial support for the MT ASE.
* Added basic support for code size reduction for microMIPS.
* Fixed numerous bugs including: multi-precision arithmetic support, various
vectorization bugs, debug information for thread local variables, debug
sections lacking the correct flags, crashing when disassembling sections
whose size is not a multiple of two or four.
During this release ...
Changes to the PowerPC Target
-----------------------------
* Additional support and exploitation of POWER ISA 3.0: vabsdub, vabsduh,
vabsduw, modsw, moduw, modsd, modud, lxv, stxv, vextublx, vextubrx, vextuhlx,
vextuhrx, vextuwlx, vextuwrx, vextsb2w, vextsb2d, vextsh2w, vextsh2d, and
vextsw2d
* Implemented Optimal Code Sequences from The PowerPC Compiler Writer's Guide.
* Enable -fomit-frame-pointer by default.
* Improved handling of bit reverse intrinsic.
* Improved handling of memcpy and memcmp functions.
* Improved handling of branches with static branch hints.
* Improved codegen for atomic load_acquire.
* Improved block placement during code layout
* Many improvements to instruction selection and code generation
During this release ...
Changes to the X86 Target
-------------------------
* Added initial AMD Ryzen (znver1) scheduler support.
* Added support for Intel Goldmont CPUs.
* Add support for avx512vpopcntdq instructions.
* Added heuristics to convert CMOV into branches when it may be profitable.
* More aggressive inlining of memcmp calls.
* Improve vXi64 shuffles on 32-bit targets.
* Improved use of PMOVMSKB for any_of/all_of comparision reductions.
* Improved Silvermont, Sandybridge, and Jaguar (btver2) schedulers.
* Improved support for AVX512 vector rotations.
* Added support for AMD Lightweight Profiling (LWP) instructions.
* Avoid using slow LEA instructions.
* Use alternative sequences for multiply by constant.
* Improved lowering of strided shuffles.
* Improved the AVX512 cost model used by the vectorizer.
* Fix scalar code performance when AVX512 is enabled by making i1's illegal.
* Fixed many inline assembly bugs.
* Preliminary support for tracing NetBSD processes and core files with a single
thread in LLDB.
During this release ...
Changes to the AMDGPU Target
-----------------------------
* Initial gfx9 support
During this release ...
Changes to the AVR Target
-----------------------------
This release consists mainly of bugfixes and implementations of features
required for compiling basic Rust programs.
During this release ...
* Enable the branch relaxation pass so that we don't crash on large
stack load/stores
Changes to the OCaml bindings
-----------------------------
* Add support for lowering bit-rotations to the native ``ror`` and ``rol``
instructions
* Fix bug where function pointers were treated as pointers to RAM and not
pointers to program memory
* Fix broken code generation for shift-by-variable expressions
* Support zero-sized types in argument lists; this is impossible in C,
but possible in Rust
During this release ...
Changes to the C API
--------------------
* Deprecated the ``LLVMAddBBVectorizePass`` interface since the ``BBVectorize``
pass has been removed. It is now a no-op and will be removed in the next
release. Use ``LLVMAddSLPVectorizePass`` instead to get the supported SLP
vectorizer.
During this release ...
External Open Source Projects Using LLVM 5
External Open Source Projects Using LLVM 6
==========================================
Zig Programming Language
------------------------
`Zig <http://ziglang.org>`_ is an open-source programming language designed
for robustness, optimality, and clarity. It integrates closely with C and is
intended to eventually take the place of C. It uses LLVM to produce highly
optimized native code and to cross-compile for any target out of the box. Zig
is in alpha; with a beta release expected in September.
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 ARM
and PowerPC (32/64 bit). Ports to other architectures like AArch64 and MIPS64
are underway.
* A project...
Additional Information

View File

@ -126,14 +126,14 @@ For example, using the environment variable:
.. code::
SCUDO_OPTIONS="DeleteSizeMismatch=1:QuarantineSizeMb=16" ./a.out
SCUDO_OPTIONS="DeleteSizeMismatch=1:QuarantineSizeKb=64" ./a.out
Or using the function:
.. code::
.. code:: cpp
extern "C" const char *__scudo_default_options() {
return "DeleteSizeMismatch=1:QuarantineSizeMb=16";
return "DeleteSizeMismatch=1:QuarantineSizeKb=64";
}
@ -142,11 +142,14 @@ The following options are available:
+-----------------------------+----------------+----------------+------------------------------------------------+
| Option | 64-bit default | 32-bit default | Description |
+-----------------------------+----------------+----------------+------------------------------------------------+
| QuarantineSizeMb | 64 | 16 | The size (in Mb) of quarantine used to delay |
| QuarantineSizeKb | 256 | 64 | The size (in Kb) of quarantine used to delay |
| | | | the actual deallocation of chunks. Lower value |
| | | | may reduce memory usage but decrease the |
| | | | effectiveness of the mitigation; a negative |
| | | | value will fallback to a default of 64Mb. |
| | | | value will fallback to the defaults. |
+-----------------------------+----------------+----------------+------------------------------------------------+
| QuarantineChunksUpToSize | 2048 | 512 | Size (in bytes) up to which chunks can be |
| | | | quarantined. |
+-----------------------------+----------------+----------------+------------------------------------------------+
| ThreadLocalQuarantineSizeKb | 1024 | 256 | The size (in Kb) of per-thread cache use to |
| | | | offload the global quarantine. Lower value may |

View File

@ -171,7 +171,48 @@ Debugger intrinsic functions
----------------------------
LLVM uses several intrinsic functions (name prefixed with "``llvm.dbg``") to
provide debug information at various points in generated code.
track source local variables through optimization and code generation.
``llvm.dbg.addr``
^^^^^^^^^^^^^^^^^^^^
.. code-block:: llvm
void @llvm.dbg.addr(metadata, metadata, metadata)
This intrinsic provides information about a local element (e.g., variable).
The first argument is metadata holding the address of variable, typically a
static alloca in the function entry block. The second argument is a
`local variable <LangRef.html#dilocalvariable>`_ containing a description of
the variable. The third argument is a `complex expression
<LangRef.html#diexpression>`_. An `llvm.dbg.addr` intrinsic describes the
*address* of a source variable.
.. code-block:: text
%i.addr = alloca i32, align 4
call void @llvm.dbg.addr(metadata i32* %i.addr, metadata !1,
metadata !DIExpression()), !dbg !2
!1 = !DILocalVariable(name: "i", ...) ; int i
!2 = !DILocation(...)
...
%buffer = alloca [256 x i8], align 8
; The address of i is buffer+64.
call void @llvm.dbg.addr(metadata [256 x i8]* %buffer, metadata !3,
metadata !DIExpression(DW_OP_plus, 64)), !dbg !4
!3 = !DILocalVariable(name: "i", ...) ; int i
!4 = !DILocation(...)
A frontend should generate exactly one call to ``llvm.dbg.addr`` at the point
of declaration of a source variable. Optimization passes that fully promote the
variable from memory to SSA values will replace this call with possibly
multiple calls to `llvm.dbg.value`. Passes that delete stores are effectively
partial promotion, and they will insert a mix of calls to ``llvm.dbg.value``
and ``llvm.dbg.addr`` to track the source variable value when it is available.
After optimization, there may be multiple calls to ``llvm.dbg.addr`` describing
the program points where the variables lives in memory. All calls for the same
concrete source variable must agree on the memory location.
``llvm.dbg.declare``
^^^^^^^^^^^^^^^^^^^^
@ -180,26 +221,14 @@ provide debug information at various points in generated code.
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 a `local variable <LangRef.html#dilocalvariable>`_ containing a
description of the variable. The third argument is a `complex expression
<LangRef.html#diexpression>`_. An `llvm.dbg.declare` instrinsic describes the
*location* of a source variable.
.. code-block:: llvm
%i.addr = alloca i32, align 4
call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !1, metadata !2), !dbg !3
!1 = !DILocalVariable(name: "i", ...) ; int i
!2 = !DIExpression()
!3 = !DILocation(...)
...
%buffer = alloca [256 x i8], align 8
; The address of i is buffer+64.
call void @llvm.dbg.declare(metadata [256 x i8]* %buffer, metadata !1, metadata !2)
!1 = !DILocalVariable(name: "i", ...) ; int i
!2 = !DIExpression(DW_OP_plus, 64)
This intrinsic is identical to `llvm.dbg.addr`, except that there can only be
one call to `llvm.dbg.declare` for a given concrete `local variable
<LangRef.html#dilocalvariable>`_. It is not control-dependent, meaning that if
a call to `llvm.dbg.declare` exists and has a valid location argument, that
address is considered to be the true home of the variable across its entire
lifetime. This makes it hard for optimizations to preserve accurate debug info
in the presence of ``llvm.dbg.declare``, so we are transitioning away from it,
and we plan to deprecate it in future LLVM releases.
``llvm.dbg.value``
@ -207,14 +236,13 @@ description of the variable. The third argument is a `complex expression
.. code-block:: llvm
void @llvm.dbg.value(metadata, i64, metadata, metadata)
void @llvm.dbg.value(metadata, 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 a `local variable
<LangRef.html#dilocalvariable>`_ containing a description of the variable. The
fourth argument is a `complex expression <LangRef.html#diexpression>`_.
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
============================
@ -243,6 +271,9 @@ following C fragment, for example:
8. X = Y;
9. }
.. FIXME: Update the following example to use llvm.dbg.addr once that is the
default in clang.
Compiled to LLVM, this function would be represented like this:
.. code-block:: text

View File

@ -172,7 +172,7 @@ 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:: text
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
@ -273,7 +273,7 @@ afterwards.
If we extend our previous example to include a pointless derived pointer,
we get:
.. code-block:: text
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
@ -319,7 +319,7 @@ 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:: text
.. code-block:: llvm
@flag = thread_local global i32 0, align 4
@ -702,7 +702,7 @@ whitelist or use one of the predefined ones.
As an example, given this code:
.. code-block:: text
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
@ -712,7 +712,7 @@ As an example, given this code:
The pass would produce this IR:
.. code-block:: text
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
@ -789,7 +789,7 @@ As an example, given input IR of the following:
This pass would produce the following IR:
.. code-block:: text
.. code-block:: llvm
define void @test() gc "statepoint-example" {
call void @do_safepoint()

View File

@ -128,7 +128,7 @@ address points of the vtables of A, B and D respectively). If we then load
an address from that pointer, we know that the address can only be one of
``&A::f``, ``&B::f`` or ``&D::f``.
.. _address point: https://mentorembedded.github.io/cxx-abi/abi.html#vtable-general
.. _address point: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
Testing Addresses For Type Membership
=====================================
@ -223,4 +223,4 @@ efficiently to minimize the sizes of the underlying bitsets.
ret void
}
.. _GlobalLayoutBuilder: http://llvm.org/klaus/llvm/blob/master/include/llvm/Transforms/IPO/LowerTypeTests.h
.. _GlobalLayoutBuilder: http://git.llvm.org/klaus/llvm/blob/master/include/llvm/Transforms/IPO/LowerTypeTests.h

View File

@ -1008,10 +1008,50 @@ Instruction Scheduling
----------------------
Instruction itineraries can be queried using MCDesc::getSchedClass(). The
value can be named by an enumemation in llvm::XXX::Sched namespace generated
value can be named by an enumeration in llvm::XXX::Sched namespace generated
by TableGen in XXXGenInstrInfo.inc. The name of the schedule classes are
the same as provided in XXXSchedule.td plus a default NoItinerary class.
The schedule models are generated by TableGen by the SubtargetEmitter,
using the ``CodeGenSchedModels`` class. This is distinct from the itinerary
method of specifying machine resource use. The tool ``utils/schedcover.py``
can be used to determine which instructions have been covered by the
schedule model description and which haven't. The first step is to use the
instructions below to create an output file. Then run ``schedcover.py`` on the
output file:
.. code-block:: shell
$ <src>/utils/schedcover.py <build>/lib/Target/AArch64/tblGenSubtarget.with
instruction, default, CortexA53Model, CortexA57Model, CycloneModel, ExynosM1Model, FalkorModel, KryoModel, ThunderX2T99Model, ThunderXT8XModel
ABSv16i8, WriteV, , , CyWriteV3, M1WriteNMISC1, FalkorWr_2VXVY_2cyc, KryoWrite_2cyc_XY_XY_150ln, ,
ABSv1i64, WriteV, , , CyWriteV3, M1WriteNMISC1, FalkorWr_1VXVY_2cyc, KryoWrite_2cyc_XY_noRSV_67ln, ,
...
To capture the debug output from generating a schedule model, change to the
appropriate target directory and use the following command:
command with the ``subtarget-emitter`` debug option:
.. code-block:: shell
$ <build>/bin/llvm-tblgen -debug-only=subtarget-emitter -gen-subtarget \
-I <src>/lib/Target/<target> -I <src>/include \
-I <src>/lib/Target <src>/lib/Target/<target>/<target>.td \
-o <build>/lib/Target/<target>/<target>GenSubtargetInfo.inc.tmp \
> tblGenSubtarget.dbg 2>&1
Where ``<build>`` is the build directory, ``src`` is the source directory,
and ``<target>`` is the name of the target.
To double check that the above command is what is needed, one can capture the
exact TableGen command from a build by using:
.. code-block:: shell
$ VERBOSE=1 make ...
and search for ``llvm-tblgen`` commands in the output.
Instruction Relation Mapping
----------------------------

View File

@ -1032,7 +1032,7 @@ implementation for the interface.
Pass Statistics
===============
The `Statistic <http://llvm.org/doxygen/Statistic_8h-source.html>`_ class is
The `Statistic <http://llvm.org/doxygen/Statistic_8h_source.html>`_ class is
designed to be an easy way to expose various success metrics from passes.
These statistics are printed at the end of a run, when the :option:`-stats`
command line option is enabled on the command line. See the :ref:`Statistics
@ -1043,7 +1043,7 @@ section <Statistic>` in the Programmer's Manual for details.
What PassManager does
---------------------
The `PassManager <http://llvm.org/doxygen/PassManager_8h-source.html>`_ `class
The `PassManager <http://llvm.org/doxygen/PassManager_8h_source.html>`_ `class
<http://llvm.org/doxygen/classllvm_1_1PassManager.html>`_ takes a list of
passes, ensures their :ref:`prerequisites <writing-an-llvm-pass-interaction>`
are set up correctly, and then schedules passes to run efficiently. All of the

View File

@ -75,11 +75,11 @@ GCC-style attributes or C++11-style attributes.
.. code-block:: c++
[[clang::xray_always_intrument]] void always_instrumented();
[[clang::xray_always_instrument]] void always_instrumented();
[[clang::xray_never_instrument]] void never_instrumented();
void alt_always_instrumented() __attribute__((xray_always_intrument));
void alt_always_instrumented() __attribute__((xray_always_instrument));
void alt_never_instrumented() __attribute__((xray_never_instrument));
@ -143,17 +143,30 @@ variable, where we list down the options and their defaults below.
| | | | instrumentation points |
| | | | before main. |
+-------------------+-----------------+---------------+------------------------+
| xray_naive_log | ``bool`` | ``true`` | Whether to install |
| | | | the naive log |
| | | | implementation. |
| xray_mode | ``const char*`` | ``""`` | Default mode to |
| | | | install and initialize |
| | | | before ``main``. |
+-------------------+-----------------+---------------+------------------------+
| xray_logfile_base | ``const char*`` | ``xray-log.`` | Filename base for the |
| | | | XRay logfile. |
+-------------------+-----------------+---------------+------------------------+
| xray_fdr_log | ``bool`` | ``false`` | Whether to install the |
| | | | Flight Data Recorder |
| xray_naive_log | ``bool`` | ``false`` | **DEPRECATED:** Use |
| | | | xray_mode=xray-basic |
| | | | instead. Whether to |
| | | | install the basic log |
| | | | the naive log |
| | | | implementation. |
+-------------------+-----------------+---------------+------------------------+
| xray_fdr_log | ``bool`` | ``false`` | **DEPRECATED:** Use |
| | | | xray_mode=xray-fdr |
| | | | instead. Whether to |
| | | | install the Flight |
| | | | Data Recorder |
| | | | (FDR) mode. |
+-------------------+-----------------+---------------+------------------------+
| verbosity | ``int`` | ``0`` | Runtime verbosity |
| | | | level. |
+-------------------+-----------------+---------------+------------------------+
If you choose to not use the default logging implementation that comes with the
@ -196,6 +209,9 @@ on your application, you may set the ``xray_fdr_log`` option to ``true`` in the
``XRAY_OPTIONS`` environment variable (while also optionally setting the
``xray_naive_log`` to ``false``).
When the buffers are flushed to disk, the result is a binary trace format
described by `XRay FDR format <XRayFDRFormat.html>`_
When FDR mode is on, it will keep writing and recycling memory buffers until
the logging implementation is finalized -- at which point it can be flushed and
re-initialised later. To do this programmatically, we follow the workflow
@ -238,6 +254,14 @@ following API:
- ``__xray_set_log_impl(...)``: This function takes a struct of type
``XRayLogImpl``, which is defined in ``xray/xray_log_interface.h``, part of
the XRay compiler-rt installation.
- ``__xray_log_register_mode(...)``: Register a logging implementation against
a string Mode. The implementation is an instance of ``XRayLogImpl`` defined
in ``xray/xray_log_interface.h``.
- ``__xray_log_select_mode(...)``: Select the mode to install, associated with
a string Mode. Only implementations registered with
``__xray_log_register_mode(...)`` can be chosen with this function. When
successful, has the same effects as calling ``__xray_set_log_impl(...)`` with
the registered logging implementation.
- ``__xray_log_init(...)``: This function allows for initializing and
re-initializing an installed logging implementation. See
``xray/xray_log_interface.h`` for details, part of the XRay compiler-rt
@ -255,10 +279,15 @@ supports the following subcommands:
- ``account``: Performs basic function call accounting statistics with various
options for sorting, and output formats (supports CSV, YAML, and
console-friendly TEXT).
- ``convert``: Converts an XRay log file from one format to another. Currently
only converts to YAML.
- ``convert``: Converts an XRay log file from one format to another. We can
convert from binary XRay traces (both naive and FDR mode) to YAML,
`flame-graph <https://github.com/brendangregg/FlameGraph>`_ friendly text
formats, as well as `Chrome Trace Viewer (catapult)
<https://github.com/catapult-project/catapult>` formats.
- ``graph``: Generates a DOT graph of the function call relationships between
functions found in an XRay trace.
- ``stack``: Reconstructs function call stacks from a timeline of function
calls in an XRay trace.
These subcommands use various library components found as part of the XRay
libraries, distributed with the LLVM distribution. These are:
@ -271,7 +300,7 @@ libraries, distributed with the LLVM distribution. These are:
associated with edges and vertices.
- ``llvm/XRay/InstrumentationMap.h``: A convenient tool for analyzing the
instrumentation map in XRay-instrumented object files and binaries. The
``extract`` subcommand uses this particular library.
``extract`` and ``stack`` subcommands uses this particular library.
Future Work
===========
@ -279,13 +308,17 @@ Future Work
There are a number of ongoing efforts for expanding the toolset building around
the XRay instrumentation system.
Trace Analysis
--------------
Trace Analysis Tools
--------------------
We have more subcommands and modes that we're thinking of developing, in the
following forms:
- ``stack``: Reconstruct the function call stacks in a timeline.
- Work is in progress to integrate with or develop tools to visualize findings
from an XRay trace. Particularly, the ``stack`` tool is being expanded to
output formats that allow graphing and exploring the duration of time in each
call stack.
- With a large instrumented binary, the size of generated XRay traces can
quickly become unwieldy. We are working on integrating pruning techniques and
heuristics for the analysis tools to sift through the traces and surface only
relevant information.
More Platforms
--------------

View File

@ -60,7 +60,7 @@ to enable XRay at application start. To do this, XRay checks the
$ ./bin/llc input.ll
# We need to set the XRAY_OPTIONS to enable some features.
$ XRAY_OPTIONS="patch_premain=true" ./bin/llc input.ll
$ XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1" ./bin/llc input.ll
==69819==XRay: Log file in 'xray-log.llc.m35qPB'
At this point we now have an XRay trace we can start analysing.
@ -100,7 +100,7 @@ this data in a spreadsheet, we can output the results as CSV using the
If we want to get a textual representation of the raw trace we can use the
``llvm-xray convert`` tool to get YAML output. The first few lines of that
ouput for an example trace would look like the following:
output for an example trace would look like the following:
::
@ -195,6 +195,70 @@ Given the above two files we can re-build by providing those two files as
arguments to clang as ``-fxray-always-instrument=always-instrument.txt`` or
``-fxray-never-instrument=never-instrument.txt``.
The XRay stack tool
-------------------
Given a trace, and optionally an instrumentation map, the ``llvm-xray stack``
command can be used to analyze a call stack graph constructed from the function
call timeline.
The simplest way to use the command is simply to output the top stacks by call
count and time spent.
::
$ llvm-xray stack xray-log.llc.5rqxkU -instr_map ./bin/llc
Unique Stacks: 3069
Top 10 Stacks by leaf sum:
Sum: 9633790
lvl function count sum
#0 main 1 58421550
#1 compileModule(char**, llvm::LLVMContext&) 1 51440360
#2 llvm::legacy::PassManagerImpl::run(llvm::Module&) 1 40535375
#3 llvm::FPPassManager::runOnModule(llvm::Module&) 2 39337525
#4 llvm::FPPassManager::runOnFunction(llvm::Function&) 6 39331465
#5 llvm::PMDataManager::verifyPreservedAnalysis(llvm::Pass*) 399 16628590
#6 llvm::PMTopLevelManager::findAnalysisPass(void const*) 4584 15155600
#7 llvm::PMDataManager::findAnalysisPass(void const*, bool) 32088 9633790
..etc..
In the default mode, identical stacks on different threads are independently
aggregated. In a multithreaded program, you may end up having identical call
stacks fill your list of top calls.
To address this, you may specify the ``-aggregate-threads`` or
``-per-thread-stacks`` flags. ``-per-thread-stacks`` treats the thread id as an
implicit root in each call stack tree, while ``-aggregate-threads`` combines
identical stacks from all threads.
Flame Graph Generation
----------------------
The ``llvm-xray stack`` tool may also be used to generate flamegraphs for
visualizing your instrumented invocations. The tool does not generate the graphs
themselves, but instead generates a format that can be used with Brendan Gregg's
FlameGraph tool, currently available on `github
<https://github.com/brendangregg/FlameGraph>`_.
To generate output for a flamegraph, a few more options are necessary.
- ``-all-stacks`` - Emits all of the stacks instead of just the top stacks.
- ``-stack-format`` - Choose the flamegraph output format 'flame'.
- ``-aggregation-type`` - Choose the metric to graph.
You may pipe the command output directly to the flamegraph tool to obtain an
svg file.
::
$llvm-xray stack xray-log.llc.5rqxkU -instr_map ./bin/llc -stack-format=flame -aggregation-type=time -all-stacks | \
/path/to/FlameGraph/flamegraph.pl > flamegraph.svg
If you open the svg in a browser, mouse events allow exploring the call stacks.
Further Exploration
-------------------
@ -211,11 +275,11 @@ application.
#include <iostream>
#include <thread>
[[clang::xray_always_intrument]] void f() {
[[clang::xray_always_instrument]] void f() {
std::cerr << '.';
}
[[clang::xray_always_intrument]] void g() {
[[clang::xray_always_instrument]] void g() {
for (int i = 0; i < 1 << 10; ++i) {
std::cerr << '-';
}

401
docs/XRayFDRFormat.rst Normal file
View File

@ -0,0 +1,401 @@
======================================
XRay Flight Data Recorder Trace Format
======================================
:Version: 1 as of 2017-07-20
.. contents::
:local:
Introduction
============
When gathering XRay traces in Flight Data Recorder mode, each thread of an
application will claim buffers to fill with trace data, which at some point
is finalized and flushed.
A goal of the profiler is to minimize overhead, so the flushed data directly
corresponds to the buffer.
This document describes the format of a trace file.
General
=======
Each trace file corresponds to a sequence of events in a particular thread.
The file has a header followed by a sequence of discriminated record types.
The endianness of byte fields matches the endianess of the platform which
produced the trace file.
Header Section
==============
A trace file begins with a 32 byte header.
+-------------------+-----------------+----------------------------------------+
| Field | Size (bytes) | Description |
+===================+=================+========================================+
| version | ``2`` | Anticipates versioned readers. This |
| | | document describes the format when |
| | | version == 1 |
+-------------------+-----------------+----------------------------------------+
| type | ``2`` | An enumeration encoding the type of |
| | | trace. Flight Data Recorder mode |
| | | traces have type == 1 |
+-------------------+-----------------+----------------------------------------+
| bitfield | ``4`` | Holds parameters that are not aligned |
| | | to bytes. Further described below. |
+-------------------+-----------------+----------------------------------------+
| cycle_frequency | ``8`` | The frequency in hertz of the CPU |
| | | oscillator used to measure duration of |
| | | events in ticks. |
+-------------------+-----------------+----------------------------------------+
| buffer_size | ``8`` | The size in bytes of the data portion |
| | | of the trace following the header. |
+-------------------+-----------------+----------------------------------------+
| reserved | ``8`` | Reserved for future use. |
+-------------------+-----------------+----------------------------------------+
The bitfield parameter of the file header is composed of the following fields.
+-------------------+----------------+-----------------------------------------+
| Field | Size (bits) | Description |
+===================+================+=========================================+
| constant_tsc | ``1`` | Whether the platform's timestamp |
| | | counter used to record ticks between |
| | | events ticks at a constant frequency |
| | | despite CPU frequency changes. |
| | | 0 == non-constant. 1 == constant. |
+-------------------+----------------+-----------------------------------------+
| nonstop_tsc | ``1`` | Whether the tsc continues to count |
| | | despite whether the CPU is in a low |
| | | power state. 0 == stop. 1 == non-stop. |
+-------------------+----------------+-----------------------------------------+
| reserved | ``30`` | Not meaningful. |
+-------------------+----------------+-----------------------------------------+
Data Section
============
Following the header in a trace is a data section with size matching the
buffer_size field in the header.
The data section is a stream of elements of different types.
There are a few categories of data in the sequence.
- ``Function Records``: Function Records contain the timing of entry into and
exit from function execution. Function Records have 8 bytes each.
- ``Metadata Records``: Metadata records serve many purposes. Mostly, they
capture information that may be too costly to record for each function, but
that is required to contextualize the fine-grained timings. They also are used
as markers for user-defined Event Data payloads. Metadata records have 16
bytes each.
- ``Event Data``: Free form data may be associated with events that are traced
by the binary and encode data defined by a handler function. Event data is
always preceded with a marker record which indicates how large it is.
- ``Function Arguments``: The arguments to some functions are included in the
trace. These are either pointer addresses or primitives that are read and
logged independently of their types in a high level language. To the tracer,
they are all simply numbers. Function Records that have attached arguments
will indicate their presence on the function entry record. We only support
logging contiguous function argument sequences starting with argument zero,
which will be the "this" pointer for member function invocations. For example,
we don't support logging the first and third argument.
A reader of the memory format must maintain a state machine. The format makes no
attempt to pad for alignment, and it is not seekable.
Function Records
----------------
Function Records have an 8 byte layout. This layout encodes information to
reconstruct a call stack of instrumented function and their durations.
+---------------+--------------+-----------------------------------------------+
| Field | Size (bits) | Description |
+===============+==============+===============================================+
| discriminant | ``1`` | Indicates whether a reader should read a |
| | | Function or Metadata record. Set to ``0`` for |
| | | Function records. |
+---------------+--------------+-----------------------------------------------+
| action | ``3`` | Specifies whether the function is being |
| | | entered, exited, or is a non-standard entry |
| | | or exit produced by optimizations. |
+---------------+--------------+-----------------------------------------------+
| function_id | ``28`` | A numeric ID for the function. Resolved to a |
| | | name via the xray instrumentation map. The |
| | | instrumentation map is built by xray at |
| | | compile time into an object file and pairs |
| | | the function ids to addresses. It is used for |
| | | patching and as a lookup into the binary's |
| | | symbols to obtain names. |
+---------------+--------------+-----------------------------------------------+
| tsc_delta | ``32`` | The number of ticks of the timestamp counter |
| | | since a previous record recorded a delta or |
| | | other TSC resetting event. |
+---------------+--------------+-----------------------------------------------+
On little-endian machines, the bitfields are ordered from least significant bit
bit to most significant bit. A reader can read an 8 bit value and apply the mask
``0x01`` for the discriminant. Similarly, they can read 32 bits and unsigned
shift right by ``0x04`` to obtain the function_id field.
On big-endian machine, the bitfields are written in order from most significant
bit to least significant bit. A reader would read an 8 bit value and unsigned
shift right by 7 bits for the discriminant. The function_id field could be
obtained by reading a 32 bit value and applying the mask ``0x0FFFFFFF``.
Function action types are as follows.
+---------------+--------------+-----------------------------------------------+
| Type | Number | Description |
+===============+==============+===============================================+
| Entry | ``0`` | Typical function entry. |
+---------------+--------------+-----------------------------------------------+
| Exit | ``1`` | Typical function exit. |
+---------------+--------------+-----------------------------------------------+
| Tail_Exit | ``2`` | An exit from a function due to tail call |
| | | optimization. |
+---------------+--------------+-----------------------------------------------+
| Entry_Args | ``3`` | A function entry that records arguments. |
+---------------+--------------+-----------------------------------------------+
Entry_Args records do not contain the arguments themselves. Instead, metadata
records for each of the logged args follow the function record in the stream.
Metadata Records
----------------
Interspersed throughout the buffer are 16 byte Metadata records. For typically
instrumented binaries, they will be sparser than Function records, and they
provide a fuller picture of the binary execution state.
Metadata record layout is partially record dependent, but they share a common
structure.
The same bit field rules described for function records apply to the first byte
of MetadataRecords. Within this byte, little endian machines use lsb to msb
ordering and big endian machines use msb to lsb ordering.
+---------------+--------------+-----------------------------------------------+
| Field | Size | Description |
+===============+==============+===============================================+
| discriminant | ``1 bit`` | Indicates whether a reader should read a |
| | | Function or Metadata record. Set to ``1`` for |
| | | Metadata records. |
+---------------+--------------+-----------------------------------------------+
| record_kind | ``7 bits`` | The type of Metadata record. |
+---------------+--------------+-----------------------------------------------+
| data | ``15 bytes`` | A data field used differently for each record |
| | | type. |
+---------------+--------------+-----------------------------------------------+
Here is a table of the enumerated record kinds.
+--------+---------------------------+
| Number | Type |
+========+===========================+
| 0 | NewBuffer |
+--------+---------------------------+
| 1 | EndOfBuffer |
+--------+---------------------------+
| 2 | NewCPUId |
+--------+---------------------------+
| 3 | TSCWrap |
+--------+---------------------------+
| 4 | WallTimeMarker |
+--------+---------------------------+
| 5 | CustomEventMarker |
+--------+---------------------------+
| 6 | CallArgument |
+--------+---------------------------+
NewBuffer Records
-----------------
Each buffer begins with a NewBuffer record immediately after the header.
It records the thread ID of the thread that the trace belongs to.
Its data segment is as follows.
+---------------+--------------+-----------------------------------------------+
| Field | Size (bytes) | Description |
+===============+==============+===============================================+
| thread_Id | ``2`` | Thread ID for buffer. |
+---------------+--------------+-----------------------------------------------+
| reserved | ``13`` | Unused. |
+---------------+--------------+-----------------------------------------------+
WallClockTime Records
---------------------
Following the NewBuffer record, each buffer records an absolute time as a frame
of reference for the durations recorded by timestamp counter deltas.
Its data segment is as follows.
+---------------+--------------+-----------------------------------------------+
| Field | Size (bytes) | Description |
+===============+==============+===============================================+
| seconds | ``8`` | Seconds on absolute timescale. The starting |
| | | point is unspecified and depends on the |
| | | implementation and platform configured by the |
| | | tracer. |
+---------------+--------------+-----------------------------------------------+
| microseconds | ``4`` | The microsecond component of the time. |
+---------------+--------------+-----------------------------------------------+
| reserved | ``3`` | Unused. |
+---------------+--------------+-----------------------------------------------+
NewCpuId Records
----------------
Each function entry invokes a routine to determine what CPU is executing.
Typically, this is done with readtscp, which reads the timestamp counter at the
same time.
If the tracing detects that the execution has switched CPUs or if this is the
first instrumented entry point, the tracer will output a NewCpuId record.
Its data segment is as follows.
+---------------+--------------+-----------------------------------------------+
| Field | Size (bytes) | Description |
+===============+==============+===============================================+
| cpu_id | ``2`` | CPU Id. |
+---------------+--------------+-----------------------------------------------+
| absolute_tsc | ``8`` | The absolute value of the timestamp counter. |
+---------------+--------------+-----------------------------------------------+
| reserved | ``5`` | Unused. |
+---------------+--------------+-----------------------------------------------+
TSCWrap Records
---------------
Since each function record uses a 32 bit value to represent the number of ticks
of the timestamp counter since the last reference, it is possible for this value
to overflow, particularly for sparsely instrumented binaries.
When this delta would not fit into a 32 bit representation, a reference absolute
timestamp counter record is written in the form of a TSCWrap record.
Its data segment is as follows.
+---------------+--------------+-----------------------------------------------+
| Field | Size (bytes) | Description |
+===============+==============+===============================================+
| absolute_tsc | ``8`` | Timestamp counter value. |
+---------------+--------------+-----------------------------------------------+
| reserved | ``7`` | Unused. |
+---------------+--------------+-----------------------------------------------+
CallArgument Records
--------------------
Immediately following an Entry_Args type function record, there may be one or
more CallArgument records that contain the traced function's parameter values.
The order of the CallArgument Record sequency corresponds one to one with the
order of the function parameters.
CallArgument data segment:
+---------------+--------------+-----------------------------------------------+
| Field | Size (bytes) | Description |
+===============+==============+===============================================+
| argument | ``8`` | Numeric argument (may be pointer address). |
+---------------+--------------+-----------------------------------------------+
| reserved | ``7`` | Unused. |
+---------------+--------------+-----------------------------------------------+
CustomEventMarker Records
-------------------------
XRay provides the feature of logging custom events. This may be leveraged to
record tracing info for RPCs or similarly trace data that is application
specific.
Custom Events themselves are an unstructured (application defined) segment of
memory with arbitrary size within the buffer. They are preceded by
CustomEventMarkers to indicate their presence and size.
CustomEventMarker data segment:
+---------------+--------------+-----------------------------------------------+
| Field | Size (bytes) | Description |
+===============+==============+===============================================+
| event_size | ``4`` | Size of preceded event. |
+---------------+--------------+-----------------------------------------------+
| absolute_tsc | ``8`` | A timestamp counter of the event. |
+---------------+--------------+-----------------------------------------------+
| reserved | ``3`` | Unused. |
+---------------+--------------+-----------------------------------------------+
EndOfBuffer Records
-------------------
An EndOfBuffer record type indicates that there is no more trace data in this
buffer. The reader is expected to seek past the remaining buffer_size expressed
before the start of buffer and look for either another header or EOF.
Format Grammar and Invariants
=============================
Not all sequences of Metadata records and Function records are valid data. A
sequence should be parsed as a state machine. The expectations for a valid
format can be expressed as a context free grammar.
This is an attempt to explain the format with statements in EBNF format.
- Format := Header ThreadBuffer* EOF
- ThreadBuffer := NewBuffer WallClockTime NewCPUId BodySequence* End
- BodySequence := NewCPUId | TSCWrap | Function | CustomEvent
- Function := (Function_Entry_Args CallArgument*) | Function_Other_Type
- CustomEvent := CustomEventMarker CustomEventUnstructuredMemory
- End := EndOfBuffer RemainingBufferSizeToSkip
Function Record Order
---------------------
There are a few clarifications that may help understand what is expected of
Function records.
- Functions with an Exit are expected to have a corresponding Entry or
Entry_Args function record precede them in the trace.
- Tail_Exit Function records record the Function ID of the function whose return
address the program counter will take. In other words, the final function that
would be popped off of the call stack if tail call optimization was not used.
- Not all functions marked for instrumentation are necessarily in the trace. The
tracer uses heuristics to preserve the trace for non-trivial functions.
- Not every entry must have a traced Exit or Tail Exit. The buffer may run out
of space or the program may request for the tracer to finalize toreturn the
buffer before an instrumented function exits.

View File

@ -466,7 +466,7 @@ looks like:
return StringRef();
}
// Determine if this scalar needs quotes.
static bool mustQuote(StringRef) { return true; }
static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
};
Block Scalars

View File

@ -48,9 +48,9 @@
# built documents.
#
# The short version.
version = '5'
version = '6'
# The full version, including alpha/beta/rc tags.
release = '5'
release = '6'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -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.
@ -63,6 +68,7 @@ representation.
CMakePrimer
AdvancedBuilds
HowToBuildOnARM
HowToCrossCompileBuiltinsOnArm
HowToCrossCompileLLVM
CommandGuide/index
GettingStarted
@ -100,6 +106,9 @@ representation.
:doc:`HowToBuildOnARM`
Notes on building and testing LLVM/Clang on ARM.
:doc:`HowToCrossCompileBuiltinsOnArm`
Notes on cross-building and testing the compiler-rt builtins for Arm.
:doc:`HowToCrossCompileLLVM`
Notes on cross-building and testing LLVM/Clang.
@ -154,7 +163,7 @@ representation.
misunderstood instruction.
:doc:`Frontend/PerformanceTips`
A collection of tips for frontend authors on how to generate IR
A collection of tips for frontend authors on how to generate IR
which LLVM is able to effectively optimize.
:doc:`Docker`
@ -178,6 +187,7 @@ For developers of applications which use LLVM as a library.
ProgrammersManual
Extensions
LibFuzzer
FuzzingLLVM
ScudoHardenedAllocator
OptBisect
@ -211,7 +221,6 @@ For developers of applications which use LLVM as a library.
`Doxygen generated documentation <http://llvm.org/doxygen/>`_
(`classes <http://llvm.org/doxygen/inherits.html>`_)
(`tarball <http://llvm.org/doxygen/doxygen.tar.gz>`_)
`Documentation for Go bindings <http://godoc.org/llvm.org/llvm/bindings/go/llvm>`_
@ -224,6 +233,9 @@ For developers of applications which use LLVM as a library.
:doc:`LibFuzzer`
A library for writing in-process guided fuzzers.
:doc:`FuzzingLLVM`
Information on writing and using Fuzzers to find bugs in LLVM.
:doc:`ScudoHardenedAllocator`
A library that implements a security-hardened `malloc()`.
@ -275,7 +287,9 @@ For API clients and LLVM developers.
GlobalISel
XRay
XRayExample
XRayFDRFormat
PDB/index
CFIVerify
:doc:`WritingAnLLVMPass`
Information on how to write LLVM transformations and analyses.
@ -406,6 +420,9 @@ For API clients and LLVM developers.
:doc:`The Microsoft PDB File Format <PDB/index>`
A detailed description of the Microsoft PDB (Program Database) file format.
:doc:`CFIVerify`
A description of the verification tool for Control Flow Integrity.
Development Process Documentation
=================================

View File

@ -75,8 +75,7 @@ will look like:
std::unique_ptr<Module> M = buildModule();
JIT J;
Handle H = J.addModule(*M);
int (*Main)(int, char*[]) =
(int(*)(int, char*[])J.findSymbol("main").getAddress();
int (*Main)(int, char*[]) = (int(*)(int, char*[]))J.getSymbolAddress("main");
int Result = Main();
J.removeModule(H);
@ -111,14 +110,24 @@ usual include guards and #includes [2]_, we get to the definition of our class:
#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
namespace llvm {
namespace orc {
@ -127,38 +136,39 @@ usual include guards and #includes [2]_, we get to the definition of our class:
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
ObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
public:
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandleT;
using ModuleHandle = decltype(CompileLayer)::ModuleHandleT;
Our class begins with four members: A TargetMachine, TM, which will be used
to build our LLVM compiler instance; A DataLayout, DL, which will be used for
Our class begins with four members: A TargetMachine, TM, which will be used to
build our LLVM compiler instance; A DataLayout, DL, which will be used for
symbol mangling (more on that later), and two ORC *layers*: an
ObjectLinkingLayer and a IRCompileLayer. We'll be talking more about layers in
the next chapter, but for now you can think of them as analogous to LLVM
RTDyldObjectLinkingLayer and a CompileLayer. We'll be talking more about layers
in the next chapter, but for now you can think of them as analogous to LLVM
Passes: they wrap up useful JIT utilities behind an easy to compose interface.
The first layer, ObjectLinkingLayer, is the foundation of our JIT: it takes
in-memory object files produced by a compiler and links them on the fly to make
them executable. This JIT-on-top-of-a-linker design was introduced in MCJIT,
however the linker was hidden inside the MCJIT class. In ORC we expose the
linker so that clients can access and configure it directly if they need to. In
this tutorial our ObjectLinkingLayer will just be used to support the next layer
in our stack: the IRCompileLayer, which will be responsible for taking LLVM IR,
compiling it, and passing the resulting in-memory object files down to the
object linking layer below.
The first layer, ObjectLayer, is the foundation of our JIT: it takes in-memory
object files produced by a compiler and links them on the fly to make them
executable. This JIT-on-top-of-a-linker design was introduced in MCJIT, however
the linker was hidden inside the MCJIT class. In ORC we expose the linker so
that clients can access and configure it directly if they need to. In this
tutorial our ObjectLayer will just be used to support the next layer in our
stack: the CompileLayer, which will be responsible for taking LLVM IR, compiling
it, and passing the resulting in-memory object files down to the object linking
layer below.
That's it for member variables, after that we have a single typedef:
ModuleHandleT. This is the handle type that will be returned from our JIT's
ModuleHandle. This is the handle type that will be returned from our JIT's
addModule method, and can be passed to the removeModule method to remove a
module. The IRCompileLayer class already provides a convenient handle type
(IRCompileLayer::ModuleSetHandleT), so we just alias our ModuleHandleT to this.
(IRCompileLayer::ModuleHandleT), so we just alias our ModuleHandle to this.
.. code-block:: c++
KaleidoscopeJIT()
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
}
@ -166,17 +176,22 @@ module. The IRCompileLayer class already provides a convenient handle type
TargetMachine &getTargetMachine() { return *TM; }
Next up we have our class constructor. We begin by initializing TM using the
EngineBuilder::selectTarget helper method, which constructs a TargetMachine for
the current process. Next we use our newly created TargetMachine to initialize
DL, our DataLayout. Then we initialize our IRCompileLayer. Our IRCompile layer
needs two things: (1) A reference to our object linking layer, and (2) a
compiler instance to use to perform the actual compilation from IR to object
files. We use the off-the-shelf SimpleCompiler instance for now. Finally, in
the body of the constructor, we call the DynamicLibrary::LoadLibraryPermanently
method with a nullptr argument. Normally the LoadLibraryPermanently method is
called with the path of a dynamic library to load, but when passed a null
pointer it will 'load' the host process itself, making its exported symbols
available for execution.
EngineBuilder::selectTarget helper method which constructs a TargetMachine for
the current process. Then we use our newly created TargetMachine to initialize
DL, our DataLayout. After that we need to initialize our ObjectLayer. The
ObjectLayer requires a function object that will build a JIT memory manager for
each module that is added (a JIT memory manager manages memory allocations,
memory permissions, and registration of exception handlers for JIT'd code). For
this we use a lambda that returns a SectionMemoryManager, an off-the-shelf
utility that provides all the basic memory management functionality required for
this chapter. Next we initialize our CompileLayer. The CompileLayer needs two
things: (1) A reference to our object layer, and (2) a compiler instance to use
to perform the actual compilation from IR to object files. We use the
off-the-shelf SimpleCompiler instance for now. Finally, in the body of the
constructor, we call the DynamicLibrary::LoadLibraryPermanently method with a
nullptr argument. Normally the LoadLibraryPermanently method is called with the
path of a dynamic library to load, but when passed a null pointer it will 'load'
the host process itself, making its exported symbols available for execution.
.. code-block:: c++
@ -191,48 +206,36 @@ available for execution.
return Sym;
return JITSymbol(nullptr);
},
[](const std::string &S) {
[](const std::string &Name) {
if (auto SymAddr =
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
return JITSymbol(nullptr);
});
// Build a singleton module set to hold our module.
std::vector<std::unique_ptr<Module>> Ms;
Ms.push_back(std::move(M));
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return CompileLayer.addModuleSet(std::move(Ms),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
return cantFail(CompileLayer.addModule(std::move(M),
std::move(Resolver)));
}
Now we come to the first of our JIT API methods: addModule. This method is
responsible for adding IR to the JIT and making it available for execution. In
this initial implementation of our JIT we will make our modules "available for
execution" by adding them straight to the IRCompileLayer, which will
immediately compile them. In later chapters we will teach our JIT to be lazier
and instead add the Modules to a "pending" list to be compiled if and when they
are first executed.
execution" by adding them straight to the CompileLayer, which will immediately
compile them. In later chapters we will teach our JIT to defer compilation
of individual functions until they're actually called.
To add our module to the IRCompileLayer we need to supply two auxiliary objects
(as well as the module itself): a memory manager and a symbol resolver. The
memory manager will be responsible for managing the memory allocated to JIT'd
machine code, setting memory permissions, and registering exception handling
tables (if the JIT'd code uses exceptions). For our memory manager we will use
the SectionMemoryManager class: another off-the-shelf utility that provides all
the basic functionality we need. The second auxiliary class, the symbol
resolver, is more interesting for us. It exists to tell the JIT where to look
when it encounters an *external symbol* in the module we are adding. External
To add our module to the CompileLayer we need to supply both the module and a
symbol resolver. The symbol resolver is responsible for supplying the JIT with
an address for each *external symbol* in the module we are adding. External
symbols are any symbol not defined within the module itself, including calls to
functions outside the JIT and calls to functions defined in other modules that
have already been added to the JIT. It may seem as though modules added to the
JIT should "know about one another" by default, but since we would still have to
have already been added to the JIT. (It may seem as though modules added to the
JIT should know about one another by default, but since we would still have to
supply a symbol resolver for references to code outside the JIT it turns out to
be easier to just re-use this one mechanism for all symbol resolution. This has
the added benefit that the user has full control over the symbol resolution
be easier to re-use this one mechanism for all symbol resolution.) This has the
added benefit that the user has full control over the symbol resolution
process. Should we search for definitions within the JIT first, then fall back
on external definitions? Or should we prefer external definitions where
available and only JIT code if we don't already have an available
@ -263,12 +266,13 @@ symbol definition via either of these paths, the JIT will refuse to accept our
module, returning a "symbol not found" error.
Now that we've built our symbol resolver, we're ready to add our module to the
JIT. We do this by calling the CompileLayer's addModuleSet method [4]_. Since
we only have a single Module and addModuleSet expects a collection, we will
create a vector of modules and add our module as the only member. Since we
have already typedef'd our ModuleHandleT type to be the same as the
CompileLayer's handle type, we can return the handle from addModuleSet
directly from our addModule method.
JIT. We do this by calling the CompileLayer's addModule method. The addModule
method returns an ``Expected<CompileLayer::ModuleHandle>``, since in more
advanced JIT configurations it could fail. In our basic configuration we know
that it will always succeed so we use the cantFail utility to assert that no
error occurred, and extract the handle value. Since we have already typedef'd
our ModuleHandle type to be the same as the CompileLayer's handle type, we can
return the unwrapped handle directly.
.. code-block:: c++
@ -279,19 +283,29 @@ directly from our addModule method.
return CompileLayer.findSymbol(MangledNameStream.str(), true);
}
JITTargetAddress getSymbolAddress(const std::string Name) {
return cantFail(findSymbol(Name).getAddress());
}
void removeModule(ModuleHandle H) {
CompileLayer.removeModuleSet(H);
cantFail(CompileLayer.removeModule(H));
}
Now that we can add code to our JIT, we need a way to find the symbols we've
added to it. To do that we call the findSymbol method on our IRCompileLayer,
but with a twist: We have to *mangle* the name of the symbol we're searching
for first. The reason for this is that the ORC JIT components use mangled
symbols internally the same way a static compiler and linker would, rather
than using plain IR symbol names. The kind of mangling will depend on the
DataLayout, which in turn depends on the target platform. To allow us to
remain portable and search based on the un-mangled name, we just re-produce
this mangling ourselves.
added to it. To do that we call the findSymbol method on our CompileLayer, but
with a twist: We have to *mangle* the name of the symbol we're searching for
first. The ORC JIT components use mangled symbols internally the same way a
static compiler and linker would, rather than using plain IR symbol names. This
allows JIT'd code to interoperate easily with precompiled code in the
application or shared libraries. The kind of mangling will depend on the
DataLayout, which in turn depends on the target platform. To allow us to remain
portable and search based on the un-mangled name, we just re-produce this
mangling ourselves.
Next we have a convenience function, getSymbolAddress, which returns the address
of a given symbol. Like CompileLayer's addModule function, JITSymbol's getAddress
function is allowed to fail [4]_, however we know that it will not in our simple
example, so we wrap it in a call to cantFail.
We now come to the last method in our JIT API: removeModule. This method is
responsible for destructing the MemoryManager and SymbolResolver that were
@ -302,7 +316,10 @@ treated as a duplicate definition when the next top-level expression is
entered. It is generally good to free any module that you know you won't need
to call further, just to free up the resources dedicated to it. However, you
don't strictly need to do this: All resources will be cleaned up when your
JIT class is destructed, if they haven't been freed before then.
JIT class is destructed, if they haven't been freed before then. Like
``CompileLayer::addModule`` and ``JITSymbol::getAddress``, removeModule may
fail in general but will never fail in our example, so we wrap it in a call to
cantFail.
This brings us to the end of Chapter 1 of Building a JIT. You now have a basic
but fully functioning JIT stack that you can use to take LLVM IR and make it
@ -321,7 +338,7 @@ example, use:
.. code-block:: bash
# Compile
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orc native` -O3 -o toy
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o toy
# Run
./toy
@ -337,36 +354,45 @@ Here is the code:
left as an exercise for the reader. (The KaleidoscopeJIT.h used in the
original tutorials will be a helpful reference).
.. [2] +-----------------------+-----------------------------------------------+
| File | Reason for inclusion |
+=======================+===============================================+
| ExecutionEngine.h | Access to the EngineBuilder::selectTarget |
| | method. |
+-----------------------+-----------------------------------------------+
| | Access to the |
| RTDyldMemoryManager.h | RTDyldMemoryManager::getSymbolAddressInProcess|
| | method. |
+-----------------------+-----------------------------------------------+
| CompileUtils.h | Provides the SimpleCompiler class. |
+-----------------------+-----------------------------------------------+
| IRCompileLayer.h | Provides the IRCompileLayer class. |
+-----------------------+-----------------------------------------------+
| | Access the createLambdaResolver function, |
| LambdaResolver.h | which provides easy construction of symbol |
| | resolvers. |
+-----------------------+-----------------------------------------------+
| ObjectLinkingLayer.h | Provides the ObjectLinkingLayer class. |
+-----------------------+-----------------------------------------------+
| Mangler.h | Provides the Mangler class for platform |
| | specific name-mangling. |
+-----------------------+-----------------------------------------------+
| DynamicLibrary.h | Provides the DynamicLibrary class, which |
| | makes symbols in the host process searchable. |
+-----------------------+-----------------------------------------------+
.. [2] +-----------------------------+-----------------------------------------------+
| File | Reason for inclusion |
+=============================+===============================================+
| STLExtras.h | LLVM utilities that are useful when working |
| | with the STL. |
+-----------------------------+-----------------------------------------------+
| ExecutionEngine.h | Access to the EngineBuilder::selectTarget |
| | method. |
+-----------------------------+-----------------------------------------------+
| | Access to the |
| RTDyldMemoryManager.h | RTDyldMemoryManager::getSymbolAddressInProcess|
| | method. |
+-----------------------------+-----------------------------------------------+
| CompileUtils.h | Provides the SimpleCompiler class. |
+-----------------------------+-----------------------------------------------+
| IRCompileLayer.h | Provides the IRCompileLayer class. |
+-----------------------------+-----------------------------------------------+
| | Access the createLambdaResolver function, |
| LambdaResolver.h | which provides easy construction of symbol |
| | resolvers. |
+-----------------------------+-----------------------------------------------+
| RTDyldObjectLinkingLayer.h | Provides the RTDyldObjectLinkingLayer class. |
+-----------------------------+-----------------------------------------------+
| Mangler.h | Provides the Mangler class for platform |
| | specific name-mangling. |
+-----------------------------+-----------------------------------------------+
| DynamicLibrary.h | Provides the DynamicLibrary class, which |
| | makes symbols in the host process searchable. |
+-----------------------------+-----------------------------------------------+
| | A fast output stream class. We use the |
| raw_ostream.h | raw_string_ostream subclass for symbol |
| | mangling |
+-----------------------------+-----------------------------------------------+
| TargetMachine.h | LLVM target machine description class. |
+-----------------------------+-----------------------------------------------+
.. [3] Actually they don't have to be lambdas, any object with a call operator
will do, including plain old functions or std::functions.
.. [4] ORC layers accept sets of Modules, rather than individual ones, so that
all Modules in the set could be co-located by the memory manager, though
this feature is not yet implemented.
.. [4] ``JITSymbol::getAddress`` will force the JIT to compile the definition of
the symbol if it hasn't already been compiled, and since the compilation
process could fail getAddress must be able to return this failure.

View File

@ -46,7 +46,7 @@ Chapter 1 and compose an ORC *IRTransformLayer* on top. We will look at how the
IRTransformLayer works in more detail below, but the interface is simple: the
constructor for this layer takes a reference to the layer below (as all layers
do) plus an *IR optimization function* that it will apply to each Module that
is added via addModuleSet:
is added via addModule:
.. code-block:: c++
@ -54,19 +54,20 @@ is added via addModuleSet:
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
ObjectLinkingLayer<> ObjectLayer;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
OptimizeFunction;
using OptimizeFunction =
std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>;
IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
public:
typedef decltype(OptimizeLayer)::ModuleSetHandleT ModuleHandle;
using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
KaleidoscopeJIT()
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
OptimizeLayer(CompileLayer,
[this](std::unique_ptr<Module> M) {
@ -101,9 +102,8 @@ define below.
.. code-block:: c++
// ...
return OptimizeLayer.addModuleSet(std::move(Ms),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
return cantFail(OptimizeLayer.addModule(std::move(M),
std::move(Resolver)));
// ...
.. code-block:: c++
@ -115,17 +115,17 @@ define below.
.. code-block:: c++
// ...
OptimizeLayer.removeModuleSet(H);
cantFail(OptimizeLayer.removeModule(H));
// ...
Next we need to replace references to 'CompileLayer' with references to
OptimizeLayer in our key methods: addModule, findSymbol, and removeModule. In
addModule we need to be careful to replace both references: the findSymbol call
inside our resolver, and the call through to addModuleSet.
inside our resolver, and the call through to addModule.
.. code-block:: c++
std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) {
// Create a function pass manager.
auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());
@ -166,37 +166,30 @@ implementations of the layer concept that can be devised:
template <typename BaseLayerT, typename TransformFtor>
class IRTransformLayer {
public:
typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT;
using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
IRTransformLayer(BaseLayerT &BaseLayer,
TransformFtor Transform = TransformFtor())
: BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
template <typename ModuleSetT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
for (auto I = Ms.begin(), E = Ms.end(); I != E; ++I)
*I = Transform(std::move(*I));
return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
std::move(Resolver));
Expected<ModuleHandleT>
addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
return BaseLayer.addModule(Transform(std::move(M)), std::move(Resolver));
}
void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(H); }
void removeModule(ModuleHandleT H) { BaseLayer.removeModule(H); }
JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
void emitAndFinalize(ModuleSetHandleT H) {
void emitAndFinalize(ModuleHandleT H) {
BaseLayer.emitAndFinalize(H);
}
@ -215,14 +208,14 @@ comments. It is a template class with two template arguments: ``BaesLayerT`` and
``TransformFtor`` that provide the type of the base layer and the type of the
"transform functor" (in our case a std::function) respectively. This class is
concerned with two very simple jobs: (1) Running every IR Module that is added
with addModuleSet through the transform functor, and (2) conforming to the ORC
with addModule through the transform functor, and (2) conforming to the ORC
layer interface. The interface consists of one typedef and five methods:
+------------------+-----------------------------------------------------------+
| Interface | Description |
+==================+===========================================================+
| | Provides a handle that can be used to identify a module |
| ModuleSetHandleT | set when calling findSymbolIn, removeModuleSet, or |
| ModuleHandleT | set when calling findSymbolIn, removeModule, or |
| | emitAndFinalize. |
+------------------+-----------------------------------------------------------+
| | Takes a given set of Modules and makes them "available |
@ -231,28 +224,28 @@ layer interface. The interface consists of one typedef and five methods:
| | the address of the symbols should be read/writable (for |
| | data symbols), or executable (for function symbols) after |
| | JITSymbol::getAddress() is called. Note: This means that |
| addModuleSet | addModuleSet doesn't have to compile (or do any other |
| addModule | addModule doesn't have to compile (or do any other |
| | work) up-front. It *can*, like IRCompileLayer, act |
| | eagerly, but it can also simply record the module and |
| | take no further action until somebody calls |
| | JITSymbol::getAddress(). In IRTransformLayer's case |
| | addModuleSet eagerly applies the transform functor to |
| | addModule eagerly applies the transform functor to |
| | each module in the set, then passes the resulting set |
| | of mutated modules down to the layer below. |
+------------------+-----------------------------------------------------------+
| | Removes a set of modules from the JIT. Code or data |
| removeModuleSet | defined in these modules will no longer be available, and |
| removeModule | defined in these modules will no longer be available, and |
| | the memory holding the JIT'd definitions will be freed. |
+------------------+-----------------------------------------------------------+
| | Searches for the named symbol in all modules that have |
| | previously been added via addModuleSet (and not yet |
| findSymbol | removed by a call to removeModuleSet). In |
| | previously been added via addModule (and not yet |
| findSymbol | removed by a call to removeModule). In |
| | IRTransformLayer we just pass the query on to the layer |
| | below. In our REPL this is our default way to search for |
| | function definitions. |
+------------------+-----------------------------------------------------------+
| | Searches for the named symbol in the module set indicated |
| | by the given ModuleSetHandleT. This is just an optimized |
| | by the given ModuleHandleT. This is just an optimized |
| | search, better for lookup-speed when you know exactly |
| | a symbol definition should be found. In IRTransformLayer |
| findSymbolIn | we just pass this query on to the layer below. In our |
@ -262,7 +255,7 @@ layer interface. The interface consists of one typedef and five methods:
| | we just added. |
+------------------+-----------------------------------------------------------+
| | Forces all of the actions required to make the code and |
| | data in a module set (represented by a ModuleSetHandleT) |
| | data in a module set (represented by a ModuleHandleT) |
| | accessible. Behaves as if some symbol in the set had been |
| | searched for and JITSymbol::getSymbolAddress called. This |
| emitAndFinalize | is rarely needed, but can be useful when dealing with |
@ -276,11 +269,11 @@ wrinkles like emitAndFinalize for performance), similar to the basic JIT API
operations we identified in Chapter 1. Conforming to the layer concept allows
classes to compose neatly by implementing their behaviors in terms of the these
same operations, carried out on the layer below. For example, an eager layer
(like IRTransformLayer) can implement addModuleSet by running each module in the
(like IRTransformLayer) can implement addModule by running each module in the
set through its transform up-front and immediately passing the result to the
layer below. A lazy layer, by contrast, could implement addModuleSet by
layer below. A lazy layer, by contrast, could implement addModule by
squirreling away the modules doing no other up-front work, but applying the
transform (and calling addModuleSet on the layer below) when the client calls
transform (and calling addModule on the layer below) when the client calls
findSymbol instead. The JIT'd program behavior will be the same either way, but
these choices will have different performance characteristics: Doing work
eagerly means the JIT takes longer up-front, but proceeds smoothly once this is
@ -319,7 +312,7 @@ IRTransformLayer added to enable optimization. To build this example, use:
.. code-block:: bash
# Compile
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orc native` -O3 -o toy
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o toy
# Run
./toy
@ -329,8 +322,8 @@ Here is the code:
:language: c++
.. [1] When we add our top-level expression to the JIT, any calls to functions
that we defined earlier will appear to the ObjectLinkingLayer as
external symbols. The ObjectLinkingLayer will call the SymbolResolver
that we defined in addModuleSet, which in turn calls findSymbol on the
that we defined earlier will appear to the RTDyldObjectLinkingLayer as
external symbols. The RTDyldObjectLinkingLayer will call the SymbolResolver
that we defined in addModule, which in turn calls findSymbol on the
OptimizeLayer, at which point even a lazy transform layer will have to
do its work.

View File

@ -21,7 +21,7 @@ Lazy Compilation
When we add a module to the KaleidoscopeJIT class from Chapter 2 it is
immediately optimized, compiled and linked for us by the IRTransformLayer,
IRCompileLayer and ObjectLinkingLayer respectively. This scheme, where all the
IRCompileLayer and RTDyldObjectLinkingLayer respectively. This scheme, where all the
work to make a Module executable is done up front, is simple to understand and
its performance characteristics are easy to reason about. However, it will lead
to very high startup times if the amount of code to be compiled is large, and
@ -33,7 +33,7 @@ the ORC APIs provide us with a layer to lazily compile LLVM IR:
*CompileOnDemandLayer*.
The CompileOnDemandLayer class conforms to the layer interface described in
Chapter 2, but its addModuleSet method behaves quite differently from the layers
Chapter 2, but its addModule method behaves quite differently from the layers
we have seen so far: rather than doing any work up front, it just scans the
Modules being added and arranges for each function in them to be compiled the
first time it is called. To do this, the CompileOnDemandLayer creates two small
@ -73,21 +73,22 @@ lazy compilation. We just need a few changes to the source:
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
std::unique_ptr<JITCompileCallbackManager> CompileCallbackManager;
ObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
OptimizeFunction;
using OptimizeFunction =
std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>;
IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
std::unique_ptr<JITCompileCallbackManager> CompileCallbackManager;
CompileOnDemandLayer<decltype(OptimizeLayer)> CODLayer;
public:
typedef decltype(CODLayer)::ModuleSetHandleT ModuleHandle;
using ModuleHandle = decltype(CODLayer)::ModuleHandleT;
First we need to include the CompileOnDemandLayer.h header, then add two new
members: a std::unique_ptr<CompileCallbackManager> and a CompileOnDemandLayer,
members: a std::unique_ptr<JITCompileCallbackManager> and a CompileOnDemandLayer,
to our class. The CompileCallbackManager member is used by the CompileOnDemandLayer
to create the compile callback needed for each function.
@ -95,9 +96,10 @@ to create the compile callback needed for each function.
KaleidoscopeJIT()
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
OptimizeLayer(CompileLayer,
[this](std::unique_ptr<Module> M) {
[this](std::shared_ptr<Module> M) {
return optimizeModule(std::move(M));
}),
CompileCallbackManager(
@ -133,7 +135,7 @@ our CompileCallbackManager. Finally, we need to supply an "indirect stubs
manager builder": a utility function that constructs IndirectStubManagers, which
are in turn used to build the stubs for the functions in each module. The
CompileOnDemandLayer will call the indirect stub manager builder once for each
call to addModuleSet, and use the resulting indirect stubs manager to create
call to addModule, and use the resulting indirect stubs manager to create
stubs for all functions in all modules in the set. If/when the module set is
removed from the JIT the indirect stubs manager will be deleted, freeing any
memory allocated to the stubs. We supply this function by using the
@ -144,9 +146,8 @@ createLocalIndirectStubsManagerBuilder utility.
// ...
if (auto Sym = CODLayer.findSymbol(Name, false))
// ...
return CODLayer.addModuleSet(std::move(Ms),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
return cantFail(CODLayer.addModule(std::move(Ms),
std::move(Resolver)));
// ...
// ...
@ -154,7 +155,7 @@ createLocalIndirectStubsManagerBuilder utility.
// ...
// ...
CODLayer.removeModuleSet(H);
CODLayer.removeModule(H);
// ...
Finally, we need to replace the references to OptimizeLayer in our addModule,
@ -173,7 +174,7 @@ layer added to enable lazy function-at-a-time compilation. To build this example
.. code-block:: bash
# Compile
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orc native` -O3 -o toy
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o toy
# Run
./toy

View File

@ -36,7 +36,7 @@ Kaleidoscope ASTS. To build this example, use:
.. code-block:: bash
# Compile
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orc native` -O3 -o toy
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o toy
# Run
./toy

View File

@ -40,8 +40,10 @@ Kaleidoscope ASTS. To build this example, use:
.. code-block:: bash
# Compile
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orc native` -O3 -o toy
clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o toy
clang++ -g Server/server.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o toy-server
# Run
./toy-server &
./toy
Here is the code for the modified KaleidoscopeJIT:

View File

@ -41,7 +41,7 @@
// Cases -1 and 7 are caught by a C++ test harness where the validity of
// of a C++ catch(...) clause catching a generated exception with a
// type info type of 7 is explained by: example in rules 1.6.4 in
// http://mentorembedded.github.com/cxx-abi/abi-eh.html (v1.22)
// http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html (v1.22)
//
// This code uses code from the llvm compiler-rt project and the llvm
// Kaleidoscope project.
@ -101,7 +101,7 @@ struct OurExceptionType_t {
///
/// Note: The above unwind.h defines struct _Unwind_Exception to be aligned
/// on a double word boundary. This is necessary to match the standard:
/// http://mentorembedded.github.com/cxx-abi/abi-eh.html
/// http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
struct OurBaseException_t {
struct OurExceptionType_t type;
@ -299,7 +299,7 @@ void deleteOurException(OurUnwindException *expToDelete) {
/// This function is the struct _Unwind_Exception API mandated delete function
/// used by foreign exception handlers when deleting our exception
/// (OurException), instances.
/// @param reason See @link http://mentorembedded.github.com/cxx-abi/abi-eh.html
/// @param reason See @link http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
/// @unlink
/// @param expToDelete exception instance to delete
void deleteFromUnwindOurException(_Unwind_Reason_Code reason,
@ -489,7 +489,7 @@ static uintptr_t readEncodedPointer(const uint8_t **data, uint8_t encoding) {
/// are supported. Filters are not supported.
/// See Variable Length Data in:
/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
/// Also see @link http://mentorembedded.github.com/cxx-abi/abi-eh.html @unlink
/// Also see @link http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html @unlink
/// @param resultAction reference variable which will be set with result
/// @param classInfo our array of type info pointers (to globals)
/// @param actionEntry index into above type info array or 0 (clean up).
@ -583,7 +583,7 @@ static bool handleActionValue(int64_t *resultAction,
/// Deals with the Language specific data portion of the emitted dwarf code.
/// See @link http://mentorembedded.github.com/cxx-abi/abi-eh.html @unlink
/// See @link http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html @unlink
/// @param version unsupported (ignored), unwind version
/// @param lsda language specific data area
/// @param _Unwind_Action actions minimally supported unwind stage
@ -767,7 +767,7 @@ static _Unwind_Reason_Code handleLsda(int version, const uint8_t *lsda,
/// This is the personality function which is embedded (dwarf emitted), in the
/// dwarf unwind info block. Again see: JITDwarfEmitter.cpp.
/// See @link http://mentorembedded.github.com/cxx-abi/abi-eh.html @unlink
/// See @link http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html @unlink
/// @param version unsupported (ignored), unwind version
/// @param _Unwind_Action actions minimally supported unwind stage
/// (forced specifically not supported)
@ -814,7 +814,7 @@ _Unwind_Reason_Code ourPersonality(int version, _Unwind_Action actions,
/// Generates our _Unwind_Exception class from a given character array.
/// thereby handling arbitrary lengths (not in standard), and handling
/// embedded \0s.
/// See @link http://mentorembedded.github.com/cxx-abi/abi-eh.html @unlink
/// See @link http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html @unlink
/// @param classChars char array to encode. NULL values not checkedf
/// @param classCharsSize number of chars in classChars. Value is not checked.
/// @returns class value
@ -1571,7 +1571,7 @@ void runExceptionThrow(llvm::ExecutionEngine *engine,
catch (...) {
// Catch all exceptions including our generated ones. This latter
// functionality works according to the example in rules 1.6.4 of
// http://mentorembedded.github.com/cxx-abi/abi-eh.html (v1.22),
// http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html (v1.22),
// given that these will be exceptions foreign to C++
// (the _Unwind_Exception::exception_class should be different from
// the one used by C++).

View File

@ -86,6 +86,10 @@ class KaleidoscopeJIT {
return CompileLayer.findSymbol(MangledNameStream.str(), true);
}
JITTargetAddress getSymbolAddress(const std::string Name) {
return cantFail(findSymbol(Name).getAddress());
}
void removeModule(ModuleHandle H) {
cantFail(CompileLayer.removeModule(H));
}

View File

@ -1144,13 +1144,11 @@ static void HandleTopLevelExpression() {
auto H = TheJIT->addModule(std::move(TheModule));
InitializeModule();
// Search the JIT for the __anon_expr symbol.
auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
assert(ExprSymbol && "Function not found");
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
// Get the anonymous expression's address and cast it to the right type,
// double(*)(), so we can call it as a native function.
double (*FP)() =
(double (*)())(intptr_t)TheJIT->getSymbolAddress("__anon_expr");
assert(FP && "Failed to codegen function");
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -135,7 +135,7 @@ class KaleidoscopeJIT {
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
// Create a CompileCallback - this is the re-entry point into the compiler
// for functions that haven't been compiled yet.
auto CCInfo = CompileCallbackMgr->getCompileCallback();
auto CCInfo = cantFail(CompileCallbackMgr->getCompileCallback());
// Create an indirect stub. This serves as the functions "canonical
// definition" - an unchanging (constant address) entry point to the

View File

@ -72,7 +72,7 @@ namespace llvm {
namespace orc {
// Typedef the remote-client API.
using MyRemote = remote::OrcRemoteTargetClient<FDRPCChannel>;
using MyRemote = remote::OrcRemoteTargetClient;
class KaleidoscopeJIT {
private:
@ -98,13 +98,7 @@ class KaleidoscopeJIT {
"", SmallVector<std::string, 0>())),
DL(TM->createDataLayout()),
ObjectLayer([&Remote]() {
std::unique_ptr<MyRemote::RCMemoryManager> MemMgr;
if (auto Err = Remote.createRemoteMemoryManager(MemMgr)) {
logAllUnhandledErrors(std::move(Err), errs(),
"Error creating remote memory manager:");
exit(1);
}
return MemMgr;
return cantFail(Remote.createRemoteMemoryManager());
}),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
OptimizeLayer(CompileLayer,
@ -119,13 +113,7 @@ class KaleidoscopeJIT {
exit(1);
}
CompileCallbackMgr = &*CCMgrOrErr;
std::unique_ptr<MyRemote::RCIndirectStubsManager> ISM;
if (auto Err = Remote.createIndirectStubsManager(ISM)) {
logAllUnhandledErrors(std::move(Err), errs(),
"Error creating indirect stubs manager:");
exit(1);
}
IndirectStubsMgr = std::move(ISM);
IndirectStubsMgr = cantFail(Remote.createIndirectStubsManager());
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
}
@ -164,7 +152,7 @@ class KaleidoscopeJIT {
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
// Create a CompileCallback - this is the re-entry point into the compiler
// for functions that haven't been compiled yet.
auto CCInfo = CompileCallbackMgr->getCompileCallback();
auto CCInfo = cantFail(CompileCallbackMgr->getCompileCallback());
// Create an indirect stub. This serves as the functions "canonical
// definition" - an unchanging (constant address) entry point to the

View File

@ -1277,7 +1277,7 @@ int main(int argc, char *argv[]) {
BinopPrecedence['*'] = 40; // highest.
auto TCPChannel = connect();
auto Remote = ExitOnErr(MyRemote::Create(*TCPChannel));
auto Remote = ExitOnErr(MyRemote::Create(*TCPChannel, ExitOnErr));
TheJIT = llvm::make_unique<KaleidoscopeJIT>(*Remote);
// Automatically inject a definition for 'printExprResult'.

View File

@ -11,4 +11,4 @@ add_llvm_example(ParallelJIT
ParallelJIT.cpp
)
target_link_libraries(ParallelJIT ${LLVM_PTHREAD_LIB})
target_link_libraries(ParallelJIT PRIVATE ${LLVM_PTHREAD_LIB})

View File

@ -1136,6 +1136,16 @@ LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C);
*/
LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C);
/**
* Create a token type in a context.
*/
LLVMTypeRef LLVMTokenTypeInContext(LLVMContextRef C);
/**
* Create a metadata type in a context.
*/
LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C);
/**
* These are similar to the above functions except they operate on the
* global context.

232
include/llvm-c/DebugInfo.h Normal file
View File

@ -0,0 +1,232 @@
//===------------ DebugInfo.h - LLVM C API Debug Info API -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// This file declares the C API endpoints for generating DWARF Debug Info
///
/// Note: This interface is experimental. It is *NOT* stable, and may be
/// changed without warning.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_C_DEBUGINFO_H
#define LLVM_C_DEBUGINFO_H
#include "llvm-c/Core.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Debug info flags.
*/
typedef enum {
LLVMDIFlagZero = 0,
LLVMDIFlagPrivate = 1,
LLVMDIFlagProtected = 2,
LLVMDIFlagPublic = 3,
LLVMDIFlagFwdDecl = 1 << 2,
LLVMDIFlagAppleBlock = 1 << 3,
LLVMDIFlagBlockByrefStruct = 1 << 4,
LLVMDIFlagVirtual = 1 << 5,
LLVMDIFlagArtificial = 1 << 6,
LLVMDIFlagExplicit = 1 << 7,
LLVMDIFlagPrototyped = 1 << 8,
LLVMDIFlagObjcClassComplete = 1 << 9,
LLVMDIFlagObjectPointer = 1 << 10,
LLVMDIFlagVector = 1 << 11,
LLVMDIFlagStaticMember = 1 << 12,
LLVMDIFlagLValueReference = 1 << 13,
LLVMDIFlagRValueReference = 1 << 14,
LLVMDIFlagReserved = 1 << 15,
LLVMDIFlagSingleInheritance = 1 << 16,
LLVMDIFlagMultipleInheritance = 2 << 16,
LLVMDIFlagVirtualInheritance = 3 << 16,
LLVMDIFlagIntroducedVirtual = 1 << 18,
LLVMDIFlagBitField = 1 << 19,
LLVMDIFlagNoReturn = 1 << 20,
LLVMDIFlagMainSubprogram = 1 << 21,
LLVMDIFlagIndirectVirtualBase = (1 << 2) | (1 << 5),
LLVMDIFlagAccessibility = LLVMDIFlagPrivate | LLVMDIFlagProtected |
LLVMDIFlagPublic,
LLVMDIFlagPtrToMemberRep = LLVMDIFlagSingleInheritance |
LLVMDIFlagMultipleInheritance |
LLVMDIFlagVirtualInheritance
} LLVMDIFlags;
/**
* Source languages known by DWARF.
*/
typedef enum {
LLVMDWARFSourceLanguageC89,
LLVMDWARFSourceLanguageC,
LLVMDWARFSourceLanguageAda83,
LLVMDWARFSourceLanguageC_plus_plus,
LLVMDWARFSourceLanguageCobol74,
LLVMDWARFSourceLanguageCobol85,
LLVMDWARFSourceLanguageFortran77,
LLVMDWARFSourceLanguageFortran90,
LLVMDWARFSourceLanguagePascal83,
LLVMDWARFSourceLanguageModula2,
// New in DWARF v3:
LLVMDWARFSourceLanguageJava,
LLVMDWARFSourceLanguageC99,
LLVMDWARFSourceLanguageAda95,
LLVMDWARFSourceLanguageFortran95,
LLVMDWARFSourceLanguagePLI,
LLVMDWARFSourceLanguageObjC,
LLVMDWARFSourceLanguageObjC_plus_plus,
LLVMDWARFSourceLanguageUPC,
LLVMDWARFSourceLanguageD,
// New in DWARF v4:
LLVMDWARFSourceLanguagePython,
// New in DWARF v5:
LLVMDWARFSourceLanguageOpenCL,
LLVMDWARFSourceLanguageGo,
LLVMDWARFSourceLanguageModula3,
LLVMDWARFSourceLanguageHaskell,
LLVMDWARFSourceLanguageC_plus_plus_03,
LLVMDWARFSourceLanguageC_plus_plus_11,
LLVMDWARFSourceLanguageOCaml,
LLVMDWARFSourceLanguageRust,
LLVMDWARFSourceLanguageC11,
LLVMDWARFSourceLanguageSwift,
LLVMDWARFSourceLanguageJulia,
LLVMDWARFSourceLanguageDylan,
LLVMDWARFSourceLanguageC_plus_plus_14,
LLVMDWARFSourceLanguageFortran03,
LLVMDWARFSourceLanguageFortran08,
LLVMDWARFSourceLanguageRenderScript,
LLVMDWARFSourceLanguageBLISS,
// Vendor extensions:
LLVMDWARFSourceLanguageMips_Assembler,
LLVMDWARFSourceLanguageGOOGLE_RenderScript,
LLVMDWARFSourceLanguageBORLAND_Delphi
} LLVMDWARFSourceLanguage;
/**
* The amount of debug information to emit.
*/
typedef enum {
LLVMDWARFEmissionNone = 0,
LLVMDWARFEmissionFull,
LLVMDWARFEmissionLineTablesOnly
} LLVMDWARFEmissionKind;
/**
* The current debug metadata version number.
*/
unsigned LLVMDebugMetadataVersion(void);
/**
* The version of debug metadata that's present in the provided \c Module.
*/
unsigned LLVMGetModuleDebugMetadataVersion(LLVMModuleRef Module);
/**
* Strip debug info in the module if it exists.
* To do this, we remove all calls to the debugger intrinsics and any named
* metadata for debugging. We also remove debug locations for instructions.
* Return true if module is modified.
*/
LLVMBool LLVMStripModuleDebugInfo(LLVMModuleRef Module);
/**
* Construct a builder for a module, and do not allow for unresolved nodes
* attached to the module.
*/
LLVMDIBuilderRef LLVMCreateDIBuilderDisallowUnresolved(LLVMModuleRef M);
/**
* Construct a builder for a module and collect unresolved nodes attached
* to the module in order to resolve cycles during a call to
* \c LLVMDIBuilderFinalize.
*/
LLVMDIBuilderRef LLVMCreateDIBuilder(LLVMModuleRef M);
/**
* Deallocates the \c DIBuilder and everything it owns.
* @note You must call \c LLVMDIBuilderFinalize before this
*/
void LLVMDisposeDIBuilder(LLVMDIBuilderRef Builder);
/**
* Construct any deferred debug info descriptors.
*/
void LLVMDIBuilderFinalize(LLVMDIBuilderRef Builder);
/**
* A CompileUnit provides an anchor for all debugging
* information generated during this instance of compilation.
* \param Lang Source programming language, eg.
* \c LLVMDWARFSourceLanguageC99
* \param FileRef File info.
* \param Producer Identify the producer of debugging information
* and code. Usually this is a compiler
* version string.
* \param ProducerLen The length of the C string passed to \c Producer.
* \param isOptimized A boolean flag which indicates whether optimization
* is enabled or not.
* \param Flags This string lists command line options. This
* string is directly embedded in debug info
* output which may be used by a tool
* analyzing generated debugging information.
* \param FlagsLen The length of the C string passed to \c Flags.
* \param RuntimeVer This indicates runtime version for languages like
* Objective-C.
* \param SplitName The name of the file that we'll split debug info
* out into.
* \param SplitNameLen The length of the C string passed to \c SplitName.
* \param Kind The kind of debug information to generate.
* \param DWOId The DWOId if this is a split skeleton compile unit.
* \param SplitDebugInlining Whether to emit inline debug info.
* \param DebugInfoForProfiling Whether to emit extra debug info for
* profile collection.
*/
LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
LLVMDIBuilderRef Builder, LLVMDWARFSourceLanguage Lang,
LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen,
LLVMBool isOptimized, const char *Flags, size_t FlagsLen,
unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen,
LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining,
LLVMBool DebugInfoForProfiling);
/**
* Create a file descriptor to hold debugging information for a file.
* \param Builder The \c DIBuilder.
* \param Filename File name.
* \param FilenameLen The length of the C string passed to \c Filename.
* \param Directory Directory.
* \param DirectoryLen The length of the C string passed to \c Directory.
*/
LLVMMetadataRef
LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename,
size_t FilenameLen, const char *Directory,
size_t DirectoryLen);
/**
* Creates a new DebugLocation that describes a source location.
* \param Line The line in the source file.
* \param Column The column in the source file.
* \param Scope The scope in which the location resides.
* \param InlinedAt The scope where this location was inlined, if at all.
* (optional).
* \note If the item to which this location is attached cannot be
* attributed to a source line, pass 0 for the line and column.
*/
LLVMMetadataRef
LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line,
unsigned Column, LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif

View File

@ -30,7 +30,6 @@ extern "C" {
#endif
typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
typedef struct LLVMOpaqueSharedObjectBuffer *LLVMSharedObjectBufferRef;
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
typedef uint32_t LLVMOrcModuleHandle;
typedef uint64_t LLVMOrcTargetAddress;
@ -67,18 +66,6 @@ LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod);
void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod);
/**
* Get an LLVMSharedObjectBufferRef from an LLVMMemoryBufferRef.
*/
LLVMSharedObjectBufferRef
LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer);
/**
* Dispose of a shared object buffer.
*/
void
LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer);
/**
* Create an ORC JIT stack.
*
@ -155,10 +142,15 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
/**
* Add an object file.
*
* This method takes ownership of the given memory buffer and attempts to add
* it to the JIT as an object file.
* Clients should *not* dispose of the 'Obj' argument: the JIT will manage it
* from this call onwards.
*/
LLVMOrcErrorCode LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
LLVMOrcModuleHandle *RetHandle,
LLVMSharedObjectBufferRef Obj,
LLVMMemoryBufferRef Obj,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);

View File

@ -34,6 +34,9 @@ void LLVMAddArgumentPromotionPass(LLVMPassManagerRef PM);
/** See llvm::createConstantMergePass function. */
void LLVMAddConstantMergePass(LLVMPassManagerRef PM);
/** See llvm::createCalledValuePropagationPass function. */
void LLVMAddCalledValuePropagationPass(LLVMPassManagerRef PM);
/** See llvm::createDeadArgEliminationPass function. */
void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM);

View File

@ -44,9 +44,6 @@ void LLVMAddAlignmentFromAssumptionsPass(LLVMPassManagerRef PM);
/** See llvm::createCFGSimplificationPass function. */
void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM);
/** See llvm::createLateCFGSimplificationPass function. */
void LLVMAddLateCFGSimplificationPass(LLVMPassManagerRef PM);
/** See llvm::createDeadStoreEliminationPass function. */
void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM);

View File

@ -1119,6 +1119,21 @@ class APFloat : public APFloatBase {
llvm_unreachable("Unexpected semantics");
}
/// We don't rely on operator== working on double values, as
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
/// As such, this method can be used to do an exact bit-for-bit comparison of
/// two floating point values.
///
/// We leave the version with the double argument here because it's just so
/// convenient to write "2.0" and the like. Without this function we'd
/// have to duplicate its logic everywhere it's called.
bool isExactlyValue(double V) const {
bool ignored;
APFloat Tmp(V);
Tmp.convert(getSemantics(), APFloat::rmNearestTiesToEven, &ignored);
return bitwiseIsEqual(Tmp);
}
unsigned int convertToHexString(char *DST, unsigned int HexDigits,
bool UpperCase, roundingMode RM) const {
APFLOAT_DISPATCH_ON_SEMANTICS(

View File

@ -1724,13 +1724,13 @@ class LLVM_NODISCARD APInt {
/// @{
/// \returns the floor log base 2 of this APInt.
unsigned logBase2() const { return BitWidth - 1 - countLeadingZeros(); }
unsigned logBase2() const { return getActiveBits() - 1; }
/// \returns the ceil log base 2 of this APInt.
unsigned ceilLogBase2() const {
APInt temp(*this);
--temp;
return BitWidth - temp.countLeadingZeros();
return temp.getActiveBits();
}
/// \returns the nearest log base 2 of this APInt. Ties round up.

View File

@ -294,7 +294,7 @@ namespace llvm {
using reverse_iterator = std::reverse_iterator<iterator>;
/// Construct an empty MutableArrayRef.
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
/*implicit*/ MutableArrayRef() = default;
/// Construct an empty MutableArrayRef from None.
/*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {}

View File

@ -911,7 +911,7 @@ class BitVector {
size_t getBitCapacity() const { return Bits.size() * BITWORD_SIZE; }
};
static inline size_t capacity_in_bytes(const BitVector &X) {
inline size_t capacity_in_bytes(const BitVector &X) {
return X.getMemorySize();
}

View File

@ -19,6 +19,7 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ReverseIteration.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert>
@ -67,18 +68,26 @@ class DenseMapBase : public DebugEpochBase {
DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>;
inline iterator begin() {
// When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this);
// When the map is empty, avoid the overhead of advancing/retreating past
// empty buckets.
if (empty())
return end();
if (shouldReverseIterate<KeyT>())
return makeIterator(getBucketsEnd() - 1, getBuckets(), *this);
return makeIterator(getBuckets(), getBucketsEnd(), *this);
}
inline iterator end() {
return iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
return makeIterator(getBucketsEnd(), getBucketsEnd(), *this, true);
}
inline const_iterator begin() const {
return empty() ? end()
: const_iterator(getBuckets(), getBucketsEnd(), *this);
if (empty())
return end();
if (shouldReverseIterate<KeyT>())
return makeConstIterator(getBucketsEnd() - 1, getBuckets(), *this);
return makeConstIterator(getBuckets(), getBucketsEnd(), *this);
}
inline const_iterator end() const {
return const_iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
return makeConstIterator(getBucketsEnd(), getBucketsEnd(), *this, true);
}
LLVM_NODISCARD bool empty() const {
@ -107,17 +116,23 @@ class DenseMapBase : public DebugEpochBase {
}
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
unsigned NumEntries = getNumEntries();
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) {
if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
P->getSecond().~ValueT();
--NumEntries;
}
if (isPodLike<KeyT>::value && isPodLike<ValueT>::value) {
// Use a simpler loop when these are trivial types.
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P)
P->getFirst() = EmptyKey;
} else {
unsigned NumEntries = getNumEntries();
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) {
if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
P->getSecond().~ValueT();
--NumEntries;
}
P->getFirst() = EmptyKey;
}
}
assert(NumEntries == 0 && "Node count imbalance!");
}
assert(NumEntries == 0 && "Node count imbalance!");
setNumEntries(0);
setNumTombstones(0);
}
@ -131,13 +146,13 @@ class DenseMapBase : public DebugEpochBase {
iterator find(const_arg_type_t<KeyT> Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return iterator(TheBucket, getBucketsEnd(), *this, true);
return makeIterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
const_iterator find(const_arg_type_t<KeyT> Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return const_iterator(TheBucket, getBucketsEnd(), *this, true);
return makeConstIterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
@ -150,14 +165,14 @@ class DenseMapBase : public DebugEpochBase {
iterator find_as(const LookupKeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return iterator(TheBucket, getBucketsEnd(), *this, true);
return makeIterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
template<class LookupKeyT>
const_iterator find_as(const LookupKeyT &Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return const_iterator(TheBucket, getBucketsEnd(), *this, true);
return makeConstIterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
@ -191,14 +206,16 @@ class DenseMapBase : public DebugEpochBase {
std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&... Args) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
false); // Already in map.
return std::make_pair(
makeIterator(TheBucket, getBucketsEnd(), *this, true),
false); // Already in map.
// Otherwise, insert the new element.
TheBucket =
InsertIntoBucket(TheBucket, std::move(Key), std::forward<Ts>(Args)...);
return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
true);
return std::make_pair(
makeIterator(TheBucket, getBucketsEnd(), *this, true),
true);
}
// Inserts key,value pair into the map if the key isn't already in the map.
@ -208,13 +225,15 @@ class DenseMapBase : public DebugEpochBase {
std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&... Args) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
false); // Already in map.
return std::make_pair(
makeIterator(TheBucket, getBucketsEnd(), *this, true),
false); // Already in map.
// Otherwise, insert the new element.
TheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(Args)...);
return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
true);
return std::make_pair(
makeIterator(TheBucket, getBucketsEnd(), *this, true),
true);
}
/// Alternate version of insert() which allows a different, and possibly
@ -227,14 +246,16 @@ class DenseMapBase : public DebugEpochBase {
const LookupKeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
false); // Already in map.
return std::make_pair(
makeIterator(TheBucket, getBucketsEnd(), *this, true),
false); // Already in map.
// Otherwise, insert the new element.
TheBucket = InsertIntoBucketWithLookup(TheBucket, std::move(KV.first),
std::move(KV.second), Val);
return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
true);
return std::make_pair(
makeIterator(TheBucket, getBucketsEnd(), *this, true),
true);
}
/// insert - Range insertion of pairs.
@ -405,6 +426,26 @@ class DenseMapBase : public DebugEpochBase {
}
private:
iterator makeIterator(BucketT *P, BucketT *E,
DebugEpochBase &Epoch,
bool NoAdvance=false) {
if (shouldReverseIterate<KeyT>()) {
BucketT *B = P == getBucketsEnd() ? getBuckets() : P + 1;
return iterator(B, E, Epoch, NoAdvance);
}
return iterator(P, E, Epoch, NoAdvance);
}
const_iterator makeConstIterator(const BucketT *P, const BucketT *E,
const DebugEpochBase &Epoch,
const bool NoAdvance=false) const {
if (shouldReverseIterate<KeyT>()) {
const BucketT *B = P == getBucketsEnd() ? getBuckets() : P + 1;
return const_iterator(B, E, Epoch, NoAdvance);
}
return const_iterator(P, E, Epoch, NoAdvance);
}
unsigned getNumEntries() const {
return static_cast<const DerivedT *>(this)->getNumEntries();
}
@ -1089,7 +1130,13 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
bool NoAdvance = false)
: DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) {
assert(isHandleInSync() && "invalid construction!");
if (!NoAdvance) AdvancePastEmptyBuckets();
if (NoAdvance) return;
if (shouldReverseIterate<KeyT>()) {
RetreatPastEmptyBuckets();
return;
}
AdvancePastEmptyBuckets();
}
// Converting ctor from non-const iterators to const iterators. SFINAE'd out
@ -1103,10 +1150,14 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
reference operator*() const {
assert(isHandleInSync() && "invalid iterator access!");
if (shouldReverseIterate<KeyT>())
return Ptr[-1];
return *Ptr;
}
pointer operator->() const {
assert(isHandleInSync() && "invalid iterator access!");
if (shouldReverseIterate<KeyT>())
return &(Ptr[-1]);
return Ptr;
}
@ -1127,6 +1178,11 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
inline DenseMapIterator& operator++() { // Preincrement
assert(isHandleInSync() && "invalid iterator access!");
if (shouldReverseIterate<KeyT>()) {
--Ptr;
RetreatPastEmptyBuckets();
return *this;
}
++Ptr;
AdvancePastEmptyBuckets();
return *this;
@ -1138,6 +1194,7 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
private:
void AdvancePastEmptyBuckets() {
assert(Ptr <= End);
const KeyT Empty = KeyInfoT::getEmptyKey();
const KeyT Tombstone = KeyInfoT::getTombstoneKey();
@ -1145,11 +1202,20 @@ class DenseMapIterator : DebugEpochBase::HandleBase {
KeyInfoT::isEqual(Ptr->getFirst(), Tombstone)))
++Ptr;
}
void RetreatPastEmptyBuckets() {
assert(Ptr >= End);
const KeyT Empty = KeyInfoT::getEmptyKey();
const KeyT Tombstone = KeyInfoT::getTombstoneKey();
while (Ptr != End && (KeyInfoT::isEqual(Ptr[-1].getFirst(), Empty) ||
KeyInfoT::isEqual(Ptr[-1].getFirst(), Tombstone)))
--Ptr;
}
};
template<typename KeyT, typename ValueT, typename KeyInfoT>
static inline size_t
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
template <typename KeyT, typename ValueT, typename KeyInfoT>
inline size_t capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
return X.getMemorySize();
}

View File

@ -239,6 +239,16 @@ class EquivalenceClasses {
return L1;
}
// isEquivalent - Return true if V1 is equivalent to V2. This can happen if
// V1 is equal to V2 or if they belong to one equivalence class.
bool isEquivalent(const ElemTy &V1, const ElemTy &V2) const {
// Fast path: any element is equivalent to itself.
if (V1 == V2)
return true;
auto It = findLeader(V1);
return It != member_end() && It == findLeader(V2);
}
class member_iterator : public std::iterator<std::forward_iterator_tag,
const ElemTy, ptrdiff_t> {
friend class EquivalenceClasses;

View File

@ -1,4 +1,4 @@
//===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- C++ -*-===//
//===- llvm/ADT/FoldingSet.h - Uniquing Hash Set ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -115,11 +115,9 @@ class FoldingSetBase {
protected:
/// Buckets - Array of bucket chains.
///
void **Buckets;
/// NumBuckets - Length of the Buckets array. Always a power of 2.
///
unsigned NumBuckets;
/// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
@ -135,14 +133,13 @@ class FoldingSetBase {
//===--------------------------------------------------------------------===//
/// Node - This class is used to maintain the singly linked bucket list in
/// a folding set.
///
class Node {
private:
// NextInFoldingSetBucket - next link in the bucket list.
void *NextInFoldingSetBucket;
void *NextInFoldingSetBucket = nullptr;
public:
Node() : NextInFoldingSetBucket(nullptr) {}
Node() = default;
// Accessors
void *getNextInBucket() const { return NextInFoldingSetBucket; }
@ -221,7 +218,6 @@ class FoldingSetBase {
/// DefaultFoldingSetTrait - This class provides default implementations
/// for FoldingSetTrait implementations.
///
template<typename T> struct DefaultFoldingSetTrait {
static void Profile(const T &X, FoldingSetNodeID &ID) {
X.Profile(ID);
@ -307,7 +303,6 @@ class FoldingSetNodeIDRef {
/// FoldingSetNodeID - This class is used to gather all the unique data bits of
/// a node. When all the bits are gathered this class is used to produce a
/// hash value for the node.
///
class FoldingSetNodeID {
/// Bits - Vector of all the data bits that make the node unique.
/// Use a SmallVector to avoid a heap allocation in the common case.
@ -320,7 +315,6 @@ class FoldingSetNodeID {
: Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {}
/// Add* - Add various data types to Bit data.
///
void AddPointer(const void *Ptr);
void AddInteger(signed I);
void AddInteger(unsigned I);
@ -344,7 +338,6 @@ class FoldingSetNodeID {
unsigned ComputeHash() const;
/// operator== - Used to compare two nodes to each other.
///
bool operator==(const FoldingSetNodeID &RHS) const;
bool operator==(const FoldingSetNodeIDRef RHS) const;
@ -363,7 +356,7 @@ class FoldingSetNodeID {
};
// Convenience type to hide the implementation of the folding set.
typedef FoldingSetBase::Node FoldingSetNode;
using FoldingSetNode = FoldingSetBase::Node;
template<class T> class FoldingSetIterator;
template<class T> class FoldingSetBucketIterator;
@ -415,15 +408,17 @@ template <class T> class FoldingSetImpl : public FoldingSetBase {
~FoldingSetImpl() = default;
public:
typedef FoldingSetIterator<T> iterator;
using iterator = FoldingSetIterator<T>;
iterator begin() { return iterator(Buckets); }
iterator end() { return iterator(Buckets+NumBuckets); }
typedef FoldingSetIterator<const T> const_iterator;
using const_iterator = FoldingSetIterator<const T>;
const_iterator begin() const { return const_iterator(Buckets); }
const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
typedef FoldingSetBucketIterator<T> bucket_iterator;
using bucket_iterator = FoldingSetBucketIterator<T>;
bucket_iterator bucket_begin(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
@ -503,9 +498,7 @@ template <class T> class FoldingSet final : public FoldingSetImpl<T> {
}
public:
explicit FoldingSet(unsigned Log2InitSize = 6)
: Super(Log2InitSize) {}
explicit FoldingSet(unsigned Log2InitSize = 6) : Super(Log2InitSize) {}
FoldingSet(FoldingSet &&Arg) = default;
FoldingSet &operator=(FoldingSet &&RHS) = default;
};
@ -552,8 +545,7 @@ class ContextualFoldingSet final : public FoldingSetImpl<T> {
public:
explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
: Super(Log2InitSize), Context(Context)
{}
: Super(Log2InitSize), Context(Context) {}
Ctx getContext() const { return Context; }
};
@ -569,15 +561,15 @@ class FoldingSetVector {
VectorT Vector;
public:
explicit FoldingSetVector(unsigned Log2InitSize = 6)
: Set(Log2InitSize) {
}
explicit FoldingSetVector(unsigned Log2InitSize = 6) : Set(Log2InitSize) {}
using iterator = pointee_iterator<typename VectorT::iterator>;
typedef pointee_iterator<typename VectorT::iterator> iterator;
iterator begin() { return Vector.begin(); }
iterator end() { return Vector.end(); }
typedef pointee_iterator<typename VectorT::const_iterator> const_iterator;
using const_iterator = pointee_iterator<typename VectorT::const_iterator>;
const_iterator begin() const { return Vector.begin(); }
const_iterator end() const { return Vector.end(); }
@ -667,15 +659,13 @@ template <class T> class FoldingSetIterator : public FoldingSetIteratorImpl {
/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
/// shared by all folding sets, which knows how to walk a particular bucket
/// of a folding set hash table.
class FoldingSetBucketIteratorImpl {
protected:
void *Ptr;
explicit FoldingSetBucketIteratorImpl(void **Bucket);
FoldingSetBucketIteratorImpl(void **Bucket, bool)
: Ptr(Bucket) {}
FoldingSetBucketIteratorImpl(void **Bucket, bool) : Ptr(Bucket) {}
void advance() {
void *Probe = static_cast<FoldingSetNode*>(Ptr)->getNextInBucket();

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