Updating branches/google/stable to r239765

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/stable@240090 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky 2015-06-18 23:36:58 +00:00
commit cb3f5d30cc
3961 changed files with 205721 additions and 64089 deletions

View File

@ -32,15 +32,23 @@ project(LLVM)
set(LLVM_PARALLEL_COMPILE_JOBS "" CACHE STRING
"Define the maximum number of concurrent compilation jobs.")
if(LLVM_PARALLEL_COMPILE_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${LLVM_PARALLEL_COMPILE_JOBS})
set(CMAKE_JOB_POOL_COMPILE compile_job_pool)
if(CMAKE_VERSION VERSION_LESS 3.0 OR NOT CMAKE_MAKE_PROGRAM MATCHES "ninja$")
message(WARNING "Job pooling is only available with Ninja generators and CMake 3.0 and later.")
else()
set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${LLVM_PARALLEL_COMPILE_JOBS})
set(CMAKE_JOB_POOL_COMPILE compile_job_pool)
endif()
endif()
set(LLVM_PARALLEL_LINK_JOBS "" CACHE STRING
"Define the maximum number of concurrent link jobs.")
if(LLVM_PARALLEL_LINK_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${LLVM_PARALLEL_LINK_JOBS})
set(CMAKE_JOB_POOL_LINK link_job_pool)
if(CMAKE_VERSION VERSION_LESS 3.0 OR NOT CMAKE_MAKE_PROGRAM MATCHES "ninja$")
message(WARNING "Job pooling is only available with Ninja generators and CMake 3.0 and later.")
else()
set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${LLVM_PARALLEL_LINK_JOBS})
set(CMAKE_JOB_POOL_LINK link_job_pool)
endif()
endif()
# Add path for custom modules
@ -93,6 +101,7 @@ set(CPACK_PACKAGE_VERSION_MINOR ${LLVM_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${LLVM_VERSION_PATCH})
set(CPACK_PACKAGE_VERSION ${PACKAGE_VERSION})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.TXT")
set(CPACK_NSIS_COMPRESSOR "/SOLID lzma \r\n SetCompressorDictSize 32")
if(WIN32 AND NOT UNIX)
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "LLVM")
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\cmake\\\\nsis_logo.bmp")
@ -167,14 +176,15 @@ set(LLVM_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
set(LLVM_ALL_TARGETS
AArch64
AMDGPU
ARM
BPF
CppBackend
Hexagon
Mips
MSP430
NVPTX
PowerPC
R600
Sparc
SystemZ
X86

View File

@ -89,6 +89,10 @@ N: Lang Hames
E: lhames@gmail.com
D: MCJIT, RuntimeDyld and JIT event listeners
N: David Majnemer
E: david.majnemer@gmail.com
D: IR Constant Folder
N: Galina Kistanova
E: gkistanova@gmail.com
D: LLVM Buildbot
@ -182,3 +186,7 @@ D: libLTO, IR Linker
N: Peter Zotov
E: whitequark@whitequark.org
D: OCaml bindings
N: Andrey Churbanov
E: andrey.churbanov@intel.com
D: OpenMP runtime library

View File

@ -58,6 +58,22 @@ LLVM_OBJ_ROOT := $(call realpath, @abs_top_builddir@)
PROJ_SRC_ROOT := $(LLVM_SRC_ROOT)
PROJ_SRC_DIR := $(LLVM_SRC_ROOT)$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR))
# FIXME: This is temporary during the grace period where in-source builds are
# deprecated. Convert to a hard error when that period is up.
#
# See: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20150323/268067.html
ifeq ($(LLVM_SRC_ROOT), $(LLVM_OBJ_ROOT))
$(warning ######################################################################################)
$(warning # #)
$(warning # WARNING #)
$(warning # #)
$(warning # In-source builds are deprecated. #)
$(warning # #)
$(warning # Please configure from a separate build directory! #)
$(warning # #)
$(warning ######################################################################################)
endif
ifneq ($(CLANG_SRC_ROOT),)
CLANG_SRC_ROOT:= $(call realpath, $(CLANG_SRC_ROOT))
PROJ_SRC_DIR := $(patsubst $(LLVM_SRC_ROOT)/tools/clang%,$(CLANG_SRC_ROOT)%,$(PROJ_SRC_DIR))

View File

@ -73,6 +73,19 @@ if test ${srcdir} != "." ; then
fi
fi
dnl Quit if it is an in-source build
if test ${srcdir} == "." ; then
AC_MSG_WARN([**************************************************************************************])
AC_MSG_WARN([* *])
AC_MSG_WARN([* WARNING *])
AC_MSG_WARN([* *])
AC_MSG_WARN([* In-source builds are deprecated. *])
AC_MSG_WARN([* *])
AC_MSG_WARN([* Please configure from a separate build directory! *])
AC_MSG_WARN([* *])
AC_MSG_WARN([**************************************************************************************])
fi
dnl Default to empty (i.e. assigning the null string to) CFLAGS and CXXFLAGS,
dnl instead of the autoconf default (for example, '-g -O2' for CC=gcc).
: ${CFLAGS=}
@ -105,7 +118,7 @@ if test "$CXX" = "clang++" ; then
],
[
AC_MSG_RESULT([no])
AC_MSG_ERROR([Selected compiler could not find or parse C++ standard library headers. Rerun with CC=c-compiler CXX=c++-compiler ./configure ...])
AC_MSG_ERROR([Selected compiler could not find or parse C++ standard library headers. Rerun with CC=c-compiler CXX=c++-compiler LLVM_SRC_DIR/configure ...])
])
AC_LANG_POP([C++])
fi
@ -1084,7 +1097,7 @@ if test "$llvm_cv_enable_crash_overrides" = "yes" ; then
fi
dnl List all possible targets
ALL_TARGETS="X86 Sparc PowerPC ARM AArch64 Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600"
ALL_TARGETS="X86 Sparc PowerPC ARM AArch64 Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ AMDGPU BPF"
AC_SUBST(ALL_TARGETS,$ALL_TARGETS)
dnl Allow specific targets to be specified for building (or not)
@ -1092,7 +1105,7 @@ TARGETS_TO_BUILD=""
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
[Build specific host targets: all or target1,target2,... Valid targets are:
host, x86, x86_64, sparc, powerpc, arm64, arm, aarch64, mips, hexagon,
xcore, msp430, nvptx, systemz, r600, and cpp (default=all)]),,
xcore, msp430, nvptx, systemz, r600, bpf, and cpp (default=all)]),,
enableval=all)
if test "$enableval" = host-only ; then
enableval=host
@ -1108,6 +1121,7 @@ case "$enableval" in
aarch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
arm64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
bpf) TARGETS_TO_BUILD="BPF $TARGETS_TO_BUILD" ;;
mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
mipsel) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
mips64) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
@ -1118,7 +1132,8 @@ case "$enableval" in
hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
amdgpu) TARGETS_TO_BUILD="AMDGPU $TARGETS_TO_BUILD" ;;
r600) TARGETS_TO_BUILD="AMDGPU $TARGETS_TO_BUILD" ;;
host) case "$llvm_cv_target_arch" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -1324,6 +1339,13 @@ AC_ARG_WITH(default-sysroot,
AC_DEFINE_UNQUOTED(DEFAULT_SYSROOT,"$withval",
[Default <path> to all compiler invocations for --sysroot=<path>.])
AC_ARG_WITH(clang-default-openmp-runtime,
AS_HELP_STRING([--with-clang-default-openmp-runtime],
[The default OpenMP runtime for Clang.]),,
withval="libgomp")
AC_DEFINE_UNQUOTED(CLANG_DEFAULT_OPENMP_RUNTIME,"$withval",
[Default OpenMP runtime used by -fopenmp.])
dnl Allow linking of LLVM with GPLv3 binutils code.
AC_ARG_WITH(binutils-include,
AS_HELP_STRING([--with-binutils-include],

View File

@ -40,16 +40,14 @@ LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef Dref,
int Optimized, const char *Flags,
unsigned RuntimeVersion) {
DIBuilder *D = unwrap(Dref);
DICompileUnit CU = D->createCompileUnit(Lang, File, Dir, Producer, Optimized,
Flags, RuntimeVersion);
return wrap(CU);
return wrap(D->createCompileUnit(Lang, File, Dir, Producer, Optimized, Flags,
RuntimeVersion));
}
LLVMMetadataRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Dref, const char *File,
const char *Dir) {
DIBuilder *D = unwrap(Dref);
DIFile F = D->createFile(File, Dir);
return wrap(F);
return wrap(D->createFile(File, Dir));
}
LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
@ -58,8 +56,8 @@ LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
unsigned Line,
unsigned Column) {
DIBuilder *D = unwrap(Dref);
auto *LB = D->createLexicalBlock(unwrap<MDLocalScope>(Scope),
unwrap<MDFile>(File), Line, Column);
auto *LB = D->createLexicalBlock(unwrap<DILocalScope>(Scope),
unwrap<DIFile>(File), Line, Column);
return wrap(LB);
}
@ -68,9 +66,8 @@ LLVMMetadataRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref,
LLVMMetadataRef File,
unsigned Discriminator) {
DIBuilder *D = unwrap(Dref);
DILexicalBlockFile LBF = D->createLexicalBlockFile(
unwrap<MDLocalScope>(Scope), unwrap<MDFile>(File), Discriminator);
return wrap(LBF);
return wrap(D->createLexicalBlockFile(unwrap<DILocalScope>(Scope),
unwrap<DIFile>(File), Discriminator));
}
LLVMMetadataRef LLVMDIBuilderCreateFunction(
@ -79,12 +76,11 @@ LLVMMetadataRef LLVMDIBuilderCreateFunction(
LLVMMetadataRef CompositeType, int IsLocalToUnit, int IsDefinition,
unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Func) {
DIBuilder *D = unwrap(Dref);
DISubprogram SP = D->createFunction(
unwrap<MDScope>(Scope), Name, LinkageName,
File ? unwrap<MDFile>(File) : nullptr, Line,
unwrap<MDSubroutineType>(CompositeType), IsLocalToUnit, IsDefinition,
ScopeLine, Flags, IsOptimized, unwrap<Function>(Func));
return wrap(SP);
return wrap(D->createFunction(unwrap<DIScope>(Scope), Name, LinkageName,
File ? unwrap<DIFile>(File) : nullptr, Line,
unwrap<DISubroutineType>(CompositeType),
IsLocalToUnit, IsDefinition, ScopeLine, Flags,
IsOptimized, unwrap<Function>(Func)));
}
LLVMMetadataRef LLVMDIBuilderCreateLocalVariable(
@ -92,10 +88,9 @@ LLVMMetadataRef LLVMDIBuilderCreateLocalVariable(
const char *Name, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty,
int AlwaysPreserve, unsigned Flags, unsigned ArgNo) {
DIBuilder *D = unwrap(Dref);
DIVariable V = D->createLocalVariable(
Tag, unwrap<MDScope>(Scope), Name, unwrap<MDFile>(File), Line,
unwrap<MDType>(Ty), AlwaysPreserve, Flags, ArgNo);
return wrap(V);
return wrap(D->createLocalVariable(
Tag, unwrap<DIScope>(Scope), Name, unwrap<DIFile>(File), Line,
unwrap<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
}
LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref,
@ -104,8 +99,7 @@ LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref,
uint64_t AlignInBits,
unsigned Encoding) {
DIBuilder *D = unwrap(Dref);
DIBasicType T = D->createBasicType(Name, SizeInBits, AlignInBits, Encoding);
return wrap(T);
return wrap(D->createBasicType(Name, SizeInBits, AlignInBits, Encoding));
}
LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
@ -114,19 +108,17 @@ LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
uint64_t AlignInBits,
const char *Name) {
DIBuilder *D = unwrap(Dref);
DIDerivedType T = D->createPointerType(unwrap<MDType>(PointeeType),
SizeInBits, AlignInBits, Name);
return wrap(T);
return wrap(D->createPointerType(unwrap<DIType>(PointeeType), SizeInBits,
AlignInBits, Name));
}
LLVMMetadataRef
LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref, LLVMMetadataRef File,
LLVMMetadataRef ParameterTypes) {
DIBuilder *D = unwrap(Dref);
DICompositeType CT =
D->createSubroutineType(File ? unwrap<MDFile>(File) : nullptr,
DITypeArray(unwrap<MDTuple>(ParameterTypes)));
return wrap(CT);
return wrap(
D->createSubroutineType(File ? unwrap<DIFile>(File) : nullptr,
DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
}
LLVMMetadataRef LLVMDIBuilderCreateStructType(
@ -135,12 +127,11 @@ LLVMMetadataRef LLVMDIBuilderCreateStructType(
uint64_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom,
LLVMMetadataRef ElementTypes) {
DIBuilder *D = unwrap(Dref);
DICompositeType CT = D->createStructType(
unwrap<MDScope>(Scope), Name, File ? unwrap<MDFile>(File) : nullptr, Line,
return wrap(D->createStructType(
unwrap<DIScope>(Scope), Name, File ? unwrap<DIFile>(File) : nullptr, Line,
SizeInBits, AlignInBits, Flags,
DerivedFrom ? unwrap<MDType>(DerivedFrom) : nullptr,
ElementTypes ? DIArray(unwrap<MDTuple>(ElementTypes)) : nullptr);
return wrap(CT);
DerivedFrom ? unwrap<DIType>(DerivedFrom) : nullptr,
ElementTypes ? DINodeArray(unwrap<MDTuple>(ElementTypes)) : nullptr));
}
LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType(
@ -149,10 +140,9 @@ LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType(
unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits,
unsigned Flags) {
DIBuilder *D = unwrap(Dref);
DICompositeType CT = D->createReplaceableCompositeType(
Tag, Name, unwrap<MDScope>(Scope), File ? unwrap<MDFile>(File) : nullptr,
Line, RuntimeLang, SizeInBits, AlignInBits, Flags);
return wrap(CT);
return wrap(D->createReplaceableCompositeType(
Tag, Name, unwrap<DIScope>(Scope), File ? unwrap<DIFile>(File) : nullptr,
Line, RuntimeLang, SizeInBits, AlignInBits, Flags));
}
LLVMMetadataRef
@ -162,10 +152,9 @@ LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef Dref, LLVMMetadataRef Scope,
uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, LLVMMetadataRef Ty) {
DIBuilder *D = unwrap(Dref);
DIDerivedType DT = D->createMemberType(
unwrap<MDScope>(Scope), Name, File ? unwrap<MDFile>(File) : nullptr, Line,
SizeInBits, AlignInBits, OffsetInBits, Flags, unwrap<MDType>(Ty));
return wrap(DT);
return wrap(D->createMemberType(
unwrap<DIScope>(Scope), Name, File ? unwrap<DIFile>(File) : nullptr, Line,
SizeInBits, AlignInBits, OffsetInBits, Flags, unwrap<DIType>(Ty)));
}
LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref,
@ -174,10 +163,9 @@ LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref,
LLVMMetadataRef ElementType,
LLVMMetadataRef Subscripts) {
DIBuilder *D = unwrap(Dref);
DICompositeType CT =
D->createArrayType(SizeInBits, AlignInBits, unwrap<MDType>(ElementType),
DIArray(unwrap<MDTuple>(Subscripts)));
return wrap(CT);
return wrap(D->createArrayType(SizeInBits, AlignInBits,
unwrap<DIType>(ElementType),
DINodeArray(unwrap<MDTuple>(Subscripts))));
}
LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref,
@ -185,17 +173,15 @@ LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref,
LLVMMetadataRef File, unsigned Line,
LLVMMetadataRef Context) {
DIBuilder *D = unwrap(Dref);
DIDerivedType DT = D->createTypedef(
unwrap<MDType>(Ty), Name, File ? unwrap<MDFile>(File) : nullptr, Line,
Context ? unwrap<MDScope>(Context) : nullptr);
return wrap(DT);
return wrap(D->createTypedef(unwrap<DIType>(Ty), Name,
File ? unwrap<DIFile>(File) : nullptr, Line,
Context ? unwrap<DIScope>(Context) : nullptr));
}
LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Dref,
int64_t Lo, int64_t Count) {
DIBuilder *D = unwrap(Dref);
DISubrange S = D->getOrCreateSubrange(Lo, Count);
return wrap(S);
return wrap(D->getOrCreateSubrange(Lo, Count));
}
LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref,
@ -204,7 +190,7 @@ LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref,
DIBuilder *D = unwrap(Dref);
Metadata **DataValue = unwrap(Data);
ArrayRef<Metadata *> Elements(DataValue, Length);
DIArray A = D->getOrCreateArray(Elements);
DINodeArray A = D->getOrCreateArray(Elements);
return wrap(A.get());
}
@ -214,15 +200,14 @@ LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref,
DIBuilder *D = unwrap(Dref);
Metadata **DataValue = unwrap(Data);
ArrayRef<Metadata *> Elements(DataValue, Length);
DITypeArray A = D->getOrCreateTypeArray(Elements);
DITypeRefArray A = D->getOrCreateTypeArray(Elements);
return wrap(A.get());
}
LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref,
int64_t *Addr, size_t Length) {
DIBuilder *D = unwrap(Dref);
DIExpression Expr = D->createExpression(ArrayRef<int64_t>(Addr, Length));
return wrap(Expr);
return wrap(D->createExpression(ArrayRef<int64_t>(Addr, Length)));
}
LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref,
@ -236,8 +221,8 @@ LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref,
DIBuilder *D = unwrap(Dref);
Instruction *Instr = D->insertDeclare(
unwrap(Storage), unwrap<MDLocalVariable>(VarInfo),
unwrap<MDExpression>(Expr), /* DebugLoc */ nullptr, unwrap(Block));
unwrap(Storage), unwrap<DILocalVariable>(VarInfo),
unwrap<DIExpression>(Expr), /* DebugLoc */ nullptr, unwrap(Block));
return wrap(Instr);
}
@ -252,7 +237,7 @@ LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef Dref,
DIBuilder *D = unwrap(Dref);
Instruction *Instr = D->insertDbgValueIntrinsic(
unwrap(Val), Offset, unwrap<MDLocalVariable>(VarInfo),
unwrap<MDExpression>(Expr), /* DebugLoc */ nullptr, unwrap(Block));
unwrap(Val), Offset, unwrap<DILocalVariable>(VarInfo),
unwrap<DIExpression>(Expr), /* DebugLoc */ nullptr, unwrap(Block));
return wrap(Instr);
}

View File

@ -526,11 +526,9 @@ else()
endif()
endif()
find_program(GOLD_EXECUTABLE NAMES ld.gold ld DOC "The gold linker")
if(GOLD_EXECUTABLE)
set(LLVM_BINUTILS_INCDIR "" CACHE PATH
"PATH to binutils/include containing plugin-api.h for gold plugin.")
endif()
find_program(GOLD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.gold ld.gold ${LLVM_DEFAULT_TARGET_TRIPLE}-ld ld DOC "The gold linker")
set(LLVM_BINUTILS_INCDIR "" CACHE PATH
"PATH to binutils/include containing plugin-api.h for gold plugin.")
if(APPLE)
find_program(LD64_EXECUTABLE NAMES ld DOC "The ld64 linker")

View File

@ -91,7 +91,7 @@ function(add_llvm_symbol_exports target_name export_file)
set(CAT "cat")
set(export_file_nativeslashes ${export_file})
if(WIN32 AND NOT CYGWIN)
if(WIN32 AND NOT CYGWIN AND NOT MSYS)
set(CAT "type")
# Convert ${export_file} to native format (backslashes) for "type"
# Does not use file(TO_NATIVE_PATH) as it doesn't create a native
@ -108,7 +108,7 @@ function(add_llvm_symbol_exports target_name export_file)
COMMENT "Creating export file for ${target_name}")
set(export_file_linker_flag "${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
if(MSVC)
set(export_file_linker_flag "/DEF:${export_file_linker_flag}")
set(export_file_linker_flag "/DEF:\"${export_file_linker_flag}\"")
endif()
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " ${export_file_linker_flag}")
@ -228,6 +228,76 @@ function(set_output_directory target bindir libdir)
endif()
endfunction()
# If on Windows and building with MSVC, add the resource script containing the
# VERSIONINFO data to the project. This embeds version resource information
# into the output .exe or .dll.
# TODO: Enable for MinGW Windows builds too.
#
function(add_windows_version_resource_file OUT_VAR)
set(sources ${ARGN})
if (MSVC)
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)
set(${OUT_VAR} ${sources} PARENT_SCOPE)
endfunction(add_windows_version_resource_file)
# set_windows_version_resource_properties(name resource_file...
# VERSION_MAJOR int
# Optional major version number (defaults to LLVM_VERSION_MAJOR)
# VERSION_MINOR int
# Optional minor version number (defaults to LLVM_VERSION_MINOR)
# VERSION_PATCHLEVEL int
# Optional patchlevel version number (defaults to LLVM_VERSION_PATCH)
# VERSION_STRING
# Optional version string (defaults to PACKAGE_VERSION)
# PRODUCT_NAME
# Optional product name string (defaults to "LLVM")
# )
function(set_windows_version_resource_properties name resource_file)
cmake_parse_arguments(ARG
""
"VERSION_MAJOR;VERSION_MINOR;VERSION_PATCHLEVEL;VERSION_STRING;PRODUCT_NAME"
""
${ARGN})
if (NOT DEFINED ARG_VERSION_MAJOR)
set(ARG_VERSION_MAJOR ${LLVM_VERSION_MAJOR})
endif()
if (NOT DEFINED ARG_VERSION_MINOR)
set(ARG_VERSION_MINOR ${LLVM_VERSION_MINOR})
endif()
if (NOT DEFINED ARG_VERSION_PATCHLEVEL)
set(ARG_VERSION_PATCHLEVEL ${LLVM_VERSION_PATCH})
endif()
if (NOT DEFINED ARG_VERSION_STRING)
set(ARG_VERSION_STRING ${PACKAGE_VERSION})
endif()
if (NOT DEFINED ARG_PRODUCT_NAME)
set(ARG_PRODUCT_NAME "LLVM")
endif()
set_property(SOURCE ${resource_file}
PROPERTY COMPILE_DEFINITIONS
"RC_VERSION_FIELD_1=${ARG_VERSION_MAJOR}"
"RC_VERSION_FIELD_2=${ARG_VERSION_MINOR}"
"RC_VERSION_FIELD_3=${ARG_VERSION_PATCHLEVEL}"
"RC_VERSION_FIELD_4=0"
"RC_FILE_VERSION=\"${ARG_VERSION_STRING}\""
"RC_INTERNAL_NAME=\"${name}\""
"RC_PRODUCT_NAME=\"${ARG_PRODUCT_NAME}\""
"RC_PRODUCT_VERSION=\"${ARG_VERSION_STRING}\"")
endfunction(set_windows_version_resource_properties)
# llvm_add_library(name sources...
# SHARED;STATIC
# STATIC by default w/o BUILD_SHARED_LIBS.
@ -316,10 +386,17 @@ function(llvm_add_library name)
if(ARG_MODULE)
add_library(${name} MODULE ${ALL_FILES})
elseif(ARG_SHARED)
add_windows_version_resource_file(ALL_FILES ${ALL_FILES})
add_library(${name} SHARED ${ALL_FILES})
else()
add_library(${name} STATIC ${ALL_FILES})
endif()
if(DEFINED windows_resource_file)
set_windows_version_resource_properties(${name} ${windows_resource_file})
set(windows_resource_file ${windows_resource_file} PARENT_SCOPE)
endif()
set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
llvm_update_compile_flags(${name})
add_link_opts( ${name} )
@ -482,11 +559,18 @@ endmacro(add_llvm_loadable_module name)
macro(add_llvm_executable name)
llvm_process_sources( ALL_FILES ${ARGN} )
add_windows_version_resource_file(ALL_FILES ${ALL_FILES})
if( EXCLUDE_FROM_ALL )
add_executable(${name} EXCLUDE_FROM_ALL ${ALL_FILES})
else()
add_executable(${name} ${ALL_FILES})
endif()
if(DEFINED windows_resource_file)
set_windows_version_resource_properties(${name} ${windows_resource_file})
endif()
llvm_update_compile_flags(${name})
add_link_opts( ${name} )

View File

@ -149,7 +149,7 @@ function(add_ocaml_library name)
"-I" "${LLVM_LIBRARY_DIR}/ocaml/"
"-dump" "${bin}/${name}.odoc"
${ocaml_pkgs} ${ocaml_inputs}
DEPENDS ${ocaml_inputs}
DEPENDS ${ocaml_inputs} ${ocaml_outputs}
COMMENT "Building OCaml documentation for ${name}"
VERBATIM)

View File

@ -88,6 +88,9 @@ elseif( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL "FORCE_ON" )
set( LLVM_ENABLE_ABI_BREAKING_CHECKS 1 )
elseif( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL "FORCE_OFF" )
# We don't need to do anything special to turn off ABI breaking checks.
elseif( NOT DEFINED LLVM_ABI_BREAKING_CHECKS )
# Treat LLVM_ABI_BREAKING_CHECKS like "FORCE_OFF" when it has not been
# defined.
else()
message(FATAL_ERROR "Unknown value for LLVM_ABI_BREAKING_CHECKS: \"${LLVM_ABI_BREAKING_CHECKS}\"!")
endif()
@ -304,7 +307,15 @@ if( MSVC )
-wd4611 # Suppress 'interaction between '_setjmp' and C++ object destruction is non-portable'
-wd4805 # Suppress 'unsafe mix of type <type> and type <type> in operation'
-wd4204 # Suppress 'nonstandard extension used : non-constant aggregate initializer'
# Idelly, we'd like this warning to be enabled, but MSVC 2013 doesn't
# support the 'aligned' attribute in the way that clang sources requires (for
# any code that uses the LLVM_ALIGNAS marco), so this is must be disabled to
# avoid unwanted alignment warnings.
# When we switch to requiring a version of MSVC that supports the 'alignas'
# specifier (MSVC 2015?) this warning can be re-enabled.
-wd4324 # Suppress 'structure was padded due to __declspec(align())'
# Promoted warnings.
-w14062 # Promote 'enumerator in switch of enum is not handled' to level 1 warning.
@ -334,6 +345,11 @@ if( MSVC )
append("${flag}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endforeach(flag)
# Disable sized deallocation if the flag is supported. MSVC fails to compile
# the operator new overload in User otherwise.
check_c_compiler_flag("/WX /Zc:sizedDealloc-" SUPPORTS_SIZED_DEALLOC)
append_if(SUPPORTS_SIZED_DEALLOC "/Zc:sizedDealloc-" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
if (LLVM_ENABLE_WARNINGS)
append("-Wall -W -Wno-unused-parameter -Wwrite-strings" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
@ -451,7 +467,7 @@ if(LLVM_USE_SANITIZER)
endif()
elseif (LLVM_USE_SANITIZER STREQUAL "Undefined")
append_common_sanitizer_flags()
append("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover"
append("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all"
CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
elseif (LLVM_USE_SANITIZER STREQUAL "Thread")
append_common_sanitizer_flags()
@ -459,7 +475,7 @@ if(LLVM_USE_SANITIZER)
elseif (LLVM_USE_SANITIZER STREQUAL "Address;Undefined" OR
LLVM_USE_SANITIZER STREQUAL "Undefined;Address")
append_common_sanitizer_flags()
append("-fsanitize=address,undefined -fno-sanitize=vptr,function -fno-sanitize-recover"
append("-fsanitize=address,undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all"
CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
else()
message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}")
@ -468,7 +484,7 @@ if(LLVM_USE_SANITIZER)
message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
endif()
if (LLVM_USE_SANITIZE_COVERAGE)
append("-fsanitize-coverage=4 -mllvm -sanitizer-coverage-8bit-counters=1" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
append("-fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
endif()

View File

@ -132,6 +132,41 @@ function(llvm_map_components_to_libnames out_libs)
# already processed
elseif( c STREQUAL "all" )
list(APPEND expanded_components ${LLVM_AVAILABLE_LIBS})
elseif( c STREQUAL "AllTargetsAsmPrinters" )
# Link all the asm printers from all the targets
foreach(t ${LLVM_TARGETS_TO_BUILD})
if( TARGET LLVM${t}AsmPrinter )
list(APPEND expanded_components "LLVM${t}AsmPrinter")
endif()
endforeach(t)
elseif( c STREQUAL "AllTargetsAsmParsers" )
# Link all the asm parsers from all the targets
foreach(t ${LLVM_TARGETS_TO_BUILD})
if( TARGET LLVM${t}AsmParser )
list(APPEND expanded_components "LLVM${t}AsmParser")
endif()
endforeach(t)
elseif( c STREQUAL "AllTargetsDescs" )
# Link all the descs from all the targets
foreach(t ${LLVM_TARGETS_TO_BUILD})
if( TARGET LLVM${t}Desc )
list(APPEND expanded_components "LLVM${t}Desc")
endif()
endforeach(t)
elseif( c STREQUAL "AllTargetsDisassemblers" )
# Link all the disassemblers from all the targets
foreach(t ${LLVM_TARGETS_TO_BUILD})
if( TARGET LLVM${t}Disassembler )
list(APPEND expanded_components "LLVM${t}Disassembler")
endif()
endforeach(t)
elseif( c STREQUAL "AllTargetsInfos" )
# Link all the infos from all the targets
foreach(t ${LLVM_TARGETS_TO_BUILD})
if( TARGET LLVM${t}Info )
list(APPEND expanded_components "LLVM${t}Info")
endif()
endforeach(t)
else( NOT idx LESS 0 )
# Canonize the component name:
string(TOUPPER "${c}" capitalized)

View File

@ -32,7 +32,7 @@ function(tablegen project ofn)
# The file in LLVM_TARGET_DEFINITIONS may be not in the current
# directory and local_tds may not contain it, so we must
# explicitly list it here:
DEPENDS ${${project}_TABLEGEN_EXE} ${local_tds} ${global_tds}
DEPENDS ${${project}_TABLEGEN_TARGET} ${local_tds} ${global_tds}
${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
COMMENT "Building ${ofn}..."
)
@ -90,10 +90,15 @@ macro(add_tablegen target project)
# Effective tblgen executable to be used:
set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN} PARENT_SCOPE)
set(${project}_TABLEGEN_TARGET ${${project}_TABLEGEN} PARENT_SCOPE)
if(LLVM_USE_HOST_TOOLS)
if( ${${project}_TABLEGEN} STREQUAL "${target}" )
set(${project}_TABLEGEN_EXE "${LLVM_NATIVE_BUILD}/bin/${target}")
if (NOT CMAKE_CONFIGURATION_TYPES)
set(${project}_TABLEGEN_EXE "${LLVM_NATIVE_BUILD}/bin/${target}")
else()
set(${project}_TABLEGEN_EXE "${LLVM_NATIVE_BUILD}/Release/bin/${target}")
endif()
set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN_EXE} PARENT_SCOPE)
add_custom_command(OUTPUT ${${project}_TABLEGEN_EXE}
@ -101,8 +106,8 @@ macro(add_tablegen target project)
DEPENDS CONFIGURE_LLVM_NATIVE ${target}
WORKING_DIRECTORY ${LLVM_NATIVE_BUILD}
COMMENT "Building native TableGen...")
add_custom_target(${project}NativeTableGen DEPENDS ${${project}_TABLEGEN_EXE})
add_dependencies(${project}NativeTableGen CONFIGURE_LLVM_NATIVE)
add_custom_target(${project}-tablegen-host DEPENDS ${${project}_TABLEGEN_EXE})
set(${project}_TABLEGEN_TARGET ${project}-tablegen-host PARENT_SCOPE)
endif()
endif()

51
configure vendored
View File

@ -1462,8 +1462,8 @@ Optional Features:
--enable-targets Build specific host targets: all or
target1,target2,... Valid targets are: host, x86,
x86_64, sparc, powerpc, arm64, arm, aarch64, mips,
hexagon, xcore, msp430, nvptx, systemz, r600, and
cpp (default=all)
hexagon, xcore, msp430, nvptx, systemz, r600, bpf,
and cpp (default=all)
--enable-experimental-targets
Build experimental host targets: disable or
target1,target2,... (default=disable)
@ -1495,6 +1495,8 @@ Optional Packages:
search for headers
--with-gcc-toolchain Directory where gcc is installed.
--with-default-sysroot Add --sysroot=<path> to all compiler invocations.
--with-clang-default-openmp-runtime
The default OpenMP runtime for Clang.
--with-binutils-include Specify path to binutils/include/ containing
plugin-api.h file for gold plugin.
--with-bug-report-url Specify the URL where bug reports should be
@ -2030,6 +2032,27 @@ echo "$as_me: error: Already configured in ${srcdir}" >&2;}
fi
fi
if test ${srcdir} == "." ; then
{ echo "$as_me:$LINENO: WARNING: **************************************************************************************" >&5
echo "$as_me: WARNING: **************************************************************************************" >&2;}
{ echo "$as_me:$LINENO: WARNING: * *" >&5
echo "$as_me: WARNING: * *" >&2;}
{ echo "$as_me:$LINENO: WARNING: * WARNING *" >&5
echo "$as_me: WARNING: * WARNING *" >&2;}
{ echo "$as_me:$LINENO: WARNING: * *" >&5
echo "$as_me: WARNING: * *" >&2;}
{ echo "$as_me:$LINENO: WARNING: * In-source builds are deprecated. *" >&5
echo "$as_me: WARNING: * In-source builds are deprecated. *" >&2;}
{ echo "$as_me:$LINENO: WARNING: * *" >&5
echo "$as_me: WARNING: * *" >&2;}
{ echo "$as_me:$LINENO: WARNING: * Please configure from a separate build directory! *" >&5
echo "$as_me: WARNING: * Please configure from a separate build directory! *" >&2;}
{ echo "$as_me:$LINENO: WARNING: * *" >&5
echo "$as_me: WARNING: * *" >&2;}
{ echo "$as_me:$LINENO: WARNING: **************************************************************************************" >&5
echo "$as_me: WARNING: **************************************************************************************" >&2;}
fi
: ${CFLAGS=}
: ${CXXFLAGS=}
@ -3605,8 +3628,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
{ { echo "$as_me:$LINENO: error: Selected compiler could not find or parse C++ standard library headers. Rerun with CC=c-compiler CXX=c++-compiler ./configure ..." >&5
echo "$as_me: error: Selected compiler could not find or parse C++ standard library headers. Rerun with CC=c-compiler CXX=c++-compiler ./configure ..." >&2;}
{ { echo "$as_me:$LINENO: error: Selected compiler could not find or parse C++ standard library headers. Rerun with CC=c-compiler CXX=c++-compiler LLVM_SRC_DIR/configure ..." >&5
echo "$as_me: error: Selected compiler could not find or parse C++ standard library headers. Rerun with CC=c-compiler CXX=c++-compiler LLVM_SRC_DIR/configure ..." >&2;}
{ (exit 1); exit 1; }; }
fi
@ -5605,7 +5628,7 @@ _ACEOF
fi
ALL_TARGETS="X86 Sparc PowerPC ARM AArch64 Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600"
ALL_TARGETS="X86 Sparc PowerPC ARM AArch64 Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ AMDGPU BPF"
ALL_TARGETS=$ALL_TARGETS
@ -5631,6 +5654,7 @@ case "$enableval" in
aarch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
arm64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
bpf) TARGETS_TO_BUILD="BPF $TARGETS_TO_BUILD" ;;
mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
mipsel) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
mips64) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
@ -5641,7 +5665,8 @@ case "$enableval" in
hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
amdgpu) TARGETS_TO_BUILD="AMDGPU $TARGETS_TO_BUILD" ;;
r600) TARGETS_TO_BUILD="AMDGPU $TARGETS_TO_BUILD" ;;
host) case "$llvm_cv_target_arch" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -5927,6 +5952,20 @@ _ACEOF
# Check whether --with-clang-default-openmp-runtime was given.
if test "${with_clang_default_openmp_runtime+set}" = set; then
withval=$with_clang_default_openmp_runtime;
else
withval="libgomp"
fi
cat >>confdefs.h <<_ACEOF
#define CLANG_DEFAULT_OPENMP_RUNTIME "$withval"
_ACEOF
# Check whether --with-binutils-include was given.
if test "${with_binutils_include+set}" = set; then
withval=$with_binutils_include;

View File

@ -1,11 +1,11 @@
============================
User Guide for R600 Back-end
============================
==============================
User Guide for AMDGPU Back-end
==============================
Introduction
============
The R600 back-end provides ISA code generation for AMD GPUs, starting with
The AMDGPU back-end provides ISA code generation for AMD GPUs, starting with
the R600 family up until the current Volcanic Islands (GCN Gen 3).
@ -14,7 +14,7 @@ Assembler
The assembler is currently considered experimental.
For syntax examples look in test/MC/R600.
For syntax examples look in test/MC/AMDGPU.
Below some of the currently supported features (modulo bugs). These
all apply to the Southern Islands ISA, Sea Islands and Volcanic Islands
@ -24,6 +24,11 @@ DS Instructions
---------------
All DS instructions are supported.
FLAT Instructions
------------------
These instructions are only present in the Sea Islands and Volcanic Islands
instruction set. All FLAT instructions are supported for these architectures
MUBUF Instructions
------------------
All non-atomic MUBUF instructions are supported.

View File

@ -115,3 +115,26 @@ CFG Modifications
Branch Weight Metatada is not proof against CFG changes. If terminator operands'
are changed some action should be taken. In other case some misoptimizations may
occur due to incorrent branch prediction information.
Function Entry Counts
=====================
To allow comparing different functions durint inter-procedural analysis and
optimization, ``MD_prof`` nodes can also be assigned to a function definition.
The first operand is a string indicating the name of the associated counter.
Currently, one counter is supported: "function_entry_count". This is a 64-bit
counter that indicates the number of times that this function was invoked (in
the case of instrumentation-based profiles). In the case of sampling-based
profiles, this counter is an approximation of how many times the function was
invoked.
For example, in the code below, the instrumentation for function foo()
indicates that it was called 2,590 times at runtime.
.. code-block:: llvm
define i32 @foo() !prof !1 {
ret i32 0
}
!1 = !{!"function_entry_count", i64 2590}

View File

@ -121,7 +121,7 @@ To configure LLVM, follow these steps:
.. code-block:: console
% SRC_ROOT/configure --prefix=/install/path [other options]
% $LLVM_SRC_DIR/configure --prefix=/install/path [other options]
Compiling the LLVM Suite Source Code
------------------------------------
@ -187,7 +187,7 @@ source code:
``gmake install``
Installs LLVM header files, libraries, tools, and documentation in a hierarchy
under ``$PREFIX``, specified with ``./configure --prefix=[dir]``, which
under ``$PREFIX``, specified with ``$LLVM_SRC_DIR/configure --prefix=[dir]``, which
defaults to ``/usr/local``.
``gmake -C runtime install-bytecode``
@ -240,7 +240,7 @@ There are some HTML documents that have not yet been converted to the new
system (which uses the easy-to-read and easy-to-write
`reStructuredText <http://sphinx-doc.org/rest.html>`_ plaintext markup
language).
The generated documentation is built in the ``SRC_ROOT/docs`` directory using
The generated documentation is built in the ``$LLVM_SRC_DIR/docs`` directory using
a special makefile.
For instructions on how to install Sphinx, see
`Sphinx Introduction for LLVM Developers
@ -250,7 +250,7 @@ HTML documentation by doing the following:
.. code-block:: console
$ cd SRC_ROOT/docs
$ cd $LLVM_SRC_DIR/docs
$ make -f Makefile.sphinx
This creates a ``_build/html`` sub-directory with all of the HTML files, not
@ -296,7 +296,7 @@ This is accomplished in the typical autoconf manner:
.. code-block:: console
% SRC_ROOT/configure
% $LLVM_SRC_DIR/configure
The LLVM build will place files underneath *OBJ_ROOT* in directories named after
the build type:

View File

@ -131,6 +131,12 @@ unlikely to be supported by our host compilers.
cannot synthesize them.
* Initializer lists: N2627_
* Delegating constructors: N1986_
* Default member initializers (non-static data member initializers): N2756_
* Only use these for scalar members that would otherwise be left
uninitialized. Non-scalar members generally have appropriate default
constructors, and MSVC 2013 has problems when braced initializer lists are
involved.
.. _N2118: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html
.. _N2439: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm
@ -156,7 +162,7 @@ unlikely to be supported by our host compilers.
.. _N2346: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm
.. _N2627: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm
.. _N1986: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
.. _MSVC-compatible RTTI: http://llvm.org/PR18951
.. _N2756: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2756.htm
The supported features in the C++11 standard libraries are less well tracked,
but also much greater. Most of the standard libraries implement most of C++11's
@ -241,8 +247,8 @@ tree. The standard header looks like this:
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file contains the declaration of the Instruction class, which is
/// the base class for all of the VM instructions.
/// This file contains the declaration of the Instruction class, which is the
/// base class for all of the VM instructions.
///
//===----------------------------------------------------------------------===//
@ -262,10 +268,10 @@ file is released under. This makes it perfectly clear what terms the source
code can be distributed under and should not be modified in any way.
The main body is a ``doxygen`` comment (identified by the ``///`` comment
marker instead of the usual ``//``) describing the purpose of the file. It
should have a ``\brief`` command that describes the file in one or two
sentences. Any additional information should be separated by a blank line. If
an algorithm is being implemented or something tricky is going on, a reference
marker instead of the usual ``//``) describing the purpose of the file. The
first sentence or a passage beginning with ``\brief`` is used as an abstract.
Any additional information should be separated by a blank line. If an
algorithm is being implemented or something tricky is going on, a reference
to the paper where it is published should be included, as well as any notes or
*gotchas* in the code to watch out for.
@ -314,10 +320,11 @@ Doxygen Use in Documentation Comments
Use the ``\file`` command to turn the standard file header into a file-level
comment.
Include descriptive ``\brief`` paragraphs for all public interfaces (public
classes, member and non-member functions). Explain API use and purpose in
``\brief`` paragraphs, don't just restate the information that can be inferred
from the API name. Put detailed discussion into separate paragraphs.
Include descriptive paragraphs for all public interfaces (public classes,
member and non-member functions). Don't just restate the information that can
be inferred from the API name. The first sentence or a paragraph beginning
with ``\brief`` is used as an abstract. Put detailed discussion into separate
paragraphs.
To refer to parameter names inside a paragraph, use the ``\p name`` command.
Don't use the ``\arg name`` command since it starts a new paragraph that
@ -337,8 +344,8 @@ A minimal documentation comment:
.. code-block:: c++
/// \brief Does foo and bar.
void fooBar(bool Baz);
/// Sets the xyzzy property to \p Baz.
void setXyzzy(bool Baz);
A documentation comment that uses all Doxygen features in a preferred way:
@ -395,10 +402,10 @@ Correct:
// In Something.h:
/// \brief An abstraction for some complicated thing.
/// An abstraction for some complicated thing.
class Something {
public:
/// \brief Does foo and bar.
/// Does foo and bar.
void fooBar();
};

View File

@ -200,9 +200,9 @@ For example, the following works like you'd expect:
.. code-block:: llvm
!0 = !MDLocation(line: 5, scope: !1, inlinedAt: !2)
!0 = !DILocation(line: 5, scope: !1, inlinedAt: !2)
; CHECK: !MDLocation(line: 5,
; CHECK: !DILocation(line: 5,
; CHECK-NOT: column:
; CHECK-SAME: scope: ![[SCOPE:[0-9]+]]

View File

@ -56,7 +56,7 @@ GENERAL OPTIONS
Search for :file:`{NAME}.cfg` and :file:`{NAME}.site.cfg` when searching for
test suites, instead of :file:`lit.cfg` and :file:`lit.site.cfg`.
.. option:: --param NAME, --param NAME=VALUE
.. option:: -D NAME, -D NAME=VALUE, --param NAME, --param NAME=VALUE
Add a user defined parameter ``NAME`` with the given ``VALUE`` (or the empty
string if not given). The meaning and use of these parameters is test suite

View File

@ -175,7 +175,7 @@ The :program:`llvm-cov show` command shows line by line coverage of a binary
*BIN* using the profile data *PROFILE*. It can optionally be filtered to only
show the coverage for the files listed in *SOURCES*.
To use :program:`llvm-cov show`, you need a program that's compiled with
To use :program:`llvm-cov show`, you need a program that is compiled with
instrumentation to emit profile and coverage data. To build such a program with
``clang`` use the ``-fprofile-instr-generate`` and ``-fcoverage-mapping``
flags. If linking with the ``clang`` driver, pass ``-fprofile-instr-generate``
@ -223,10 +223,10 @@ OPTIONS
.. option:: -arch=<name>
If the covered binary is a universal binary, select the architecture to use
when looking up the coverage map. Errors out if the supplied architecture is
not found in the universal binary, or if used on a non-universal binary of
a different architecture.
If the covered binary is a universal binary, select the architecture to use.
It is an error to specify an architecture that is not included in the
universal binary or to use an architecture that does not match a
non-universal binary.
.. option:: -name=<NAME>
@ -291,7 +291,7 @@ OPTIONS
.. option:: -arch=<name>
If the covered binary is a universal binary, select the architecture to use
when looking up the coverage map. Errors out if the supplied architecture is
not found in the universal binary, or if used on a non-universal binary of
a different architecture.
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.

View File

@ -49,6 +49,28 @@ OPTIONS
Specify the output file name. *Output* cannot be ``-`` as the resulting
indexed profile data can't be written to standard output.
.. option:: -instr (default)
Specify that the input profile is an instrumentation-based profile.
.. option:: -sample
Specify that the input profile is a sample-based profile. When using
sample-based profiles, the format of the generated file can be generated
in one of three ways:
.. option:: -binary (default)
Emit the profile using a binary encoding.
.. option:: -text
Emit the profile in text mode.
.. option:: -gcc
Emit the profile using GCC's gcov format (Not yet supported).
.. program:: llvm-profdata show
.. _profdata-show:
@ -95,6 +117,14 @@ OPTIONS
Specify the output file name. If *output* is ``-`` or it isn't specified,
then the output is sent to standard output.
.. option:: -instr (default)
Specify that the input profile is an instrumentation-based profile.
.. option:: -sample
Specify that the input profile is a sample-based profile.
EXIT STATUS
-----------

View File

@ -68,8 +68,8 @@ Other documents, collections, notes
* `PowerPC64 alignment of long doubles (from GCC) <http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00997.html>`_
* `Long branch stubs for powerpc64-linux (from binutils) <http://sources.redhat.com/ml/binutils/2002-04/msg00573.html>`_
R600
----
AMDGPU
------
* `AMD R6xx shader ISA <http://developer.amd.com/wordpress/media/2012/10/R600_Instruction_Set_Architecture.pdf>`_
* `AMD R7xx shader ISA <http://developer.amd.com/wordpress/media/2012/10/R700-Family_Instruction_Set_Architecture.pdf>`_

View File

@ -324,6 +324,11 @@ Below are some guidelines about the format of the message itself:
* Text formatting and spelling should follow the same rules as documentation
and in-code comments, ex. capitalization, full stop, etc.
* If the commit is a bug fix on top of another recently committed patch, or a
revert or reapply of a patch, include the svn revision number of the prior
related commit. This could be as simple as "Revert rNNNN because it caused
PR#".
For minor violations of these recommendations, the community normally favors
reminding the contributor of this policy over reverting. Minor corrections and
omissions can be handled by sending a reply to the commits mailing list.

View File

@ -102,7 +102,7 @@ grabbing the wrong linker/assembler/etc, there are two ways to fix it:
.. code-block:: console
% PATH=[the path without the bad program] ./configure ...
% PATH=[the path without the bad program] $LLVM_SRC_DIR/configure ...
This is still somewhat inconvenient, but it allows ``configure`` to do its
work without having to adjust your ``PATH`` permanently.

54
docs/FaultMaps.rst Normal file
View File

@ -0,0 +1,54 @@
==============================
FaultMaps and implicit checks
==============================
.. contents::
:local:
:depth: 2
Motivation
==========
Code generated by managed language runtimes tend to have checks that
are required for safety but never fail in practice. In such cases, it
is profitable to make the non-failing case cheaper even if it makes
the failing case significantly more expensive. This asymmetry can be
exploited by folding such safety checks into operations that can be
made to fault reliably if the check would have failed, and recovering
from such a fault by using a signal handler.
For example, Java requires null checks on objects before they are read
from or written to. If the object is ``null`` then a
``NullPointerException`` has to be thrown, interrupting normal
execution. In practice, however, dereferencing a ``null`` pointer is
extremely rare in well-behaved Java programs, and typically the null
check can be folded into a nearby memory operation that operates on
the same memory location.
The Fault Map Section
=====================
Information about implicit checks generated by LLVM are put in a
special "fault map" section. On Darwin this section is named
``__llvm_faultmaps``.
The format of this section is
.. code-block:: none
Header {
uint8 : Fault Map Version (current version is 1)
uint8 : Reserved (expected to be 0)
uint16 : Reserved (expected to be 0)
}
uint32 : NumFunctions
FunctionInfo[NumFunctions] {
uint64 : FunctionAddress
uint32 : NumFaultingPCs
uint32 : Reserved (expected to be 0)
FunctionFaultInfo[NumFaultingPCs] {
uint32 : FaultKind = FaultMaps::FaultingLoad (only legal value currently)
uint32 : FaultingPCOffset
uint32 : handlerPCOffset
}
}

View File

@ -55,8 +55,7 @@ Other things to consider
#. Add nsw/nuw flags as appropriate. Reasoning about overflow is
generally hard for an optimizer so providing these facts from the frontend
can be very impactful. For languages which need overflow semantics,
consider using the :ref:`overflow intrinsics <int_overflow>`.
can be very impactful.
#. Use fast-math flags on floating point operations if legal. If you don't
need strict IEEE floating point semantics, there are a number of additional
@ -142,6 +141,29 @@ Other things to consider
perform badly with confronted with such structures. The only exception to
this guidance is that a unified return block with high in-degree is fine.
#. When checking a value against a constant, emit the check using a consistent
comparison type. The GVN pass *will* optimize redundant equalities even if
the type of comparison is inverted, but GVN only runs late in the pipeline.
As a result, you may miss the opportunity to run other important
optimizations. Improvements to EarlyCSE to remove this issue are tracked in
Bug 23333.
#. Avoid using arithmetic intrinsics unless you are *required* by your source
language specification to emit a particular code sequence. The optimizer
is quite good at reasoning about general control flow and arithmetic, it is
not anywhere near as strong at reasoning about the various intrinsics. If
profitable for code generation purposes, the optimizer will likely form the
intrinsics itself late in the optimization pipeline. It is *very* rarely
profitable to emit these directly in the language frontend. This item
explicitly includes the use of the :ref:`overflow intrinsics <int_overflow>`.
#. Avoid using the :ref:`assume intrinsic <int_assume>` until you've
established that a) there's no other way to express the given fact and b)
that fact is critical for optimization purposes. Assumes are a great
prototyping mechanism, but they can have negative effects on both compile
time and optimization effectiveness. The former is fixable with enough
effort, but the later is fairly fundamental to their designed purpose.
p.s. If you want to help improve this document, patches expanding any of the
above items into standalone sections of their own with a more complete
discussion would be very welcome.

View File

@ -494,6 +494,7 @@ a ``gcroot`` strategy.
As there names imply, the binary format produced is intended to model that
used by the Erlang and OCaml compilers respectively.
.. _statepoint_example_gc:
The Statepoint Example GC
-------------------------
@ -517,6 +518,28 @@ The stack map format generated by this GC strategy can be found in the
<statepoint-stackmap-format>`. This format is intended to be the standard
format supported by LLVM going forward.
The CoreCLR GC
-------------------------
.. code-block:: c++
F.setGC("coreclr");
This GC leverages the ``gc.statepoint`` mechanism to support the
`CoreCLR <https://github.com/dotnet/coreclr>`__ runtime.
Support for this GC strategy is a work in progress. This strategy will
differ from
:ref:`statepoint-example GC<statepoint_example_gc>` strategy in
certain aspects like:
* Base-pointers of interior pointers are not explicitly
tracked and reported.
* A different format is used for encoding stack maps.
* Safe-point polls are only needed before loop-back edges
and before tail-calls (not needed at function-entry).
Custom GC Strategies
====================

View File

@ -711,7 +711,7 @@ used by people developing LLVM.
| | as ``LLVM_ALL_TARGETS``, and can be set to include |
| | out-of-tree targets. The default value includes: |
| | ``AArch64, ARM, CppBackend, Hexagon, |
| | Mips, MSP430, NVPTX, PowerPC, R600, Sparc, |
| | Mips, MSP430, NVPTX, PowerPC, AMDGPU, Sparc, |
| | SystemZ, X86, XCore``. |
+-------------------------+----------------------------------------------------+
| LLVM_ENABLE_DOXYGEN | Build doxygen-based documentation from the source |

View File

@ -40,7 +40,7 @@ on the ARMv6 and ARMv7 architectures and may be inapplicable to older chips.
.. code-block:: bash
./configure --build=armv7l-unknown-linux-gnueabihf \
../$LLVM_SRC_DIR/configure --build=armv7l-unknown-linux-gnueabihf \
--host=armv7l-unknown-linux-gnueabihf \
--target=armv7l-unknown-linux-gnueabihf --with-cpu=cortex-a9 \
--with-float=hard --with-abi=aapcs-vfp --with-fpu=neon \

View File

@ -834,6 +834,11 @@ Named metadata is a collection of metadata. :ref:`Metadata
nodes <metadata>` (but not metadata strings) are the only valid
operands for a named metadata.
#. Named metadata are represented as a string of characters with the
metadata prefix. The rules for metadata names are the same as for
identifiers, but quoted names are not allowed. ``"\xx"`` type escapes
are still valid, which allows any character to be part of a name.
Syntax::
; Some unnamed metadata nodes, which are referenced by the named metadata.
@ -1196,6 +1201,13 @@ example:
computing edge weights, basic blocks post-dominated by a cold
function call are also considered to be cold; and, thus, given low
weight.
``convergent``
This attribute indicates that the callee is dependent on a convergent
thread execution pattern under certain parallel execution models.
Transformations that are execution model agnostic may only move or
tranform this call if the final location is control equivalent to its
original position in the program, where control equivalence is defined as
A dominates B and B post-dominates A, or vice versa.
``inlinehint``
This attribute indicates that the source code contained a hint that
inlining this function is desirable (such as the "inline" keyword in
@ -1307,6 +1319,15 @@ example:
``setjmp`` is an example of such a function. The compiler disables
some optimizations (like tail calls) in the caller of these
functions.
``safestack``
This attribute indicates that
`SafeStack <http://clang.llvm.org/docs/SafeStack.html>`_
protection is enabled for this function.
If a function that has a ``safestack`` attribute is inlined into a
function that doesn't have a ``safestack`` attribute or which has an
``ssp``, ``sspstrong`` or ``sspreq`` attribute, then the resulting
function will have a ``safestack`` attribute.
``sanitize_address``
This attribute indicates that AddressSanitizer checks
(dynamic address safety analysis) are enabled for this function.
@ -2922,12 +2943,12 @@ order.
These aren't inherently debug info centric, but currently all the specialized
metadata nodes are related to debug info.
.. _MDCompileUnit:
.. _DICompileUnit:
MDCompileUnit
DICompileUnit
"""""""""""""
``MDCompileUnit`` nodes represent a compile unit. The ``enums:``,
``DICompileUnit`` nodes represent a compile unit. The ``enums:``,
``retainedTypes:``, ``subprograms:``, ``globals:`` and ``imports:`` fields are
tuples containing the debug info to be emitted along with the compile unit,
regardless of code optimizations (some nodes are only emitted if there are
@ -2935,7 +2956,7 @@ references to them from instructions).
.. code-block:: llvm
!0 = !MDCompileUnit(language: DW_LANG_C99, file: !1, producer: "clang",
!0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang",
isOptimized: true, flags: "-O2", runtimeVersion: 2,
splitDebugFilename: "abc.debug", emissionKind: 1,
enums: !2, retainedTypes: !3, subprograms: !4,
@ -2947,33 +2968,33 @@ These descriptors are collected by a named metadata ``!llvm.dbg.cu``. They
keep track of subprograms, global variables, type information, and imported
entities (declarations and namespaces).
.. _MDFile:
.. _DIFile:
MDFile
DIFile
""""""
``MDFile`` nodes represent files. The ``filename:`` can include slashes.
``DIFile`` nodes represent files. The ``filename:`` can include slashes.
.. code-block:: llvm
!0 = !MDFile(filename: "path/to/file", directory: "/path/to/dir")
!0 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
Files are sometimes used in ``scope:`` fields, and are the only valid target
for ``file:`` fields.
.. _MDLocation:
.. _DIBasicType:
MDBasicType
DIBasicType
"""""""""""
``MDBasicType`` nodes represent primitive types, such as ``int``, ``bool`` and
``DIBasicType`` nodes represent primitive types, such as ``int``, ``bool`` and
``float``. ``tag:`` defaults to ``DW_TAG_base_type``.
.. code-block:: llvm
!0 = !MDBasicType(name: "unsigned char", size: 8, align: 8,
!0 = !DIBasicType(name: "unsigned char", size: 8, align: 8,
encoding: DW_ATE_unsigned_char)
!1 = !MDBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)")
!1 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)")
The ``encoding:`` describes the details of the type. Usually it's one of the
following:
@ -2988,12 +3009,12 @@ following:
DW_ATE_unsigned = 7
DW_ATE_unsigned_char = 8
.. _MDSubroutineType:
.. _DISubroutineType:
MDSubroutineType
DISubroutineType
""""""""""""""""
``MDSubroutineType`` nodes represent subroutine types. Their ``types:`` field
``DISubroutineType`` nodes represent subroutine types. Their ``types:`` field
refers to a tuple; the first operand is the return type, while the rest are the
types of the formal arguments in order. If the first operand is ``null``, that
represents a function with no return value (such as ``void foo() {}`` in C++).
@ -3002,21 +3023,21 @@ represents a function with no return value (such as ``void foo() {}`` in C++).
!0 = !BasicType(name: "int", size: 32, align: 32, DW_ATE_signed)
!1 = !BasicType(name: "char", size: 8, align: 8, DW_ATE_signed_char)
!2 = !MDSubroutineType(types: !{null, !0, !1}) ; void (int, char)
!2 = !DISubroutineType(types: !{null, !0, !1}) ; void (int, char)
.. _MDDerivedType:
.. _DIDerivedType:
MDDerivedType
DIDerivedType
"""""""""""""
``MDDerivedType`` nodes represent types derived from other types, such as
``DIDerivedType`` nodes represent types derived from other types, such as
qualified types.
.. code-block:: llvm
!0 = !MDBasicType(name: "unsigned char", size: 8, align: 8,
!0 = !DIBasicType(name: "unsigned char", size: 8, align: 8,
encoding: DW_ATE_unsigned_char)
!1 = !MDDerivedType(tag: DW_TAG_pointer_type, baseType: !0, size: 32,
!1 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !0, size: 32,
align: 32)
The following ``tag:`` values are valid:
@ -3034,7 +3055,7 @@ The following ``tag:`` values are valid:
DW_TAG_restrict_type = 55
``DW_TAG_member`` is used to define a member of a :ref:`composite type
<MDCompositeType>` or :ref:`subprogram <MDSubprogram>`. The type of the member
<DICompositeType>` or :ref:`subprogram <DISubprogram>`. The type of the member
is the ``baseType:``. The ``offset:`` is the member's bit offset.
``DW_TAG_formal_parameter`` is used to define a member which is a formal
argument of a subprogram.
@ -3047,12 +3068,12 @@ argument of a subprogram.
Note that the ``void *`` type is expressed as a type derived from NULL.
.. _MDCompositeType:
.. _DICompositeType:
MDCompositeType
DICompositeType
"""""""""""""""
``MDCompositeType`` nodes represent types composed of other types, like
``DICompositeType`` nodes represent types composed of other types, like
structures and unions. ``elements:`` points to a tuple of the composed types.
If the source language supports ODR, the ``identifier:`` field gives the unique
@ -3062,10 +3083,10 @@ can refer to composite types indirectly via a :ref:`metadata string
.. code-block:: llvm
!0 = !MDEnumerator(name: "SixKind", value: 7)
!1 = !MDEnumerator(name: "SevenKind", value: 7)
!2 = !MDEnumerator(name: "NegEightKind", value: -8)
!3 = !MDCompositeType(tag: DW_TAG_enumeration_type, name: "Enum", file: !12,
!0 = !DIEnumerator(name: "SixKind", value: 7)
!1 = !DIEnumerator(name: "SevenKind", value: 7)
!2 = !DIEnumerator(name: "NegEightKind", value: -8)
!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum", file: !12,
line: 2, size: 32, align: 32, identifier: "_M4Enum",
elements: !{!0, !1, !2})
@ -3083,108 +3104,108 @@ The following ``tag:`` values are valid:
For ``DW_TAG_array_type``, the ``elements:`` should be :ref:`subrange
descriptors <MDSubrange>`, each representing the range of subscripts at that
descriptors <DISubrange>`, each representing the range of subscripts at that
level of indexing. The ``DIFlagVector`` flag to ``flags:`` indicates that an
array type is a native packed vector.
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
descriptors <MDEnumerator>`, each representing the definition of an enumeration
descriptors <DIEnumerator>`, each representing the definition of an enumeration
value for the set. All enumeration type descriptors are collected in the
``enums:`` field of the :ref:`compile unit <MDCompileUnit>`.
``enums:`` field of the :ref:`compile unit <DICompileUnit>`.
For ``DW_TAG_structure_type``, ``DW_TAG_class_type``, and
``DW_TAG_union_type``, the ``elements:`` should be :ref:`derived types
<MDDerivedType>` with ``tag: DW_TAG_member`` or ``tag: DW_TAG_inheritance``.
<DIDerivedType>` with ``tag: DW_TAG_member`` or ``tag: DW_TAG_inheritance``.
.. _MDSubrange:
.. _DISubrange:
MDSubrange
DISubrange
""""""""""
``MDSubrange`` nodes are the elements for ``DW_TAG_array_type`` variants of
:ref:`MDCompositeType`. ``count: -1`` indicates an empty array.
``DISubrange`` nodes are the elements for ``DW_TAG_array_type`` variants of
:ref:`DICompositeType`. ``count: -1`` indicates an empty array.
.. code-block:: llvm
!0 = !MDSubrange(count: 5, lowerBound: 0) ; array counting from 0
!1 = !MDSubrange(count: 5, lowerBound: 1) ; array counting from 1
!2 = !MDSubrange(count: -1) ; empty array.
!0 = !DISubrange(count: 5, lowerBound: 0) ; array counting from 0
!1 = !DISubrange(count: 5, lowerBound: 1) ; array counting from 1
!2 = !DISubrange(count: -1) ; empty array.
.. _MDEnumerator:
.. _DIEnumerator:
MDEnumerator
DIEnumerator
""""""""""""
``MDEnumerator`` nodes are the elements for ``DW_TAG_enumeration_type``
variants of :ref:`MDCompositeType`.
``DIEnumerator`` nodes are the elements for ``DW_TAG_enumeration_type``
variants of :ref:`DICompositeType`.
.. code-block:: llvm
!0 = !MDEnumerator(name: "SixKind", value: 7)
!1 = !MDEnumerator(name: "SevenKind", value: 7)
!2 = !MDEnumerator(name: "NegEightKind", value: -8)
!0 = !DIEnumerator(name: "SixKind", value: 7)
!1 = !DIEnumerator(name: "SevenKind", value: 7)
!2 = !DIEnumerator(name: "NegEightKind", value: -8)
MDTemplateTypeParameter
DITemplateTypeParameter
"""""""""""""""""""""""
``MDTemplateTypeParameter`` nodes represent type parameters to generic source
language constructs. They are used (optionally) in :ref:`MDCompositeType` and
:ref:`MDSubprogram` ``templateParams:`` fields.
``DITemplateTypeParameter`` nodes represent type parameters to generic source
language constructs. They are used (optionally) in :ref:`DICompositeType` and
:ref:`DISubprogram` ``templateParams:`` fields.
.. code-block:: llvm
!0 = !MDTemplateTypeParameter(name: "Ty", type: !1)
!0 = !DITemplateTypeParameter(name: "Ty", type: !1)
MDTemplateValueParameter
DITemplateValueParameter
""""""""""""""""""""""""
``MDTemplateValueParameter`` nodes represent value parameters to generic source
``DITemplateValueParameter`` nodes represent value parameters to generic source
language constructs. ``tag:`` defaults to ``DW_TAG_template_value_parameter``,
but if specified can also be set to ``DW_TAG_GNU_template_template_param`` or
``DW_TAG_GNU_template_param_pack``. They are used (optionally) in
:ref:`MDCompositeType` and :ref:`MDSubprogram` ``templateParams:`` fields.
:ref:`DICompositeType` and :ref:`DISubprogram` ``templateParams:`` fields.
.. code-block:: llvm
!0 = !MDTemplateValueParameter(name: "Ty", type: !1, value: i32 7)
!0 = !DITemplateValueParameter(name: "Ty", type: !1, value: i32 7)
MDNamespace
DINamespace
"""""""""""
``MDNamespace`` nodes represent namespaces in the source language.
``DINamespace`` nodes represent namespaces in the source language.
.. code-block:: llvm
!0 = !MDNamespace(name: "myawesomeproject", scope: !1, file: !2, line: 7)
!0 = !DINamespace(name: "myawesomeproject", scope: !1, file: !2, line: 7)
MDGlobalVariable
DIGlobalVariable
""""""""""""""""
``MDGlobalVariable`` nodes represent global variables in the source language.
``DIGlobalVariable`` nodes represent global variables in the source language.
.. code-block:: llvm
!0 = !MDGlobalVariable(name: "foo", linkageName: "foo", scope: !1,
!0 = !DIGlobalVariable(name: "foo", linkageName: "foo", scope: !1,
file: !2, line: 7, type: !3, isLocal: true,
isDefinition: false, variable: i32* @foo,
declaration: !4)
All global variables should be referenced by the `globals:` field of a
:ref:`compile unit <MDCompileUnit>`.
:ref:`compile unit <DICompileUnit>`.
.. _MDSubprogram:
.. _DISubprogram:
MDSubprogram
DISubprogram
""""""""""""
``MDSubprogram`` nodes represent functions from the source language. The
``variables:`` field points at :ref:`variables <MDLocalVariable>` that must be
``DISubprogram`` nodes represent functions from the source language. The
``variables:`` field points at :ref:`variables <DILocalVariable>` that must be
retained, even if their IR counterparts are optimized out of the IR. The
``type:`` field must point at an :ref:`MDSubroutineType`.
``type:`` field must point at an :ref:`DISubroutineType`.
.. code-block:: llvm
!0 = !MDSubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
!0 = !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
file: !2, line: 7, type: !3, isLocal: true,
isDefinition: false, scopeLine: 8, containingType: !4,
virtuality: DW_VIRTUALITY_pure_virtual, virtualIndex: 10,
@ -3192,76 +3213,78 @@ retained, even if their IR counterparts are optimized out of the IR. The
function: void ()* @_Z3foov,
templateParams: !5, declaration: !6, variables: !7)
.. _MDLexicalBlock:
.. _DILexicalBlock:
MDLexicalBlock
DILexicalBlock
""""""""""""""
``MDLexicalBlock`` nodes describe nested blocks within a :ref:`subprogram
<MDSubprogram>`. The line number and column numbers are used to dinstinguish
``DILexicalBlock`` nodes describe nested blocks within a :ref:`subprogram
<DISubprogram>`. The line number and column numbers are used to dinstinguish
two lexical blocks at same depth. They are valid targets for ``scope:``
fields.
.. code-block:: llvm
!0 = distinct !MDLexicalBlock(scope: !1, file: !2, line: 7, column: 35)
!0 = distinct !DILexicalBlock(scope: !1, file: !2, line: 7, column: 35)
Usually lexical blocks are ``distinct`` to prevent node merging based on
operands.
.. _MDLexicalBlockFile:
.. _DILexicalBlockFile:
MDLexicalBlockFile
DILexicalBlockFile
""""""""""""""""""
``MDLexicalBlockFile`` nodes are used to discriminate between sections of a
:ref:`lexical block <MDLexicalBlock>`. The ``file:`` field can be changed to
``DILexicalBlockFile`` nodes are used to discriminate between sections of a
:ref:`lexical block <DILexicalBlock>`. The ``file:`` field can be changed to
indicate textual inclusion, or the ``discriminator:`` field can be used to
discriminate between control flow within a single block in the source language.
.. code-block:: llvm
!0 = !MDLexicalBlock(scope: !3, file: !4, line: 7, column: 35)
!1 = !MDLexicalBlockFile(scope: !0, file: !4, discriminator: 0)
!2 = !MDLexicalBlockFile(scope: !0, file: !4, discriminator: 1)
!0 = !DILexicalBlock(scope: !3, file: !4, line: 7, column: 35)
!1 = !DILexicalBlockFile(scope: !0, file: !4, discriminator: 0)
!2 = !DILexicalBlockFile(scope: !0, file: !4, discriminator: 1)
MDLocation
.. _DILocation:
DILocation
""""""""""
``MDLocation`` nodes represent source debug locations. The ``scope:`` field is
mandatory, and points at an :ref:`MDLexicalBlockFile`, an
:ref:`MDLexicalBlock`, or an :ref:`MDSubprogram`.
``DILocation`` nodes represent source debug locations. The ``scope:`` field is
mandatory, and points at an :ref:`DILexicalBlockFile`, an
:ref:`DILexicalBlock`, or an :ref:`DISubprogram`.
.. code-block:: llvm
!0 = !MDLocation(line: 2900, column: 42, scope: !1, inlinedAt: !2)
!0 = !DILocation(line: 2900, column: 42, scope: !1, inlinedAt: !2)
.. _MDLocalVariable:
.. _DILocalVariable:
MDLocalVariable
DILocalVariable
"""""""""""""""
``MDLocalVariable`` nodes represent local variables in the source language.
``DILocalVariable`` nodes represent local variables in the source language.
Instead of ``DW_TAG_variable``, they use LLVM-specific fake tags to
discriminate between local variables (``DW_TAG_auto_variable``) and subprogram
arguments (``DW_TAG_arg_variable``). In the latter case, the ``arg:`` field
specifies the argument position, and this variable will be included in the
``variables:`` field of its :ref:`MDSubprogram`.
``variables:`` field of its :ref:`DISubprogram`.
.. code-block:: llvm
!0 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 0,
!0 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg: 0,
scope: !3, file: !2, line: 7, type: !3,
flags: DIFlagArtificial)
!1 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "x", arg: 1,
!1 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "x", arg: 1,
scope: !4, file: !2, line: 7, type: !3)
!1 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "y",
!1 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "y",
scope: !5, file: !2, line: 7, type: !3)
MDExpression
DIExpression
""""""""""""
``MDExpression`` nodes represent DWARF expression sequences. They are used in
``DIExpression`` nodes represent DWARF expression sequences. They are used in
:ref:`debug intrinsics<dbg_intrinsics>` (such as ``llvm.dbg.declare``) to
describe how the referenced LLVM variable relates to the source language
variable.
@ -3275,30 +3298,30 @@ The current supported vocabulary is limited:
.. code-block:: llvm
!0 = !MDExpression(DW_OP_deref)
!1 = !MDExpression(DW_OP_plus, 3)
!2 = !MDExpression(DW_OP_bit_piece, 3, 7)
!3 = !MDExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_bit_piece, 3, 7)
!0 = !DIExpression(DW_OP_deref)
!1 = !DIExpression(DW_OP_plus, 3)
!2 = !DIExpression(DW_OP_bit_piece, 3, 7)
!3 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_bit_piece, 3, 7)
MDObjCProperty
DIObjCProperty
""""""""""""""
``MDObjCProperty`` nodes represent Objective-C property nodes.
``DIObjCProperty`` nodes represent Objective-C property nodes.
.. code-block:: llvm
!3 = !MDObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo",
!3 = !DIObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo",
getter: "getFoo", attributes: 7, type: !2)
MDImportedEntity
DIImportedEntity
""""""""""""""""
``MDImportedEntity`` nodes represent entities (such as modules) imported into a
``DIImportedEntity`` nodes represent entities (such as modules) imported into a
compile unit.
.. code-block:: llvm
!2 = !MDImportedEntity(tag: DW_TAG_imported_module, name: "foo", scope: !0,
!2 = !DIImportedEntity(tag: DW_TAG_imported_module, name: "foo", scope: !0,
entity: !1, line: 7)
'``tbaa``' Metadata
@ -3423,7 +3446,7 @@ For example,
%2 = load float, float* %c, align 4, !alias.scope !5
store float %2, float* %arrayidx.i2, align 4, !noalias !6
; These two instructions don't alias (for domain !0, the set of scopes in
; These two instructions may alias (for domain !0, the set of scopes in
; the !noalias list is not a superset of, or equal to, the scopes in the
; !alias.scope list):
%2 = load float, float* %c, align 4, !alias.scope !6
@ -5060,7 +5083,7 @@ Semantics:
The value produced is ``op1`` \* 2\ :sup:`op2` mod 2\ :sup:`n`,
where ``n`` is the width of the result. If ``op2`` is (statically or
dynamically) negative or equal to or larger than the number of bits in
dynamically) equal to or larger than the number of bits in
``op1``, the result is undefined. If the arguments are vectors, each
vector element of ``op1`` is shifted by the corresponding shift amount
in ``op2``.
@ -5656,7 +5679,7 @@ Syntax:
::
<result> = load [volatile] <ty>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>][, !nonnull !<index>]
<result> = load [volatile] <ty>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>][, !invariant.load !<index>][, !nonnull !<index>][, !dereferenceable !<index>][, !dereferenceable_or_null !<index>]
<result> = load atomic [volatile] <ty>* <pointer> [singlethread] <ordering>, align <alignment>
!<index> = !{ i32 1 }
@ -5721,6 +5744,25 @@ never be null. This is analogous to the ''nonnull'' attribute
on parameters and return values. This metadata can only be applied
to loads of a pointer type.
The optional ``!dereferenceable`` metadata must reference a single
metadata name ``<index>`` corresponding to a metadata node with one ``i64``
entry. The existence of the ``!dereferenceable`` metadata on the instruction
tells the optimizer that the value loaded is known to be dereferenceable.
The number of bytes known to be dereferenceable is specified by the integer
value in the metadata node. This is analogous to the ''dereferenceable''
attribute on parameters and return values. This metadata can only be applied
to loads of a pointer type.
The optional ``!dereferenceable_or_null`` metadata must reference a single
metadata name ``<index>`` corresponding to a metadata node with one ``i64``
entry. The existence of the ``!dereferenceable_or_null`` metadata on the
instruction tells the optimizer that the value loaded is known to be either
dereferenceable or null.
The number of bytes known to be dereferenceable is specified by the integer
value in the metadata node. This is analogous to the ''dereferenceable_or_null''
attribute on parameters and return values. This metadata can only be applied
to loads of a pointer type.
Semantics:
""""""""""
@ -9754,6 +9796,8 @@ intrinsic returns the executable address corresponding to ``tramp``
after performing the required machine specific adjustments. The pointer
returned can then be :ref:`bitcast and executed <int_trampoline>`.
.. _int_mload_mstore:
Masked Vector Load and Store Intrinsics
---------------------------------------
@ -9776,13 +9820,13 @@ This is an overloaded intrinsic. The loaded data is a vector of any integer or f
Overview:
"""""""""
Reads a vector from memory according to the provided mask. The mask holds a bit for each vector lane, and is used to prevent memory accesses to the masked-off lanes. The masked-off lanes in the result vector are taken from the corresponding lanes in the passthru operand.
Reads a vector from memory according to the provided mask. The mask holds a bit for each vector lane, and is used to prevent memory accesses to the masked-off lanes. The masked-off lanes in the result vector are taken from the corresponding lanes of the '``passthru``' operand.
Arguments:
""""""""""
The first operand is the base pointer for the load. The second operand is the alignment of the source location. It must be a constant integer value. The third operand, mask, is a vector of boolean 'i1' values with the same number of elements as the return type. The fourth is a pass-through value that is used to fill the masked-off lanes of the result. The return type, underlying type of the base pointer and the type of passthru operand are the same vector types.
The first operand is the base pointer for the load. The second operand is the alignment of the source location. It must be a constant integer value. The third operand, mask, is a vector of boolean values with the same number of elements as the return type. The fourth is a pass-through value that is used to fill the masked-off lanes of the result. The return type, underlying type of the base pointer and the type of the '``passthru``' operand are the same vector types.
Semantics:
@ -9841,6 +9885,115 @@ The result of this operation is equivalent to a load-modify-store sequence. Howe
store <16 x float> %res, <16 x float>* %ptr, align 4
Masked Vector Gather and Scatter Intrinsics
-------------------------------------------
LLVM provides intrinsics for vector gather and scatter operations. They are similar to :ref:`Masked Vector Load and Store <int_mload_mstore>`, except they are designed for arbitrary memory accesses, rather than sequential memory accesses. Gather and scatter also employ a mask operand, which holds one bit per vector element, switching the associated vector lane on or off. The memory addresses corresponding to the "off" lanes are not accessed. When all bits are off, no memory is accessed.
.. _int_mgather:
'``llvm.masked.gather.*``' Intrinsics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
"""""""
This is an overloaded intrinsic. The loaded data are multiple scalar values of any integer or floating point data type gathered together into one vector.
::
declare <16 x float> @llvm.masked.gather.v16f32 (<16 x float*> <ptrs>, i32 <alignment>, <16 x i1> <mask>, <16 x float> <passthru>)
declare <2 x double> @llvm.masked.gather.v2f64 (<2 x double*> <ptrs>, i32 <alignment>, <2 x i1> <mask>, <2 x double> <passthru>)
Overview:
"""""""""
Reads scalar values from arbitrary memory locations and gathers them into one vector. The memory locations are provided in the vector of pointers '``ptrs``'. The memory is accessed according to the provided mask. The mask holds a bit for each vector lane, and is used to prevent memory accesses to the masked-off lanes. The masked-off lanes in the result vector are taken from the corresponding lanes of the '``passthru``' operand.
Arguments:
""""""""""
The first operand is a vector of pointers which holds all memory addresses to read. The second operand is an alignment of the source addresses. It must be a constant integer value. The third operand, mask, is a vector of boolean values with the same number of elements as the return type. The fourth is a pass-through value that is used to fill the masked-off lanes of the result. The return type, underlying type of the vector of pointers and the type of the '``passthru``' operand are the same vector types.
Semantics:
""""""""""
The '``llvm.masked.gather``' intrinsic is designed for conditional reading of multiple scalar values from arbitrary memory locations in a single IR operation. It is useful for targets that support vector masked gathers and allows vectorizing basic blocks with data and control divergence. Other targets may support this intrinsic differently, for example by lowering it into a sequence of scalar load operations.
The semantics of this operation are equivalent to a sequence of conditional scalar loads with subsequent gathering all loaded values into a single vector. The mask restricts memory access to certain lanes and facilitates vectorization of predicated basic blocks.
::
%res = call <4 x double> @llvm.masked.gather.v4f64 (<4 x double*> %ptrs, i32 8, <4 x i1>%mask, <4 x double> <true, true, true, true>)
;; The gather with all-true mask is equivalent to the following instruction sequence
%ptr0 = extractelement <4 x double*> %ptrs, i32 0
%ptr1 = extractelement <4 x double*> %ptrs, i32 1
%ptr2 = extractelement <4 x double*> %ptrs, i32 2
%ptr3 = extractelement <4 x double*> %ptrs, i32 3
%val0 = load double, double* %ptr0, align 8
%val1 = load double, double* %ptr1, align 8
%val2 = load double, double* %ptr2, align 8
%val3 = load double, double* %ptr3, align 8
%vec0 = insertelement <4 x double>undef, %val0, 0
%vec01 = insertelement <4 x double>%vec0, %val1, 1
%vec012 = insertelement <4 x double>%vec01, %val2, 2
%vec0123 = insertelement <4 x double>%vec012, %val3, 3
.. _int_mscatter:
'``llvm.masked.scatter.*``' Intrinsics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
"""""""
This is an overloaded intrinsic. The data stored in memory is a vector of any integer or floating point data type. Each vector element is stored in an arbitrary memory addresses. Scatter with overlapping addresses is guaranteed to be ordered from least-significant to most-significant element.
::
declare void @llvm.masked.scatter.v8i32 (<8 x i32> <value>, <8 x i32*> <ptrs>, i32 <alignment>, <8 x i1> <mask>)
declare void @llvm.masked.scatter.v16f32(<16 x i32> <value>, <16 x i32*> <ptrs>, i32 <alignment>, <16 x i1> <mask>)
Overview:
"""""""""
Writes each element from the value vector to the corresponding memory address. The memory addresses are represented as a vector of pointers. Writing is done according to the provided mask. The mask holds a bit for each vector lane, and is used to prevent memory accesses to the masked-off lanes.
Arguments:
""""""""""
The first operand is a vector value to be written to memory. The second operand is a vector of pointers, pointing to where the value elements should be stored. It has the same underlying type as the value operand. The third operand is an alignment of the destination addresses. The fourth operand, mask, is a vector of boolean values. The types of the mask and the value operand must have the same number of vector elements.
Semantics:
""""""""""
The '``llvm.masked.scatter``' intrinsics is designed for writing selected vector elements to arbitrary memory addresses in a single IR operation. The operation may be conditional, when not all bits in the mask are switched on. It is useful for targets that support vector masked scatter and allows vectorizing basic blocks with data and control divergency. Other targets may support this intrinsic differently, for example by lowering it into a sequence of branches that guard scalar store operations.
::
;; This instruction unconditionaly stores data vector in multiple addresses
call @llvm.masked.scatter.v8i32 (<8 x i32> %value, <8 x i32*> %ptrs, i32 4, <8 x i1> <true, true, .. true>)
;; It is equivalent to a list of scalar stores
%val0 = extractelement <8 x i32> %value, i32 0
%val1 = extractelement <8 x i32> %value, i32 1
..
%val7 = extractelement <8 x i32> %value, i32 7
%ptr0 = extractelement <8 x i32*> %ptrs, i32 0
%ptr1 = extractelement <8 x i32*> %ptrs, i32 1
..
%ptr7 = extractelement <8 x i32*> %ptrs, i32 7
;; Note: the order of the following stores is important when they overlap:
store i32 %val0, i32* %ptr0, align 4
store i32 %val1, i32* %ptr1, align 4
..
store i32 %val7, i32* %ptr7, align 4
Memory Use Markers
------------------
@ -10285,6 +10438,8 @@ Semantics:
This intrinsic is lowered to the ``val``.
.. _int_assume:
'``llvm.assume``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -46,6 +46,15 @@ B
C
-
**CFI**
Call Frame Information. Used in DWARF debug info and in C++ unwind info
to show how the function prolog lays out the stack frame.
**CIE**
Common Information Entry. A kind of CFI used to reduce the size of FDEs.
The compiler creates a CIE which contains the information common across all
the FDEs. Each FDE then points to its CIE.
**CSE**
Common Subexpression Elimination. An optimization that removes common
subexpression compuation. For example ``(a+b)*(a+b)`` has two subexpressions
@ -82,6 +91,10 @@ F
**FCA**
First Class Aggregate
**FDE**
Frame Description Entry. A kind of CFI used to describe the stack frame of
one function.
G
-
@ -118,9 +131,21 @@ L
**LCSSA**
Loop-Closed Static Single Assignment Form
**LGTM**
"Looks Good To Me". In a review thread, this indicates that the
reviewer thinks that the patch is okay to commit.
**LICM**
Loop Invariant Code Motion
**LSDA**
Language Specific Data Area. C++ "zero cost" unwinding is built on top a
generic unwinding mechanism. As the unwinder walks each frame, it calls
a "personality" function to do language specific analysis. Each function's
FDE points to an optional LSDA which is passed to the personality function.
For C++, the LSDA contain info about the type and location of catch
statements in that function.
**Load-VN**
Load Value Numbering

View File

@ -14,26 +14,29 @@ This library is intended primarily for in-process coverage-guided fuzz testing
* Build the Fuzzer library as a static archive (or just a set of .o files).
Note that the Fuzzer contains the main() function.
Preferably do *not* use sanitizers while building the Fuzzer.
* Build the library you are going to test with -fsanitize-coverage=[234]
* Build the library you are going to test with
`-fsanitize-coverage={bb,edge}[,indirect-calls,8bit-counters]`
and one of the sanitizers. We recommend to build the library in several
different modes (e.g. asan, msan, lsan, ubsan, etc) and even using different
optimizations options (e.g. -O0, -O1, -O2) to diversify testing.
* Build a test driver using the same options as the library.
The test driver is a C/C++ file containing interesting calls to the library
inside a single function ``extern "C" void TestOneInput(const uint8_t *Data, size_t Size);``
inside a single function ``extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);``
* Link the Fuzzer, the library and the driver together into an executable
using the same sanitizer options as for the library.
* Collect the initial corpus of inputs for the
fuzzer (a directory with test inputs, one file per input).
The better your inputs are the faster you will find something interesting.
Also try to keep your inputs small, otherwise the Fuzzer will run too slow.
By default, the Fuzzer limits the size of every input to 64 bytes
(use ``-max_len=N`` to override).
* Run the fuzzer with the test corpus. As new interesting test cases are
discovered they will be added to the corpus. If a bug is discovered by
the sanitizer (asan, etc) it will be reported as usual and the reproducer
will be written to disk.
Each Fuzzer process is single-threaded (unless the library starts its own
threads). You can run the Fuzzer on the same corpus in multiple processes.
in parallel. For run-time options run the Fuzzer binary with '-help=1'.
threads). You can run the Fuzzer on the same corpus in multiple processes
in parallel.
The Fuzzer is similar in concept to AFL_,
@ -47,6 +50,27 @@ and is used to fuzz various parts of LLVM,
but the Fuzzer itself does not (and should not) depend on any
part of LLVM and can be used for other projects w/o requiring the rest of LLVM.
Flags
=====
The most important flags are::
seed 0 Random seed. If 0, seed is generated.
runs -1 Number of individual test runs (-1 for infinite runs).
max_len 64 Maximum length of the test input.
cross_over 1 If 1, cross over inputs.
mutate_depth 5 Apply this number of consecutive mutations to each input.
timeout 1200 Timeout in seconds (if positive). If one unit runs more than this number of seconds the process will abort.
help 0 Print help.
save_minimized_corpus 0 If 1, the minimized corpus is saved into the first input directory
jobs 0 Number of jobs to run. If jobs >= 1 we spawn this number of jobs in separate worker processes with stdout/stderr redirected to fuzz-JOB.log.
workers 0 Number of simultaneous worker processes to run the jobs. If zero, "min(jobs,NumberOfCpuCores()/2)" is used.
tokens 0 Use the file with tokens (one token per line) to fuzz a token based input language.
apply_tokens 0 Read the given input file, substitute bytes with tokens and write the result to stdout.
sync_command 0 Execute an external command "<sync_command> <test_corpus>" to synchronize the test corpus.
sync_timeout 600 Minimum timeout between syncs.
For the full list of flags run the fuzzer binary with ``-help=1``.
Usage examples
==============
@ -56,7 +80,7 @@ Toy example
A simple function that does something interesting if it receives the input "HI!"::
cat << EOF >> test_fuzzer.cc
extern "C" void TestOneInput(const unsigned char *data, unsigned long size) {
extern "C" void LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) {
if (size > 0 && data[0] == 'H')
if (size > 1 && data[1] == 'I')
if (size > 2 && data[2] == '!')
@ -68,7 +92,7 @@ A simple function that does something interesting if it receives the input "HI!"
# Build lib/Fuzzer files.
clang -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
# Build test_fuzzer.cc with asan and link against lib/Fuzzer.
clang++ -fsanitize=address -fsanitize-coverage=3 test_fuzzer.cc Fuzzer*.o
clang++ -fsanitize=address -fsanitize-coverage=edge test_fuzzer.cc Fuzzer*.o
# Run the fuzzer with no corpus.
./a.out
@ -79,7 +103,7 @@ PCRE2
Here we show how to use lib/Fuzzer on something real, yet simple: pcre2_::
COV_FLAGS=" -fsanitize-coverage=4 -mllvm -sanitizer-coverage-8bit-counters=1"
COV_FLAGS=" -fsanitize-coverage=edge,indirect-calls,8bit-counters"
# Get PCRE2
svn co svn://vcs.exim.org/pcre2/code/trunk pcre
# Get lib/Fuzzer. Assuming that you already have fresh clang in PATH.
@ -92,7 +116,7 @@ Here we show how to use lib/Fuzzer on something real, yet simple: pcre2_::
cat << EOF > pcre_fuzzer.cc
#include <string.h>
#include "pcre2posix.h"
extern "C" void TestOneInput(const unsigned char *data, size_t size) {
extern "C" void LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) {
if (size < 1) return;
char *str = new char[size+1];
memcpy(str, data, size);
@ -151,17 +175,21 @@ Now, interrupt the fuzzer and run it again the same way. You will see::
This time you were running the fuzzer with a non-empty input corpus (564 items).
As the first step, the fuzzer minimized the set to produce 344 interesting items (the ``INITED`` line)
It is quite convenient to store test corpuses in git.
As an example, here is a git repository with test inputs for the above PCRE2 fuzzer::
git clone https://github.com/kcc/fuzzing-with-sanitizers.git
./pcre_fuzzer ./fuzzing-with-sanitizers/pcre2/C1/
You may run ``N`` independent fuzzer jobs in parallel on ``M`` CPUs::
N=100; M=4; ./pcre_fuzzer ./CORPUS -jobs=$N -workers=$M
This is useful when you already have an exhaustive test corpus.
If you've just started fuzzing with no good corpus running independent
jobs will create a corpus with too many duplicates.
One way to avoid this and still use all of your CPUs is to use the flag ``-exit_on_first=1``
which will cause the fuzzer to exit on the first new synthesised input::
By default (``-reload=1``) the fuzzer processes will periodically scan the CORPUS directory
and reload any new tests. This way the test inputs found by one process will be picked up
by all others.
N=100; M=4; ./pcre_fuzzer ./CORPUS -jobs=$N -workers=$M -exit_on_first=1
If ``-workers=$M`` is not supplied, ``min($N,NumberOfCpuCore/2)`` will be used.
Heartbleed
----------
@ -172,7 +200,7 @@ to find Heartbleed with LibFuzzer::
wget https://www.openssl.org/source/openssl-1.0.1f.tar.gz
tar xf openssl-1.0.1f.tar.gz
COV_FLAGS="-fsanitize-coverage=4" # -mllvm -sanitizer-coverage-8bit-counters=1"
COV_FLAGS="-fsanitize-coverage=edge,indirect-calls" # -fsanitize-coverage=8bit-counters
(cd openssl-1.0.1f/ && ./config &&
make -j 32 CC="clang -g -fsanitize=address $COV_FLAGS")
# Get and build LibFuzzer
@ -196,7 +224,7 @@ to find Heartbleed with LibFuzzer::
assert (SSL_CTX_use_PrivateKey_file(sctx, "server.key", SSL_FILETYPE_PEM));
return 0;
}
extern "C" void TestOneInput(unsigned char *Data, size_t Size) {
extern "C" void LLVMFuzzerTestOneInput(unsigned char *Data, size_t Size) {
static int unused = Init();
SSL *server = SSL_new(sctx);
BIO *sinbio = BIO_new(BIO_s_mem());
@ -259,7 +287,7 @@ Periodically restart both fuzzers so that they can use each other's findings.
How good is my fuzzer?
----------------------
Once you implement your target function ``TestOneInput`` and fuzz it to death,
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::
@ -271,6 +299,12 @@ and dump covered PCs to disk before exiting.
Then you can subtract the set of covered PCs from the set of all instrumented PCs in the binary,
see SanitizerCoverage_ for details.
User-supplied mutators
----------------------
LibFuzzer allows to use custom (user-supplied) mutators,
see FuzzerInterface.h_
Fuzzing components of LLVM
==========================
@ -299,6 +333,24 @@ Clang can also be fuzzed with Tokens_ using ``-tokens=$LLVM/lib/Fuzzer/cxx_fuzze
Tracking bug: https://llvm.org/bugs/show_bug.cgi?id=23057
Buildbot
--------
We have a buildbot that runs the above fuzzers for LLVM components
24/7/365 at http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fuzzer .
Pre-fuzzed test inputs in git
-----------------------------
The buildbot occumulates large test corpuses over time.
The corpuses are stored in git on github and can be used like this::
git clone https://github.com/kcc/fuzzing-with-sanitizers.git
bin/clang-format-fuzzer fuzzing-with-sanitizers/llvm/clang-format/C1
bin/clang-fuzzer fuzzing-with-sanitizers/llvm/clang/C1/
bin/clang-fuzzer fuzzing-with-sanitizers/llvm/clang/TOK1 -tokens=$LLVM/llvm/lib/Fuzzer/cxx_fuzzer_tokens.txt
FAQ
=========================
@ -359,6 +411,8 @@ Examples: regular expression matchers, text or binary format parsers.
.. _AFL: http://lcamtuf.coredump.cx/afl/
.. _SanitizerCoverage: https://code.google.com/p/address-sanitizer/wiki/AsanCoverage
.. _SanitizerCoverage: http://clang.llvm.org/docs/SanitizerCoverage.html
.. _Heartbleed: http://en.wikipedia.org/wiki/Heartbleed
.. _FuzzerInterface.h: https://github.com/llvm-mirror/llvm/blob/master/lib/Fuzzer/FuzzerInterface.h

View File

@ -168,10 +168,10 @@ These are overloaded intrinsics. You can use these on any pointer types.
.. code-block:: llvm
declare i8* @llvm.nvvm.ptr.gen.to.global.p1i8.p0i8(i8 addrspace(1)*)
declare i8* @llvm.nvvm.ptr.gen.to.shared.p3i8.p0i8(i8 addrspace(3)*)
declare i8* @llvm.nvvm.ptr.gen.to.constant.p4i8.p0i8(i8 addrspace(4)*)
declare i8* @llvm.nvvm.ptr.gen.to.local.p5i8.p0i8(i8 addrspace(5)*)
declare i8 addrspace(1)* @llvm.nvvm.ptr.gen.to.global.p1i8.p0i8(i8*)
declare i8 addrspace(3)* @llvm.nvvm.ptr.gen.to.shared.p3i8.p0i8(i8*)
declare i8 addrspace(4)* @llvm.nvvm.ptr.gen.to.constant.p4i8.p0i8(i8*)
declare i8 addrspace(5)* @llvm.nvvm.ptr.gen.to.local.p5i8.p0i8(i8*)
Overview:
"""""""""

View File

@ -146,10 +146,20 @@ Submit button to finish closing the review.
Status
------
Please let us know whether you like it and what could be improved!
Please let us know whether you like it and what could be improved! We're still
working on setting up a bug tracker, but you can email klimek-at-google-dot-com
and chandlerc-at-gmail-dot-com and CC the llvmdev mailing list with questions
until then. We also could use help implementing improvements. This sadly is
really painful and hard because the Phabricator codebase is in PHP and not as
testable as you might like. However, we've put exactly what we're deploying up
on an `llvm-reviews GitHub project`_ where folks can hack on it and post pull
requests. We're looking into what the right long-term hosting for this is, but
note that it is a derivative of an existing open source project, and so not
trivially a good fit for an official LLVM project.
.. _LLVM's Phabricator: http://reviews.llvm.org
.. _`http://reviews.llvm.org`: http://reviews.llvm.org
.. _Code Repository Browser: http://reviews.llvm.org/diffusion/
.. _Arcanist Quick Start: http://www.phabricator.com/docs/phabricator/article/Arcanist_Quick_Start.html
.. _Arcanist User Guide: http://www.phabricator.com/docs/phabricator/article/Arcanist_User_Guide.html
.. _llvm-reviews GitHub project: https://github.com/r4nt/llvm-reviews/

View File

@ -1105,10 +1105,10 @@ If you have a set-like data structure that is usually small and whose elements
are reasonably small, a ``SmallSet<Type, N>`` is a good choice. This set has
space for N elements in place (thus, if the set is dynamically smaller than N,
no malloc traffic is required) and accesses them with a simple linear search.
When the set grows beyond 'N' elements, it allocates a more expensive
When the set grows beyond N elements, it allocates a more expensive
representation that guarantees efficient access (for most types, it falls back
to std::set, but for pointers it uses something far better, :ref:`SmallPtrSet
<dss_smallptrset>`.
to :ref:`std::set <dss_set>`, but for pointers it uses something far better,
:ref:`SmallPtrSet <dss_smallptrset>`.
The magic of this class is that it handles small sets extremely efficiently, but
gracefully handles extremely large sets without loss of efficiency. The
@ -1120,16 +1120,31 @@ and erasing, but does not support iteration.
llvm/ADT/SmallPtrSet.h
^^^^^^^^^^^^^^^^^^^^^^
SmallPtrSet has all the advantages of ``SmallSet`` (and a ``SmallSet`` of
``SmallPtrSet`` has all the advantages of ``SmallSet`` (and a ``SmallSet`` of
pointers is transparently implemented with a ``SmallPtrSet``), but also supports
iterators. If more than 'N' insertions are performed, a single quadratically
iterators. If more than N insertions are performed, a single quadratically
probed hash table is allocated and grows as needed, providing extremely
efficient access (constant time insertion/deleting/queries with low constant
factors) and is very stingy with malloc traffic.
Note that, unlike ``std::set``, the iterators of ``SmallPtrSet`` are invalidated
whenever an insertion occurs. Also, the values visited by the iterators are not
visited in sorted order.
Note that, unlike :ref:`std::set <dss_set>`, the iterators of ``SmallPtrSet``
are invalidated whenever an insertion occurs. Also, the values visited by the
iterators are not visited in sorted order.
.. _dss_stringset:
llvm/ADT/StringSet.h
^^^^^^^^^^^^^^^^^^^^
``StringSet`` is a thin wrapper around :ref:`StringMap\<char\> <dss_stringmap>`,
and it allows efficient storage and retrieval of unique strings.
Functionally analogous to ``SmallSet<StringRef>``, ``StringSet`` also suports
iteration. (The iterator dereferences to a ``StringMapEntry<char>``, so you
need to call ``i->getKey()`` to access the item of the StringSet.) On the
other hand, ``StringSet`` doesn't support range-insertion and
copy-construction, which :ref:`SmallSet <dss_smallset>` and :ref:`SmallPtrSet
<dss_smallptrset>` do support.
.. _dss_denseset:
@ -1297,8 +1312,9 @@ never use hash_set and unordered_set because they are generally very expensive
(each insertion requires a malloc) and very non-portable.
std::multiset is useful if you're not interested in elimination of duplicates,
but has all the drawbacks of std::set. A sorted vector (where you don't delete
duplicate entries) or some other approach is almost always better.
but has all the drawbacks of :ref:`std::set <dss_set>`. A sorted vector
(where you don't delete duplicate entries) or some other approach is almost
always better.
.. _ds_map:

View File

@ -153,8 +153,8 @@ debugger to interpret the information.
To provide basic functionality, the LLVM debugger does have to make some
assumptions about the source-level language being debugged, though it keeps
these to a minimum. The only common features that the LLVM debugger assumes
exist are `source files <LangRef.html#MDFile>`_, and `program objects
<LangRef.html#MDGlobalVariable>`_. These abstract objects are used by a
exist are `source files <LangRef.html#difile>`_, and `program objects
<LangRef.html#diglobalvariable>`_. These abstract objects are used by a
debugger to form stack traces, show information about local variables, etc.
This section of the documentation first describes the representation aspects
@ -177,27 +177,27 @@ provide debug information at various points in generated code.
.. code-block:: llvm
void %llvm.dbg.declare(metadata, metadata, metadata)
void @llvm.dbg.declare(metadata, metadata, metadata)
This intrinsic provides information about a local element (e.g., variable).
The first argument is metadata holding the alloca for the variable. The second
argument is a `local variable <LangRef.html#MDLocalVariable>`_ containing a
argument is a `local variable <LangRef.html#dilocalvariable>`_ containing a
description of the variable. The third argument is a `complex expression
<LangRef.html#MDExpression>`_.
<LangRef.html#diexpression>`_.
``llvm.dbg.value``
^^^^^^^^^^^^^^^^^^
.. code-block:: llvm
void %llvm.dbg.value(metadata, i64, metadata, metadata)
void @llvm.dbg.value(metadata, i64, metadata, metadata)
This intrinsic provides information when a user source variable is set to a new
value. The first argument is the new value (wrapped as metadata). The second
argument is the offset in the user source variable where the new value is
written. The third argument is a `local variable
<LangRef.html#MDLocalVariable>`_ containing a description of the variable. The
third argument is a `complex expression <LangRef.html#MDExpression>`_.
<LangRef.html#dilocalvariable>`_ containing a description of the variable. The
third argument is a `complex expression <LangRef.html#diexpression>`_.
Object lifetimes and scoping
============================
@ -259,31 +259,31 @@ Compiled to LLVM, this function would be represented like this:
!llvm.module.flags = !{!7, !8, !9}
!llvm.ident = !{!10}
!0 = !MDCompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
!1 = !MDFile(filename: "/dev/stdin", directory: "/Users/dexonsmith/data/llvm/debug-info")
!0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
!1 = !DIFile(filename: "/dev/stdin", directory: "/Users/dexonsmith/data/llvm/debug-info")
!2 = !{}
!3 = !{!4}
!4 = !MDSubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, function: void ()* @foo, variables: !2)
!5 = !MDSubroutineType(types: !6)
!4 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, function: void ()* @foo, variables: !2)
!5 = !DISubroutineType(types: !6)
!6 = !{null}
!7 = !{i32 2, !"Dwarf Version", i32 2}
!8 = !{i32 2, !"Debug Info Version", i32 3}
!9 = !{i32 1, !"PIC Level", i32 2}
!10 = !{!"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)"}
!11 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "X", scope: !4, file: !1, line: 2, type: !12)
!12 = !MDBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!13 = !MDExpression()
!14 = !MDLocation(line: 2, column: 9, scope: !4)
!15 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "Y", scope: !4, file: !1, line: 3, type: !12)
!16 = !MDLocation(line: 3, column: 9, scope: !4)
!17 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "Z", scope: !18, file: !1, line: 5, type: !12)
!18 = distinct !MDLexicalBlock(scope: !4, file: !1, line: 4, column: 5)
!19 = !MDLocation(line: 5, column: 11, scope: !18)
!20 = !MDLocation(line: 6, column: 11, scope: !18)
!21 = !MDLocation(line: 6, column: 9, scope: !18)
!22 = !MDLocation(line: 8, column: 9, scope: !4)
!23 = !MDLocation(line: 8, column: 7, scope: !4)
!24 = !MDLocation(line: 9, column: 3, scope: !4)
!11 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "X", scope: !4, file: !1, line: 2, type: !12)
!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!13 = !DIExpression()
!14 = !DILocation(line: 2, column: 9, scope: !4)
!15 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "Y", scope: !4, file: !1, line: 3, type: !12)
!16 = !DILocation(line: 3, column: 9, scope: !4)
!17 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "Z", scope: !18, file: !1, line: 5, type: !12)
!18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
!19 = !DILocation(line: 5, column: 11, scope: !18)
!20 = !DILocation(line: 6, column: 11, scope: !18)
!21 = !DILocation(line: 6, column: 9, scope: !18)
!22 = !DILocation(line: 8, column: 9, scope: !4)
!23 = !DILocation(line: 8, column: 7, scope: !4)
!24 = !DILocation(line: 9, column: 3, scope: !4)
This example illustrates a few important details about LLVM debugging
@ -303,15 +303,15 @@ scope information for the variable ``X``.
.. code-block:: llvm
!14 = !MDLocation(line: 2, column: 9, scope: !4)
!4 = !MDSubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5,
!14 = !DILocation(line: 2, column: 9, scope: !4)
!4 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5,
isLocal: false, isDefinition: true, scopeLine: 1,
isOptimized: false, function: void ()* @foo,
variables: !2)
Here ``!14`` is metadata providing `location information
<LangRef.html#MDLocation>`_. In this example, scope is encoded by ``!4``, a
`subprogram descriptor <LangRef.html#MDSubprogram>`_. This way the location
<LangRef.html#dilocation>`_. In this example, scope is encoded by ``!4``, a
`subprogram descriptor <LangRef.html#disubprogram>`_. This way the location
information attached to the intrinsics indicates that the variable ``X`` is
declared at line number 2 at a function level scope in function ``foo``.
@ -328,8 +328,8 @@ scope information for the variable ``Z``.
.. code-block:: llvm
!18 = distinct !MDLexicalBlock(scope: !4, file: !1, line: 4, column: 5)
!19 = !MDLocation(line: 5, column: 11, scope: !18)
!18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
!19 = !DILocation(line: 5, column: 11, scope: !18)
Here ``!19`` indicates that ``Z`` is declared at line number 5 and column
number 0 inside of lexical scope ``!18``. The lexical scope itself resides
@ -406,7 +406,7 @@ a C/C++ front-end would generate the following descriptors:
!llvm.module.flags = !{!6, !7}
;; Define the compile unit.
!0 = !MDCompileUnit(language: DW_LANG_C99, file: !1,
!0 = !DICompileUnit(language: DW_LANG_C99, file: !1,
producer:
"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)",
isOptimized: false, runtimeVersion: 0, emissionKind: 1,
@ -416,7 +416,7 @@ a C/C++ front-end would generate the following descriptors:
;;
;; Define the file
;;
!1 = !MDFile(filename: "/dev/stdin",
!1 = !DIFile(filename: "/dev/stdin",
directory: "/Users/dexonsmith/data/llvm/debug-info")
;; An empty array.
@ -428,14 +428,14 @@ a C/C++ front-end would generate the following descriptors:
;;
;; Define the global variable itself.
;;
!4 = !MDGlobalVariable(name: "MyGlobal", scope: !0, file: !1, line: 1,
!4 = !DIGlobalVariable(name: "MyGlobal", scope: !0, file: !1, line: 1,
type: !5, isLocal: false, isDefinition: true,
variable: i32* @MyGlobal)
;;
;; Define the type
;;
!5 = !MDBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!5 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
;; Dwarf version to output.
!6 = !{i32 2, !"Dwarf Version", i32 2}
@ -461,7 +461,7 @@ a C/C++ front-end would generate the following descriptors:
;;
;; Define the anchor for subprograms.
;;
!4 = !MDSubprogram(name: "main", scope: !1, file: !1, line: 1, type: !5,
!4 = !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !5,
isLocal: false, isDefinition: true, scopeLine: 1,
flags: DIFlagPrototyped, isOptimized: false,
function: i32 (i32, i8**)* @main, variables: !2)

View File

@ -142,8 +142,8 @@ resulting relocation sequence is:
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
%0 = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 9, i32 9)
%0 = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 7, i32 7)
ret i8 addrspace(1)* %obj.relocated
}
@ -207,7 +207,82 @@ This example was taken from the tests for the :ref:`RewriteStatepointsForGC` uti
opt -rewrite-statepoints-for-gc test/Transforms/RewriteStatepointsForGC/basics.ll -S | llc -debug-only=stackmaps
GC Transitions
^^^^^^^^^^^^^^^^^^
As a practical consideration, many garbage-collected systems allow code that is
collector-aware ("managed code") to call code that is not collector-aware
("unmanaged code"). It is common that such calls must also be safepoints, since
it is desirable to allow the collector to run during the execution of
unmanaged code. Futhermore, it is common that coordinating the transition from
managed to unmanaged code requires extra code generation at the call site to
inform the collector of the transition. In order to support these needs, a
statepoint may be marked as a GC transition, and data that is necessary to
perform the transition (if any) may be provided as additional arguments to the
statepoint.
Note that although in many cases statepoints may be inferred to be GC
transitions based on the function symbols involved (e.g. a call from a
function with GC strategy "foo" to a function with GC strategy "bar"),
indirect calls that are also GC transitions must also be supported. This
requirement is the driving force behing the decision to require that GC
transitions are explicitly marked.
Let's revisit the sample given above, this time treating the call to ``@foo``
as a GC transition. Depending on our target, the transition code may need to
access some extra state in order to inform the collector of the transition.
Let's assume a hypothetical GC--somewhat unimaginatively named "hypothetical-gc"
--that requires that a TLS variable must be written to before and after a call
to unmanaged code. The resulting relocation sequence is:
.. code-block:: llvm
@flag = thread_local global i32 0, align 4
define i8 addrspace(1)* @test1(i8 addrspace(1) *%obj)
gc "hypothetical-gc" {
%0 = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 1, i32* @Flag, i32 0, i8 addrspace(1)* %obj)
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 7, i32 7)
ret i8 addrspace(1)* %obj.relocated
}
During lowering, this will result in a instruction selection DAG that looks
something like:
::
CALLSEQ_START
...
GC_TRANSITION_START (lowered i32 *@Flag), SRCVALUE i32* Flag
STATEPOINT
GC_TRANSITION_END (lowered i32 *@Flag), SRCVALUE i32 *Flag
...
CALLSEQ_END
In order to generate the necessary transition code, the backend for each target
supported by "hypothetical-gc" must be modified to lower ``GC_TRANSITION_START``
and ``GC_TRANSITION_END`` nodes appropriately when the "hypothetical-gc"
strategy is in use for a particular function. Assuming that such lowering has
been added for X86, the generated assembly would be:
.. code-block:: gas
.globl test1
.align 16, 0x90
pushq %rax
movl $1, %fs:Flag@TPOFF
callq foo
movl $0, %fs:Flag@TPOFF
.Ltmp1:
movq (%rsp), %rax # This load is redundant (oops!)
popq %rdx
retq
Note that the design as presented above is not fully implemented: in particular,
strategy-specific lowering is not present, and all GC transitions are emitted as
as single no-op before and after the call instruction. These no-ops are often
removed by the backend during dead machine instruction elimination.
Intrinsics
@ -222,9 +297,11 @@ Syntax:
::
declare i32
@llvm.experimental.gc.statepoint(func_type <target>,
i64 <#call args>. i64 <unused>,
@llvm.experimental.gc.statepoint(i64 <id>, i32 <num patch bytes>,
func_type <target>,
i64 <#call args>, i64 <flags>,
... (call parameters),
i64 <# transition args>, ... (transition parameters),
i64 <# deopt args>, ... (deopt parameters),
... (gc parameters))
@ -237,18 +314,49 @@ runtime.
Operands:
"""""""""
The 'id' operand is a constant integer that is reported as the ID
field in the generated stackmap. LLVM does not interpret this
parameter in any way and its meaning is up to the statepoint user to
decide. Note that LLVM is free to duplicate code containing
statepoint calls, and this may transform IR that had a unique 'id' per
lexical call to statepoint to IR that does not.
If 'num patch bytes' is non-zero then the call instruction
corresponding to the statepoint is not emitted and LLVM emits 'num
patch bytes' bytes of nops in its place. LLVM will emit code to
prepare the function arguments and retrieve the function return value
in accordance to the calling convention; the former before the nop
sequence and the latter after the nop sequence. It is expected that
the user will patch over the 'num patch bytes' bytes of nops with a
calling sequence specific to their runtime before executing the
generated machine code. There are no guarantees with respect to the
alignment of the nop sequence. Unlike :doc:`StackMaps` statepoints do
not have a concept of shadow bytes.
The 'target' operand is the function actually being called. The
target can be specified as either a symbolic LLVM function, or as an
arbitrary Value of appropriate function type. Note that the function
type must match the signature of the callee and the types of the 'call
parameters' arguments.
parameters' arguments. If 'num patch bytes' is non-zero then 'target'
has to be the constant pointer null of the appropriate function type.
The '#call args' operand is the number of arguments to the actual
call. It must exactly match the number of arguments passed in the
'call parameters' variable length section.
The 'unused' operand is unused and likely to be removed. Please do
not use.
The 'flags' operand is used to specify extra information about the
statepoint. This is currently only used to mark certain statepoints
as GC transitions. This operand is a 64-bit integer with the following
layout, where bit 0 is the least significant bit:
+-------+---------------------------------------------------+
| Bit # | Usage |
+=======+===================================================+
| 0 | Set if the statepoint is a GC transition, cleared |
| | otherwise. |
+-------+---------------------------------------------------+
| 1-63 | Reserved for future use; must be cleared. |
+-------+---------------------------------------------------+
The 'call parameters' arguments are simply the arguments which need to
be passed to the call target. They will be lowered according to the
@ -257,6 +365,14 @@ instruction. The number of arguments must exactly match what is
specified in '# call args'. The types must match the signature of
'target'.
The 'transition parameters' arguments contain an arbitrary list of
Values which need to be passed to GC transition code. They will be
lowered and passed as operands to the appropriate GC_TRANSITION nodes
in the selection DAG. It is assumed that these arguments must be
available before and after (but not necessarily during) the execution
of the callee. The '# transition args' field indicates how many operands
are to be interpreted as 'transition parameters'.
The 'deopt parameters' arguments contain an arbitrary list of Values
which is meaningful to the runtime. The runtime may read any of these
values, but is assumed not to modify them. If the garbage collector
@ -388,6 +504,12 @@ the runtime or collector are provided via the :ref:`Stack Map format
Each statepoint generates the following Locations:
* Constant which describes the calling convention of the call target. This
constant is a valid :ref:`calling convention identifier <callingconv>` for
the version of LLVM used to generate the stackmap. No additional compatibility
guarantees are made for this constant over what LLVM provides elsewhere w.r.t.
these identifiers.
* Constant which describes the flags passed to the statepoint intrinsic
* Constant which describes number of following deopt *Locations* (not
operands)
* Variable number of Locations, one for each deopt parameter listed in
@ -405,9 +527,6 @@ Note that the Locations used in each section may describe the same
physical location. e.g. A stack slot may appear as a deopt location,
a gc base pointer, and a gc derived pointer.
The ID field of the 'StkMapRecord' for a statepoint is meaningless and
it's value is explicitly unspecified.
The LiveOut section of the StkMapRecord will be empty for a statepoint
record.
@ -471,7 +590,7 @@ As an example, given this code:
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
ret i8 addrspace(1)* %obj
}
@ -481,8 +600,8 @@ The pass would produce this IR:
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
%0 = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 9, i32 9)
%0 = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 12, i32 12)
ret i8 addrspace(1)* %obj.relocated
}
@ -535,8 +654,8 @@ This pass would produce the following IR:
.. code-block:: llvm
define void @test() gc "statepoint-example" {
%safepoint_token = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0)
%safepoint_token1 = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0)
%safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
%safepoint_token1 = call i32 (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
ret void
}
@ -558,6 +677,21 @@ of this function is inserted at each poll site desired. While calls or invokes
inside this method are transformed to a ``gc.statepoints``, recursive poll
insertion is not performed.
By default PlaceSafepoints passes in ``0xABCDEF00`` as the statepoint
ID and ``0`` as the number of patchable bytes to the newly constructed
``gc.statepoint``. These values can be configured on a per-callsite
basis using the attributes ``"statepoint-id"`` and
``"statepoint-num-patch-bytes"``. If a call site is marked with a
``"statepoint-id"`` function attribute and its value is a positive
integer (represented as a string), then that value is used as the ID
of the newly constructed ``gc.statepoint``. If a call site is marked
with a ``"statepoint-num-patch-bytes"`` function attribute and its
value is a positive integer, then that value is used as the 'num patch
bytes' parameter of the newly constructed ``gc.statepoint``. The
``"statepoint-id"`` and ``"statepoint-num-patch-bytes"`` attributes
are not propagated to the ``gc.statepoint`` call or invoke if they
could be successfully parsed.
If you are scheduling the RewriteStatepointsForGC pass late in the pass order,
you should probably schedule this pass immediately before it. The exception
would be if you need to preserve abstract frame information (e.g. for

View File

@ -190,7 +190,7 @@ supported include:
for 'a' in 'c.' This operation is analogous to $(subst) in GNU make.
``!foreach(a, b, c)``
For each member 'b' of dag or list 'a' apply operator 'c.' 'b' is a dummy
For each member of dag or list 'b' apply operator 'c.' 'a' is a dummy
variable that should be declared as a member variable of an instantiated
class. This operation is analogous to $(foreach) in GNU make.

View File

@ -473,6 +473,25 @@ RUN lines:
To add more substituations, look at ``test/lit.cfg`` or ``lit.local.cfg``.
Options
-------
The llvm lit configuration allows to customize some things with user options:
``llc``, ``opt``, ...
Substitute the respective llvm tool name with a custom command line. This
allows to specify custom paths and default arguments for these tools.
Example:
% llvm-lit "-Dllc=llc -verify-machineinstrs"
``run_long_tests``
Enable the execution of long running tests.
``llvm_site_config``
Load the specified lit configuration instead of the default one.
Other Features
--------------

View File

@ -456,10 +456,10 @@ looks like:
template <>
struct ScalarTraits<MyCustomType> {
static void output(const T &value, llvm::raw_ostream &out) {
static void output(const T &value, void*, llvm::raw_ostream &out) {
out << value; // do custom formatting here
}
static StringRef input(StringRef scalar, T &value) {
static StringRef input(StringRef scalar, void*, T &value) {
// do custom parsing here. Return the empty string on success,
// or an error message on failure.
return StringRef();
@ -467,6 +467,56 @@ looks like:
// Determine if this scalar needs quotes.
static bool mustQuote(StringRef) { return true; }
};
Block Scalars
-------------
YAML block scalars are string literals that are represented in YAML using the
literal block notation, just like the example shown below:
.. code-block:: yaml
text: |
First line
Second line
The YAML I/O library provides support for translating between YAML block scalars
and specific C++ types by allowing you to specialize BlockScalarTraits<> on
your data type. The library doesn't provide any built-in support for block
scalar I/O for types like std::string and llvm::StringRef as they are already
supported by YAML I/O and use the ordinary scalar notation by default.
BlockScalarTraits specializations are very similar to the
ScalarTraits specialization - YAML I/O will provide the native type and your
specialization must create a temporary llvm::StringRef when writing, and
it will also provide an llvm::StringRef that has the value of that block scalar
and your specialization must convert that to your native data type when reading.
An example of a custom type with an appropriate specialization of
BlockScalarTraits is shown below:
.. code-block:: c++
using llvm::yaml::BlockScalarTraits;
using llvm::yaml::IO;
struct MyStringType {
std::string Str;
};
template <>
struct BlockScalarTraits<MyStringType> {
static void output(const MyStringType &Value, void *Ctxt,
llvm::raw_ostream &OS) {
OS << Value.Str;
}
static StringRef input(StringRef Scalar, void *Ctxt,
MyStringType &Value) {
Value.Str = Scalar.str();
return StringRef();
}
};
Mappings
@ -723,6 +773,33 @@ because it is a programming error to have invalid struct values.
}
};
Flow Mapping
------------
A YAML "flow mapping" is a mapping that uses the inline notation
(e.g { x: 1, y: 0 } ) when written to YAML. To specify that a type should be
written in YAML using flow mapping, your MappingTraits specialization should
add "static const bool flow = true;". For instance:
.. code-block:: c++
using llvm::yaml::MappingTraits;
using llvm::yaml::IO;
struct Stuff {
...
};
template <>
struct MappingTraits<Stuff> {
static void mapping(IO &io, Stuff &stuff) {
...
}
static const bool flow = true;
}
Flow mappings are subject to line wrapping according to the Output object
configuration.
Sequence
========
@ -770,6 +847,8 @@ With the above, if you used MyList as the data type in your native data
structures, then when converted to YAML, a flow sequence of integers
will be used (e.g. [ 10, -3, 4 ]).
Flow sequences are subject to line wrapping according to the Output object
configuration.
Utility Macros
--------------
@ -833,14 +912,14 @@ Output
The llvm::yaml::Output class is used to generate a YAML document from your
in-memory data structures, using traits defined on your data types.
To instantiate an Output object you need an llvm::raw_ostream, and optionally
a context pointer:
To instantiate an Output object you need an llvm::raw_ostream, an optional
context pointer and an optional wrapping column:
.. code-block:: c++
class Output : public IO {
public:
Output(llvm::raw_ostream &, void *context=NULL);
Output(llvm::raw_ostream &, void *context = NULL, int WrapColumn = 70);
Once you have an Output object, you can use the C++ stream operator on it
to write your native data as YAML. One thing to recall is that a YAML file
@ -849,6 +928,10 @@ streaming as YAML is a mapping, scalar, or sequence, then Output assumes you
are generating one document and wraps the mapping output
with "``---``" and trailing "``...``".
The WrapColumn parameter will cause the flow mappings and sequences to
line-wrap when they go over the supplied column. Pass 0 to completely
suppress the wrapping.
.. code-block:: c++
using llvm::yaml::Output;

View File

@ -169,7 +169,7 @@ SHORT_NAMES = NO
# description.)
# The default value is: NO.
JAVADOC_AUTOBRIEF = NO
JAVADOC_AUTOBRIEF = YES
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
@ -177,7 +177,7 @@ JAVADOC_AUTOBRIEF = NO
# requiring an explicit \brief command for a brief description.)
# The default value is: NO.
QT_AUTOBRIEF = NO
QT_AUTOBRIEF = YES
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as

View File

@ -252,7 +252,7 @@ For API clients and LLVM developers.
WritingAnLLVMPass
HowToUseAttributes
NVPTXUsage
R600Usage
AMDGPUUsage
StackMaps
InAlloca
BigEndianNEON
@ -260,6 +260,7 @@ For API clients and LLVM developers.
Statepoints
MergeFunctions
BitSets
FaultMaps
:doc:`WritingAnLLVMPass`
Information on how to write LLVM transformations and analyses.
@ -338,8 +339,8 @@ For API clients and LLVM developers.
:doc:`NVPTXUsage`
This document describes using the NVPTX back-end to compile GPU kernels.
:doc:`R600Usage`
This document describes how to use the R600 back-end.
:doc:`AMDGPUUsage`
This document describes how to use the AMDGPU back-end.
:doc:`StackMaps`
LLVM support for mapping instruction addresses to the location of
@ -362,6 +363,9 @@ For API clients and LLVM developers.
:doc:`InAlloca`
Description of the ``inalloca`` argument attribute.
:doc:`FaultMaps`
LLVM support for folding control flow into faulting machine instructions.
Development Process Documentation
=================================

View File

@ -187,13 +187,13 @@ expressions:
static DIBuilder *DBuilder;
struct DebugInfo {
DICompileUnit TheCU;
DIType DblTy;
DICompileUnit *TheCU;
DIType *DblTy;
DIType getDoubleTy();
DIType *getDoubleTy();
} KSDbgInfo;
DIType DebugInfo::getDoubleTy() {
DIType *DebugInfo::getDoubleTy() {
if (DblTy.isValid())
return DblTy;
@ -245,26 +245,26 @@ So the context:
.. code-block:: c++
DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
KSDbgInfo.TheCU.getDirectory());
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
KSDbgInfo.TheCU.getDirectory());
giving us a DIFile and asking the ``Compile Unit`` we created above for the
giving us an DIFile and asking the ``Compile Unit`` we created above for the
directory and filename where we are currently. Then, for now, we use some
source locations of 0 (since our AST doesn't currently have source location
information) and construct our function definition:
.. code-block:: c++
DIDescriptor FContext(Unit);
DIScope *FContext = Unit;
unsigned LineNo = 0;
unsigned ScopeLine = 0;
DISubprogram SP = DBuilder->createFunction(
DISubprogram *SP = DBuilder->createFunction(
FContext, Name, StringRef(), Unit, LineNo,
CreateFunctionType(Args.size(), Unit), false /* internal linkage */,
true /* definition */, ScopeLine, DIDescriptor::FlagPrototyped, false, F);
true /* definition */, ScopeLine, DINode::FlagPrototyped, false, F);
and we now have a DISubprogram that contains a reference to all of our metadata
for the function.
and we now have an DISubprogram that contains a reference to all of our
metadata for the function.
Source Locations
================
@ -332,11 +332,11 @@ by constructing another small function:
void DebugInfo::emitLocation(ExprAST *AST) {
DIScope *Scope;
if (LexicalBlocks.empty())
Scope = &TheCU;
Scope = TheCU;
else
Scope = LexicalBlocks.back();
Builder.SetCurrentDebugLocation(
DebugLoc::get(AST->getLine(), AST->getCol(), DIScope(*Scope)));
DebugLoc::get(AST->getLine(), AST->getCol(), Scope));
}
that both tells the main ``IRBuilder`` where we are, but also what scope
@ -348,10 +348,10 @@ of scopes:
.. code-block:: c++
std::vector<DIScope *> LexicalBlocks;
std::map<const PrototypeAST *, DIScope> FnScopeMap;
std::map<const PrototypeAST *, DIScope *> FnScopeMap;
and keep a map of each function to the scope that it represents (a DISubprogram
is also a DIScope).
and keep a map of each function to the scope that it represents (an
DISubprogram is also an DIScope).
Then we make sure to:
@ -393,15 +393,15 @@ argument allocas in ``PrototypeAST::CreateArgumentAllocas``.
.. code-block:: c++
DIScope *Scope = KSDbgInfo.LexicalBlocks.back();
DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
KSDbgInfo.TheCU.getDirectory());
DIVariable D = DBuilder->createLocalVariable(dwarf::DW_TAG_arg_variable,
*Scope, Args[Idx], Unit, Line,
KSDbgInfo.getDoubleTy(), Idx);
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
KSDbgInfo.TheCU.getDirectory());
DILocalVariable D = DBuilder->createLocalVariable(
dwarf::DW_TAG_arg_variable, Scope, Args[Idx], Unit, Line,
KSDbgInfo.getDoubleTy(), Idx);
Instruction *Call = DBuilder->insertDeclare(
Alloca, D, DBuilder->createExpression(), Builder.GetInsertBlock());
Call->setDebugLoc(DebugLoc::get(Line, 0, *Scope));
Call->setDebugLoc(DebugLoc::get(Line, 0, Scope));
Here we're doing a few things. First, we're grabbing our current scope
for the variable so we can say what range of code our variable is valid

View File

@ -201,7 +201,8 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb,
case SYM_READ:
{
//%tape.%d = call i32 @getchar()
CallInst *getchar_call = builder->CreateCall(getchar_func, tapereg);
CallInst *getchar_call =
builder->CreateCall(getchar_func, {}, tapereg);
getchar_call->setTailCall(false);
Value *tape_0 = getchar_call;

View File

@ -1293,10 +1293,11 @@ static llvm::Function *createCatchWrappedInvokeFunction(
// (_Unwind_Exception instance). This member tells us whether or not
// the exception is foreign.
llvm::Value *unwindExceptionClass =
builder.CreateLoad(builder.CreateStructGEP(
builder.CreatePointerCast(unwindException,
ourUnwindExceptionType->getPointerTo()),
0));
builder.CreateLoad(builder.CreateStructGEP(
ourUnwindExceptionType,
builder.CreatePointerCast(unwindException,
ourUnwindExceptionType->getPointerTo()),
0));
// Branch to the externalExceptionBlock if the exception is foreign or
// to a catch router if not. Either way the finally block will be run.
@ -1336,10 +1337,10 @@ static llvm::Function *createCatchWrappedInvokeFunction(
//
// Note: Index is not relative to pointer but instead to structure
// unlike a true getelementptr (GEP) instruction
typeInfoThrown = builder.CreateStructGEP(typeInfoThrown, 0);
typeInfoThrown = builder.CreateStructGEP(ourExceptionType, typeInfoThrown, 0);
llvm::Value *typeInfoThrownType =
builder.CreateStructGEP(typeInfoThrown, 0);
builder.CreateStructGEP(builder.getInt8PtrTy(), typeInfoThrown, 0);
generateIntegerPrint(context,
module,

View File

@ -11,10 +11,6 @@ set(LLVM_LINK_COMPONENTS
native
)
set(LLVM_REQUIRES_RTTI 1)
set(LLVM_BUILD_EXAMPLES OFF)
add_kaleidoscope_chapter(Kaleidoscope-Ch7
toy.cpp
)

View File

@ -9,7 +9,6 @@
LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch7
EXAMPLE_TOOL = 1
REQUIRES_RTTI := 1
LINK_COMPONENTS := core mcjit native

View File

@ -713,7 +713,10 @@ Value *BinaryExprAST::Codegen() {
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
VariableExprAST *LHSE = dynamic_cast<VariableExprAST *>(LHS);
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS);
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.

View File

@ -7,10 +7,6 @@ set(LLVM_LINK_COMPONENTS
native
)
set(LLVM_REQUIRES_RTTI 1)
set(LLVM_BUILD_EXAMPLES OFF)
add_kaleidoscope_chapter(Kaleidoscope-Ch8
toy.cpp
)

View File

@ -9,7 +9,6 @@
LEVEL = ../../..
TOOLNAME = Kaleidoscope-Ch8
EXAMPLE_TOOL = 1
REQUIRES_RTTI := 1
LINK_COMPONENTS := core mcjit native

View File

@ -93,13 +93,13 @@ class ExprAST;
}
static IRBuilder<> Builder(getGlobalContext());
struct DebugInfo {
DICompileUnit TheCU;
DIType DblTy;
DICompileUnit *TheCU;
DIType *DblTy;
std::vector<DIScope *> LexicalBlocks;
std::map<const PrototypeAST *, DIScope> FnScopeMap;
std::map<const PrototypeAST *, DIScope *> FnScopeMap;
void emitLocation(ExprAST *AST);
DIType getDoubleTy();
DIType *getDoubleTy();
} KSDbgInfo;
static std::string IdentifierStr; // Filled in if tok_identifier
@ -816,7 +816,7 @@ static PrototypeAST *ParseExtern() {
static DIBuilder *DBuilder;
DIType DebugInfo::getDoubleTy() {
DIType *DebugInfo::getDoubleTy() {
if (DblTy)
return DblTy;
@ -827,18 +827,18 @@ DIType DebugInfo::getDoubleTy() {
void DebugInfo::emitLocation(ExprAST *AST) {
if (!AST)
return Builder.SetCurrentDebugLocation(DebugLoc());
MDScope *Scope;
DIScope *Scope;
if (LexicalBlocks.empty())
Scope = TheCU;
else
Scope = *LexicalBlocks.back();
Scope = LexicalBlocks.back();
Builder.SetCurrentDebugLocation(
DebugLoc::get(AST->getLine(), AST->getCol(), Scope));
}
static MDSubroutineType *CreateFunctionType(unsigned NumArgs, DIFile Unit) {
static DISubroutineType *CreateFunctionType(unsigned NumArgs, DIFile *Unit) {
SmallVector<Metadata *, 8> EltTys;
DIType DblTy = KSDbgInfo.getDoubleTy();
DIType *DblTy = KSDbgInfo.getDoubleTy();
// Add the result type.
EltTys.push_back(DblTy);
@ -846,8 +846,8 @@ static MDSubroutineType *CreateFunctionType(unsigned NumArgs, DIFile Unit) {
for (unsigned i = 0, e = NumArgs; i != e; ++i)
EltTys.push_back(DblTy);
DITypeArray EltTypeArray = DBuilder->getOrCreateTypeArray(EltTys);
return DBuilder->createSubroutineType(Unit, EltTypeArray);
return DBuilder->createSubroutineType(Unit,
DBuilder->getOrCreateTypeArray(EltTys));
}
//===----------------------------------------------------------------------===//
@ -908,7 +908,10 @@ Value *BinaryExprAST::Codegen() {
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
VariableExprAST *LHSE = dynamic_cast<VariableExprAST *>(LHS);
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS);
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
@ -1224,15 +1227,15 @@ Function *PrototypeAST::Codegen() {
AI->setName(Args[Idx]);
// Create a subprogram DIE for this function.
DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
KSDbgInfo.TheCU->getDirectory());
MDScope *FContext = Unit;
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
KSDbgInfo.TheCU->getDirectory());
DIScope *FContext = Unit;
unsigned LineNo = Line;
unsigned ScopeLine = Line;
DISubprogram SP = DBuilder->createFunction(
DISubprogram *SP = DBuilder->createFunction(
FContext, Name, StringRef(), Unit, LineNo,
CreateFunctionType(Args.size(), Unit), false /* internal linkage */,
true /* definition */, ScopeLine, DebugNode::FlagPrototyped, false, F);
true /* definition */, ScopeLine, DINode::FlagPrototyped, false, F);
KSDbgInfo.FnScopeMap[this] = SP;
return F;
@ -1248,14 +1251,14 @@ void PrototypeAST::CreateArgumentAllocas(Function *F) {
// Create a debug descriptor for the variable.
DIScope *Scope = KSDbgInfo.LexicalBlocks.back();
DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
KSDbgInfo.TheCU->getDirectory());
DIVariable D = DBuilder->createLocalVariable(dwarf::DW_TAG_arg_variable,
*Scope, Args[Idx], Unit, Line,
KSDbgInfo.getDoubleTy(), Idx);
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
KSDbgInfo.TheCU->getDirectory());
DILocalVariable *D = DBuilder->createLocalVariable(
dwarf::DW_TAG_arg_variable, Scope, Args[Idx], Unit, Line,
KSDbgInfo.getDoubleTy(), Idx);
DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(),
DebugLoc::get(Line, 0, *Scope),
DebugLoc::get(Line, 0, Scope),
Builder.GetInsertBlock());
// Store the initial value into the alloca.
@ -1274,7 +1277,7 @@ Function *FunctionAST::Codegen() {
return 0;
// Push the current scope.
KSDbgInfo.LexicalBlocks.push_back(&KSDbgInfo.FnScopeMap[Proto]);
KSDbgInfo.LexicalBlocks.push_back(KSDbgInfo.FnScopeMap[Proto]);
// Unset the location for the prologue emission (leading instructions with no
// location in a function are considered part of the prologue and the debugger

View File

@ -672,7 +672,7 @@ Value *BinaryExprAST::Codegen() {
// For now, I'm building without RTTI because LLVM builds that way by
// default and so we need to build that way to use the command line supprt.
// If you build LLVM with RTTI this can be changed back to a dynamic_cast.
VariableExprAST *LHSE = reinterpret_cast<VariableExprAST*>(LHS);
VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS);
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.

View File

@ -1039,7 +1039,7 @@ Value *BinaryExprAST::Codegen() {
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
VariableExprAST *LHSE = reinterpret_cast<VariableExprAST*>(LHS);
VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS);
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.

View File

@ -1113,7 +1113,7 @@ Value *BinaryExprAST::Codegen() {
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
VariableExprAST *LHSE = reinterpret_cast<VariableExprAST*>(LHS);
VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS);
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.

View File

@ -897,7 +897,7 @@ Value *BinaryExprAST::Codegen() {
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
VariableExprAST *LHSE = reinterpret_cast<VariableExprAST*>(LHS);
VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS);
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.

View File

@ -937,7 +937,7 @@ Value *BinaryExprAST::Codegen() {
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
VariableExprAST *LHSE = reinterpret_cast<VariableExprAST*>(LHS);
VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS);
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.

View File

@ -1214,11 +1214,11 @@ public:
void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
JITSymbol findSymbol(const std::string &Name) {
return LazyEmitLayer.findSymbol(Name, true);
return LazyEmitLayer.findSymbol(Name, false);
}
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
return LazyEmitLayer.findSymbolIn(H, Name, true);
return LazyEmitLayer.findSymbolIn(H, Name, false);
}
JITSymbol findUnmangledSymbol(const std::string &Name) {
@ -1276,7 +1276,7 @@ private:
makeStub(*F, *FunctionBodyPointer);
// Step 4) Add the module containing the stub to the JIT.
auto H = addModule(C.takeM());
auto StubH = addModule(C.takeM());
// Step 5) Set the compile and update actions.
//
@ -1289,14 +1289,20 @@ private:
// The update action will update FunctionBodyPointer to point at the newly
// compiled function.
std::shared_ptr<FunctionAST> Fn = std::move(FnAST);
CallbackInfo.setCompileAction([this, Fn]() {
CallbackInfo.setCompileAction([this, Fn, BodyPtrName, StubH]() {
auto H = addModule(IRGen(Session, *Fn));
return findUnmangledSymbolIn(H, Fn->Proto->Name).getAddress();
auto BodySym = findUnmangledSymbolIn(H, Fn->Proto->Name);
auto BodyPtrSym = findUnmangledSymbolIn(StubH, BodyPtrName);
assert(BodySym && "Missing function body.");
assert(BodyPtrSym && "Missing function pointer.");
auto BodyAddr = BodySym.getAddress();
auto BodyPtr = reinterpret_cast<void*>(
static_cast<uintptr_t>(BodyPtrSym.getAddress()));
memcpy(BodyPtr, &BodyAddr, sizeof(uintptr_t));
return BodyAddr;
});
CallbackInfo.setUpdateAction(
getLocalFPUpdater(LazyEmitLayer, H, mangle(BodyPtrName)));
return H;
return StubH;
}
SessionContext &Session;

View File

@ -997,6 +997,13 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
*/
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
/**
* Get the type of the element at a given index in the structure.
*
* @see llvm::StructType::getTypeAtIndex()
*/
LLVMTypeRef LLVMStructGetTypeAtIndex(LLVMTypeRef StructTy, unsigned i);
/**
* Determine whether a structure is packed.
*

View File

@ -58,6 +58,24 @@ LLVMBool LLVMLoadLibraryPermanently(const char* Filename);
void LLVMParseCommandLineOptions(int argc, const char *const *argv,
const char *Overview);
/**
* This function will search through all previously loaded dynamic
* libraries for the symbol \p symbolName. If it is found, the address of
* that symbol is returned. If not, null is returned.
*
* @see sys::DynamicLibrary::SearchForAddressOfSymbol()
*/
void *LLVMSearchForAddressOfSymbol(const char *symbolName);
/**
* This functions permanently adds the symbol \p symbolName with the
* value \p symbolValue. These symbols are searched before any
* libraries.
*
* @see sys::DynamicLibrary::AddSymbol()
*/
void LLVMAddSymbol(const char *symbolName, void *symbolValue);
#ifdef __cplusplus
}
#endif

View File

@ -40,7 +40,7 @@ typedef bool lto_bool_t;
* @{
*/
#define LTO_API_VERSION 13
#define LTO_API_VERSION 15
/**
* \since prior to LTO_API_VERSION=3
@ -62,7 +62,8 @@ typedef enum {
LTO_SYMBOL_SCOPE_HIDDEN = 0x00001000,
LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000,
LTO_SYMBOL_SCOPE_DEFAULT = 0x00001800,
LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800
LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800,
LTO_SYMBOL_COMDAT = 0x00004000
} lto_symbol_attributes;
/**
@ -171,7 +172,7 @@ lto_module_create_from_memory(const void* mem, size_t length);
* Loads an object file from memory with an extra path argument.
* Returns NULL on error (check lto_get_error_message() for details).
*
* \since prior to LTO_API_VERSION=9
* \since LTO_API_VERSION=9
*/
extern lto_module_t
lto_module_create_from_memory_with_path(const void* mem, size_t length,
@ -401,7 +402,7 @@ lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod);
*
* \c cg and \c mod must both be in the same context.
*
* \since prior to LTO_API_VERSION=13
* \since LTO_API_VERSION=13
*/
extern void
lto_codegen_set_module(lto_code_gen_t cg, lto_module_t mod);
@ -548,6 +549,28 @@ lto_codegen_debug_options(lto_code_gen_t cg, const char *);
extern void
lto_initialize_disassembler(void);
/**
* Sets if we should run internalize pass during optimization and code
* generation.
*
* \since LTO_API_VERSION=14
*/
extern void
lto_codegen_set_should_internalize(lto_code_gen_t cg,
lto_bool_t ShouldInternalize);
/**
* \brief Set whether to embed uselists in bitcode.
*
* Sets whether \a lto_codegen_write_merged_modules() should embed uselists in
* output bitcode. This should be turned on for all -save-temps output.
*
* \since LTO_API_VERSION=15
*/
extern void
lto_codegen_set_should_embed_uselists(lto_code_gen_t cg,
lto_bool_t ShouldEmbedUselists);
#ifdef __cplusplus
}
#endif

View File

@ -343,7 +343,7 @@ public:
/// copied from some other APFloat.
static APFloat copySign(APFloat Value, const APFloat &Sign) {
Value.copySign(Sign);
return std::move(Value);
return Value;
}
/// @}

View File

@ -129,7 +129,7 @@ class APInt {
/// \brief Clear unused high order bits
///
/// This method is used internally to clear the to "N" bits in the high order
/// This method is used internally to clear the top "N" bits in the high order
/// word that are not used by the APInt. This is needed after the most
/// significant word is assigned a value to ensure that those bits are
/// zero'd out.
@ -351,8 +351,7 @@ public:
/// This checks to see if the value of this APInt is the maximum signed
/// value for the APInt's bit width.
bool isMaxSignedValue() const {
return BitWidth == 1 ? VAL == 0
: !isNegative() && countPopulation() == BitWidth - 1;
return !isNegative() && countPopulation() == BitWidth - 1;
}
/// \brief Determine if this is the smallest unsigned value.
@ -366,7 +365,7 @@ public:
/// This checks to see if the value of this APInt is the minimum signed
/// value for the APInt's bit width.
bool isMinSignedValue() const {
return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2();
return isNegative() && isPowerOf2();
}
/// \brief Check if this APInt has an N-bits unsigned integer value.
@ -796,7 +795,7 @@ public:
/// \brief Bitwise OR function.
///
/// Performs a bitwise or on *this and RHS. This is implemented bny simply
/// Performs a bitwise or on *this and RHS. This is implemented by simply
/// calling operator|.
///
/// \returns An APInt value representing the bitwise OR of *this and RHS.

View File

@ -96,6 +96,25 @@ namespace llvm {
std::is_convertible<U *const *, T const *>::value>::type* = 0)
: Data(A.data()), Length(A.size()) {}
/// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is
/// templated in order to avoid instantiating SmallVectorTemplateCommon<T>
/// whenever we copy-construct an ArrayRef.
template<typename U, typename DummyT>
/*implicit*/ ArrayRef(const SmallVectorTemplateCommon<U*, DummyT> &Vec,
typename std::enable_if<
std::is_convertible<U *const *,
T const *>::value>::type* = 0)
: Data(Vec.data()), Length(Vec.size()) {
}
/// Construct an ArrayRef<const T*> from std::vector<T*>. This uses SFINAE
/// to ensure that only vectors of pointers can be converted.
template<typename U, typename A>
ArrayRef(const std::vector<U *, A> &Vec,
typename std::enable_if<
std::is_convertible<U *const *, T const *>::value>::type* = 0)
: Data(Vec.data()), Length(Vec.size()) {}
/// @}
/// @name Simple Operations
/// @{

View File

@ -272,10 +272,6 @@ protected:
P->getSecond().~ValueT();
P->getFirst().~KeyT();
}
#ifndef NDEBUG
memset((void*)getBuckets(), 0x5a, sizeof(BucketT)*getNumBuckets());
#endif
}
void initEmpty() {
@ -312,12 +308,6 @@ protected:
}
B->getFirst().~KeyT();
}
#ifndef NDEBUG
if (OldBucketsBegin != OldBucketsEnd)
memset((void*)OldBucketsBegin, 0x5a,
sizeof(BucketT) * (OldBucketsEnd - OldBucketsBegin));
#endif
}
template <typename OtherBaseT>

View File

@ -159,8 +159,10 @@ public:
return *this;
}
// skips all children of the current node and traverses to next node
//
/// \brief Skips all children of the current node and traverses to next node
///
/// Note: This function takes care of incrementing the iterator. If you
/// always increment and call this function, you risk walking off the end.
df_iterator &skipChildren() {
VisitStack.pop_back();
if (!VisitStack.empty())

View File

@ -53,6 +53,7 @@
#include <cassert>
#include <cstring>
#include <iterator>
#include <string>
#include <utility>
namespace llvm {

View File

@ -18,6 +18,7 @@
#define LLVM_ADT_STLEXTRAS_H
#include "llvm/Support/Compiler.h"
#include <algorithm> // for std::all_of
#include <cassert>
#include <cstddef> // for std::size_t
#include <cstdlib> // for qsort
@ -327,6 +328,14 @@ void DeleteContainerSeconds(Container &C) {
C.clear();
}
/// Provide wrappers to std::all_of which take ranges instead of having to pass
/// being/end explicitly.
template<typename R, class UnaryPredicate>
bool all_of(R &&Range, UnaryPredicate &&P) {
return std::all_of(Range.begin(), Range.end(),
std::forward<UnaryPredicate>(P));
}
//===----------------------------------------------------------------------===//
// Extra additions to <memory>
//===----------------------------------------------------------------------===//

View File

@ -50,7 +50,8 @@ public:
armeb, // ARM (big endian): armeb
aarch64, // AArch64 (little endian): aarch64
aarch64_be, // AArch64 (big endian): aarch64_be
bpf, // eBPF or extended BPF or 64-bit BPF (little endian)
bpfel, // eBPF or extended BPF or 64-bit BPF (little endian)
bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel
@ -64,6 +65,7 @@ public:
amdgcn, // AMDGCN: AMD GCN GPUs
sparc, // Sparc: sparc
sparcv9, // Sparcv9: Sparcv9
sparcel, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
systemz, // SystemZ: s390x
tce, // TCE (http://tce.cs.tut.fi/): tce
thumb, // Thumb (little endian): thumb, thumbv.*
@ -81,7 +83,9 @@ public:
hsail64, // AMD HSAIL with 64-bit pointers
spir, // SPIR: standard portable IR for OpenCL 32-bit version
spir64, // SPIR: standard portable IR for OpenCL 64-bit version
kalimba // Kalimba: generic kalimba
kalimba, // Kalimba: generic kalimba
shave, // SHAVE: Movidius vector VLIW processors
LastArchType = shave
};
enum SubArchType {
NoSubArch,
@ -117,7 +121,8 @@ public:
ImaginationTechnologies,
MipsTechnologies,
NVIDIA,
CSR
CSR,
LastVendorType = CSR
};
enum OSType {
UnknownOS,
@ -145,7 +150,8 @@ public:
CUDA, // NVIDIA CUDA
NVCL, // NVIDIA OpenCL
AMDHSA, // AMD HSA Runtime
PS4
PS4,
LastOSType = PS4
};
enum EnvironmentType {
UnknownEnvironment,
@ -162,6 +168,7 @@ public:
MSVC,
Itanium,
Cygnus,
LastEnvironmentType = Cygnus
};
enum ObjectFormatType {
UnknownObjectFormat,
@ -250,6 +257,15 @@ public:
/// getEnvironment - Get the parsed environment type of this triple.
EnvironmentType getEnvironment() const { return Environment; }
/// \brief Parse the version number from the OS name component of the
/// triple, if present.
///
/// For example, "fooos1.2.3" would return (1, 2, 3).
///
/// If an entry is not defined, it will be returned as 0.
void getEnvironmentVersion(unsigned &Major, unsigned &Minor,
unsigned &Micro) const;
/// getFormat - Get the object format for this triple.
ObjectFormatType getObjectFormat() const { return ObjectFormat; }

View File

@ -10,7 +10,7 @@
#ifndef LLVM_ADT_TWINE_H
#define LLVM_ADT_TWINE_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@ -137,7 +137,7 @@ namespace llvm {
const char *cString;
const std::string *stdString;
const StringRef *stringRef;
const SmallVectorImpl<char> *smallString;
const SmallVectorImpl<char> *smallString;
char character;
unsigned int decUI;
int decI;
@ -410,7 +410,7 @@ namespace llvm {
case CStringKind:
case StdStringKind:
case StringRefKind:
case SmallStringKind:
case SmallStringKind:
return true;
default:
return false;

View File

@ -50,7 +50,7 @@ unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray,
// http://en.wikipedia.org/wiki/Levenshtein_distance
//
// Although the algorithm is typically described using an m x n
// array, only two rows are used at a time, so this implemenation
// array, only two rows are used at a time, so this implementation
// just keeps two separate vectors for those two rows.
typename ArrayRef<T>::size_type m = FromArray.size();
typename ArrayRef<T>::size_type n = ToArray.size();

View File

@ -40,6 +40,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Analysis/MemoryLocation.h"
namespace llvm {
@ -82,7 +83,7 @@ public:
/// UnknownSize - This is a special value which can be used with the
/// size arguments in alias queries to indicate that the caller does not
/// know the sizes of the potential memory references.
static uint64_t const UnknownSize = ~UINT64_C(0);
static uint64_t const UnknownSize = MemoryLocation::UnknownSize;
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
@ -98,66 +99,9 @@ public:
/// Alias Queries...
///
/// Location - A description of a memory location.
struct Location {
/// Ptr - The address of the start of the location.
const Value *Ptr;
/// Size - The maximum size of the location, in address-units, or
/// UnknownSize if the size is not known. Note that an unknown size does
/// not mean the pointer aliases the entire virtual address space, because
/// there are restrictions on stepping out of one object and into another.
/// See http://llvm.org/docs/LangRef.html#pointeraliasing
uint64_t Size;
/// AATags - The metadata nodes which describes the aliasing of the
/// location (each member is null if that kind of information is
/// unavailable)..
AAMDNodes AATags;
explicit Location(const Value *P = nullptr, uint64_t S = UnknownSize,
const AAMDNodes &N = AAMDNodes())
: Ptr(P), Size(S), AATags(N) {}
Location getWithNewPtr(const Value *NewPtr) const {
Location Copy(*this);
Copy.Ptr = NewPtr;
return Copy;
}
Location getWithNewSize(uint64_t NewSize) const {
Location Copy(*this);
Copy.Size = NewSize;
return Copy;
}
Location getWithoutAATags() const {
Location Copy(*this);
Copy.AATags = AAMDNodes();
return Copy;
}
};
/// getLocation - Fill in Loc with information about the memory reference by
/// the given instruction.
Location getLocation(const LoadInst *LI);
Location getLocation(const StoreInst *SI);
Location getLocation(const VAArgInst *VI);
Location getLocation(const AtomicCmpXchgInst *CXI);
Location getLocation(const AtomicRMWInst *RMWI);
static Location getLocationForSource(const MemTransferInst *MTI);
static Location getLocationForDest(const MemIntrinsic *MI);
Location getLocation(const Instruction *Inst) {
if (auto *I = dyn_cast<LoadInst>(Inst))
return getLocation(I);
else if (auto *I = dyn_cast<StoreInst>(Inst))
return getLocation(I);
else if (auto *I = dyn_cast<VAArgInst>(Inst))
return getLocation(I);
else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst))
return getLocation(I);
else if (auto *I = dyn_cast<AtomicRMWInst>(Inst))
return getLocation(I);
llvm_unreachable("unsupported memory instruction");
}
/// Legacy typedef for the AA location object. New code should use \c
/// MemoryLocation directly.
typedef MemoryLocation Location;
/// Alias analysis result - Either we know for sure that it does not alias, we
/// know for sure it must alias, or we don't know anything: The two pointers
@ -597,30 +541,6 @@ public:
}
};
// Specialize DenseMapInfo for Location.
template<>
struct DenseMapInfo<AliasAnalysis::Location> {
static inline AliasAnalysis::Location getEmptyKey() {
return AliasAnalysis::Location(DenseMapInfo<const Value *>::getEmptyKey(),
0);
}
static inline AliasAnalysis::Location getTombstoneKey() {
return AliasAnalysis::Location(
DenseMapInfo<const Value *>::getTombstoneKey(), 0);
}
static unsigned getHashValue(const AliasAnalysis::Location &Val) {
return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags);
}
static bool isEqual(const AliasAnalysis::Location &LHS,
const AliasAnalysis::Location &RHS) {
return LHS.Ptr == RHS.Ptr &&
LHS.Size == RHS.Size &&
LHS.AATags == RHS.AATags;
}
};
/// isNoAliasCall - Return true if this pointer is returned by a noalias
/// function.
bool isNoAliasCall(const Value *V);

View File

@ -268,7 +268,7 @@ public:
///
bool aliasesPointer(const Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo,
AliasAnalysis &AA) const;
bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const;
bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const;
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
@ -358,7 +358,7 @@ public:
/// getAliasSetForPointerIfExists - Return the alias set containing the
/// location specified if one exists, otherwise return null.
AliasSet *getAliasSetForPointerIfExists(Value *P, uint64_t Size,
AliasSet *getAliasSetForPointerIfExists(const Value *P, uint64_t Size,
const AAMDNodes &AAInfo) {
return findAliasSetForPointer(P, Size, AAInfo);
}
@ -366,11 +366,12 @@ public:
/// containsPointer - Return true if the specified location is represented by
/// this alias set, false otherwise. This does not modify the AST object or
/// alias sets.
bool containsPointer(Value *P, uint64_t Size, const AAMDNodes &AAInfo) const;
bool containsPointer(const Value *P, uint64_t Size,
const AAMDNodes &AAInfo) const;
/// Return true if the specified instruction "may" (or must) alias one of the
/// members in any of the sets.
bool containsUnknown(Instruction *I) const;
bool containsUnknown(const Instruction *I) const;
/// getAliasAnalysis - Return the underlying alias analysis object used by
/// this tracker.

View File

@ -191,8 +191,8 @@ public:
/// \brief Data about a loop.
///
/// Contains the data necessary to represent represent a loop as a
/// pseudo-node once it's packaged.
/// Contains the data necessary to represent a loop as a pseudo-node once it's
/// packaged.
struct LoopData {
typedef SmallVector<std::pair<BlockNode, BlockMass>, 4> ExitMap;
typedef SmallVector<BlockNode, 4> NodeList;
@ -930,7 +930,7 @@ void BlockFrequencyInfoImpl<BT>::doFunction(const FunctionT *F,
initializeRPOT();
initializeLoops();
// Visit loops in post-order to find thelocal mass distribution, and then do
// Visit loops in post-order to find the local mass distribution, and then do
// the full function.
computeMassInLoops();
computeMassInFunction();

View File

@ -47,6 +47,9 @@ public:
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnFunction(Function &F) override;
void releaseMemory() override;
void print(raw_ostream &OS, const Module *M = nullptr) const override;
/// \brief Get an edge's probability, relative to other out-edges of the Src.

View File

@ -263,8 +263,7 @@ private:
template <typename CGSCCPassT>
ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>
createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
return std::move(
ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass)));
return ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass));
}
/// \brief A CGSCC analysis which acts as a proxy for a function analysis
@ -484,7 +483,7 @@ private:
template <typename FunctionPassT>
CGSCCToFunctionPassAdaptor<FunctionPassT>
createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
return std::move(CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
return CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
}
}

View File

@ -230,7 +230,7 @@ public:
void addCalledFunction(CallSite CS, CallGraphNode *M) {
assert(!CS.getInstruction() || !CS.getCalledFunction() ||
!CS.getCalledFunction()->isIntrinsic());
CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
CalledFunctions.emplace_back(CS.getInstruction(), M);
M->AddRef();
}

View File

@ -41,6 +41,7 @@
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
@ -520,11 +521,11 @@ namespace llvm {
/// in LoopNest.
bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
/// Makes sure both subscripts (i.e. Pair->Src and Pair->Dst) share the same
/// integer type by sign-extending one of them when necessary.
/// Makes sure all subscript pairs share the same integer type by
/// sign-extending as necessary.
/// Sign-extending a subscript is safe because getelementptr assumes the
/// array subscripts are signed.
void unifySubscriptType(Subscript *Pair);
/// array subscripts are signed.
void unifySubscriptType(ArrayRef<Subscript *> Pairs);
/// removeMatchingExtensions - Examines a subscript pair.
/// If the source and destination are identically sign (or zero)

View File

@ -19,7 +19,9 @@
#define LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GenericDomTree.h"
namespace llvm {

View File

@ -0,0 +1,96 @@
//===- IteratedDominanceFrontier.h - Calculate IDF --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \brief Compute iterated dominance frontiers using a linear time algorithm.
///
/// The algorithm used here is based on:
///
/// Sreedhar and Gao. A linear time algorithm for placing phi-nodes.
/// In Proceedings of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of
/// Programming Languages
/// POPL '95. ACM, New York, NY, 62-73.
///
/// It has been modified to not explicitly use the DJ graph data structure and
/// to directly compute pruned SSA using per-variable liveness information.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_IDF_H
#define LLVM_ANALYSIS_IDF_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
namespace llvm {
class BasicBlock;
template <class T> class DomTreeNodeBase;
typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
class DominatorTree;
/// \brief Determine the iterated dominance frontier, given a set of defining
/// blocks, and optionally, a set of live-in blocks.
///
/// In turn, the results can be used to place phi nodes.
///
/// This algorithm is a linear time computation of Iterated Dominance Frontiers,
/// pruned using the live-in set.
/// By default, liveness is not used to prune the IDF computation.
class IDFCalculator {
public:
IDFCalculator(DominatorTree &DT) : DT(DT), useLiveIn(false) {}
/// \brief Give the IDF calculator the set of blocks in which the value is
/// defined. This is equivalent to the set of starting blocks it should be
/// calculating the IDF for (though later gets pruned based on liveness).
///
/// Note: This set *must* live for the entire lifetime of the IDF calculator.
void setDefiningBlocks(const SmallPtrSetImpl<BasicBlock *> &Blocks) {
DefBlocks = &Blocks;
}
/// \brief Give the IDF calculator the set of blocks in which the value is
/// live on entry to the block. This is used to prune the IDF calculation to
/// not include blocks where any phi insertion would be dead.
///
/// Note: This set *must* live for the entire lifetime of the IDF calculator.
void setLiveInBlocks(const SmallPtrSetImpl<BasicBlock *> &Blocks) {
LiveInBlocks = &Blocks;
useLiveIn = true;
}
/// \brief Reset the live-in block set to be empty, and tell the IDF
/// calculator to not use liveness anymore.
void resetLiveInBlocks() {
LiveInBlocks = nullptr;
useLiveIn = false;
}
/// \brief Calculate iterated dominance frontiers
///
/// This uses the linear-time phi algorithm based on DJ-graphs mentioned in
/// the file-level comment. It performs DF->IDF pruning using the live-in
/// set, to avoid computing the IDF for blocks where an inserted PHI node
/// would be dead.
void calculate(SmallVectorImpl<BasicBlock *> &IDFBlocks);
private:
DominatorTree &DT;
bool useLiveIn;
DenseMap<DomTreeNode *, unsigned> DomLevels;
const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks;
const SmallPtrSetImpl<BasicBlock *> *DefBlocks;
SmallVector<BasicBlock *, 32> PHIBlocks;
};
}
#endif

View File

@ -225,6 +225,8 @@ public:
return RecordInterestingDependences ? &InterestingDependences : nullptr;
}
void clearInterestingDependences() { InterestingDependences.clear(); }
/// \brief The vector of memory access instructions. The indices are used as
/// instruction identifiers in the Dependence class.
const SmallVectorImpl<Instruction *> &getMemoryInstructions() const {
@ -343,6 +345,10 @@ public:
/// to needsChecking.
bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const;
/// \brief Returns the number of run-time checks required according to
/// needsChecking.
unsigned getNumberOfChecks(const SmallVectorImpl<int> *PtrPartition) const;
/// \brief Print the list run-time memory checks necessary.
///
/// If \p PtrPartition is set, it contains the partition number for
@ -370,7 +376,8 @@ public:
LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout &DL,
const TargetLibraryInfo *TLI, AliasAnalysis *AA,
DominatorTree *DT, const ValueToValueMap &Strides);
DominatorTree *DT, LoopInfo *LI,
const ValueToValueMap &Strides);
/// Return true we can analyze the memory accesses in the loop and there are
/// no memory dependence cycles.
@ -382,7 +389,10 @@ public:
/// \brief Number of memchecks required to prove independence of otherwise
/// may-alias pointers.
unsigned getNumRuntimePointerChecks() const { return NumComparisons; }
unsigned getNumRuntimePointerChecks(
const SmallVectorImpl<int> *PtrPartition = nullptr) const {
return PtrRtCheck.getNumberOfChecks(PtrPartition);
}
/// Return true if the block BB needs to be predicated in order for the loop
/// to be vectorized.
@ -457,16 +467,13 @@ private:
/// loop-independent and loop-carried dependences between memory accesses.
MemoryDepChecker DepChecker;
/// \brief Number of memchecks required to prove independence of otherwise
/// may-alias pointers
unsigned NumComparisons;
Loop *TheLoop;
ScalarEvolution *SE;
const DataLayout &DL;
const TargetLibraryInfo *TLI;
AliasAnalysis *AA;
DominatorTree *DT;
LoopInfo *LI;
unsigned NumLoads;
unsigned NumStores;
@ -497,6 +504,11 @@ const SCEV *replaceSymbolicStrideSCEV(ScalarEvolution *SE,
const ValueToValueMap &PtrToStride,
Value *Ptr, Value *OrigPtr = nullptr);
/// \brief Check the stride of the pointer and ensure that it does not wrap in
/// the address space.
int isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp,
const ValueToValueMap &StridesMap);
/// \brief This analysis provides dependence information for the memory accesses
/// of a loop.
///
@ -541,6 +553,7 @@ private:
const TargetLibraryInfo *TLI;
AliasAnalysis *AA;
DominatorTree *DT;
LoopInfo *LI;
};
} // End llvm namespace

View File

@ -47,13 +47,6 @@ namespace llvm {
template <typename IRUnitT> class AnalysisManager;
class PreservedAnalyses;
template<typename T>
inline void RemoveFromVector(std::vector<T*> &V, T *N) {
typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N);
assert(I != V.end() && "N is not in this list!");
V.erase(I);
}
class DominatorTree;
class LoopInfo;
class Loop;
@ -324,7 +317,10 @@ public:
/// current loop, updating the Blocks as appropriate. This does not update
/// the mapping in the LoopInfo class.
void removeBlockFromLoop(BlockT *BB) {
RemoveFromVector(Blocks, BB);
auto I = std::find(Blocks.begin(), Blocks.end(), BB);
assert(I != Blocks.end() && "N is not in this list!");
Blocks.erase(I);
DenseBlockSet.erase(BB);
}
@ -361,11 +357,11 @@ public:
/// isLoopInvariant - Return true if the specified value is loop invariant
///
bool isLoopInvariant(Value *V) const;
bool isLoopInvariant(const Value *V) const;
/// hasLoopInvariantOperands - Return true if all the operands of the
/// specified instruction are loop invariant.
bool hasLoopInvariantOperands(Instruction *I) const;
bool hasLoopInvariantOperands(const Instruction *I) const;
/// makeLoopInvariant - If the given value is an instruction inside of the
/// loop and it can be hoisted, do so to make it trivially loop-invariant.
@ -493,7 +489,7 @@ private:
template<class BlockT, class LoopT>
class LoopInfoBase {
// BBMap - Mapping of basic blocks to the inner most loop they occur in
DenseMap<BlockT *, LoopT *> BBMap;
DenseMap<const BlockT *, LoopT *> BBMap;
std::vector<LoopT *> TopLevelLoops;
friend class LoopBase<BlockT, LoopT>;
friend class LoopInfo;
@ -543,9 +539,7 @@ public:
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
/// block is in no loop (for example the entry node), null is returned.
///
LoopT *getLoopFor(const BlockT *BB) const {
return BBMap.lookup(const_cast<BlockT*>(BB));
}
LoopT *getLoopFor(const BlockT *BB) const { return BBMap.lookup(BB); }
/// operator[] - same as getLoopFor...
///
@ -562,7 +556,7 @@ public:
}
// isLoopHeader - True if the block is a loop header node
bool isLoopHeader(BlockT *BB) const {
bool isLoopHeader(const BlockT *BB) const {
const LoopT *L = getLoopFor(BB);
return L && L->getHeader() == BB;
}
@ -729,12 +723,6 @@ public:
/// \brief Provide a name for the analysis for debugging and logging.
static StringRef name() { return "LoopAnalysis"; }
LoopAnalysis() {}
LoopAnalysis(const LoopAnalysis &Arg) {}
LoopAnalysis(LoopAnalysis &&Arg) {}
LoopAnalysis &operator=(const LoopAnalysis &RHS) { return *this; }
LoopAnalysis &operator=(LoopAnalysis &&RHS) { return *this; }
LoopInfo run(Function &F, AnalysisManager<Function> *AM);
};

View File

@ -527,7 +527,7 @@ void LoopInfoBase<BlockT, LoopT>::verify() const {
// Verify that blocks are mapped to valid loops.
#ifndef NDEBUG
for (auto &Entry : BBMap) {
BlockT *BB = Entry.first;
const BlockT *BB = Entry.first;
LoopT *L = Entry.second;
assert(Loops.count(L) && "orphaned loop");
assert(L->contains(BB) && "orphaned block");

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/PredIteratorCache.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
@ -325,7 +326,7 @@ namespace llvm {
AliasAnalysis *AA;
DominatorTree *DT;
AssumptionCache *AC;
std::unique_ptr<PredIteratorCache> PredCache;
PredIteratorCache PredCache;
public:
MemoryDependenceAnalysis();

View File

@ -0,0 +1,137 @@
//===- MemoryLocation.h - Memory location descriptions ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
/// This file provides utility analysis objects describing memory locations.
/// These are used both by the Alias Analysis infrastructure and more
/// specialized memory analysis layers.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_MEMORYLOCATION_H
#define LLVM_ANALYSIS_MEMORYLOCATION_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Metadata.h"
namespace llvm {
class LoadInst;
class StoreInst;
class MemTransferInst;
class MemIntrinsic;
/// Representation for a specific memory location.
///
/// This abstraction can be used to represent a specific location in memory.
/// The goal of the location is to represent enough information to describe
/// abstract aliasing, modification, and reference behaviors of whatever
/// value(s) are stored in memory at the particular location.
///
/// The primary user of this interface is LLVM's Alias Analysis, but other
/// memory analyses such as MemoryDependence can use it as well.
class MemoryLocation {
public:
/// UnknownSize - This is a special value which can be used with the
/// size arguments in alias queries to indicate that the caller does not
/// know the sizes of the potential memory references.
enum : uint64_t { UnknownSize = ~UINT64_C(0) };
/// The address of the start of the location.
const Value *Ptr;
/// The maximum size of the location, in address-units, or
/// UnknownSize if the size is not known.
///
/// Note that an unknown size does not mean the pointer aliases the entire
/// virtual address space, because there are restrictions on stepping out of
/// one object and into another. See
/// http://llvm.org/docs/LangRef.html#pointeraliasing
uint64_t Size;
/// The metadata nodes which describes the aliasing of the location (each
/// member is null if that kind of information is unavailable).
AAMDNodes AATags;
/// Return a location with information about the memory reference by the given
/// instruction.
static MemoryLocation get(const LoadInst *LI);
static MemoryLocation get(const StoreInst *SI);
static MemoryLocation get(const VAArgInst *VI);
static MemoryLocation get(const AtomicCmpXchgInst *CXI);
static MemoryLocation get(const AtomicRMWInst *RMWI);
static MemoryLocation get(const Instruction *Inst) {
if (auto *I = dyn_cast<LoadInst>(Inst))
return get(I);
else if (auto *I = dyn_cast<StoreInst>(Inst))
return get(I);
else if (auto *I = dyn_cast<VAArgInst>(Inst))
return get(I);
else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst))
return get(I);
else if (auto *I = dyn_cast<AtomicRMWInst>(Inst))
return get(I);
llvm_unreachable("unsupported memory instruction");
}
/// Return a location representing the source of a memory transfer.
static MemoryLocation getForSource(const MemTransferInst *MTI);
/// Return a location representing the destination of a memory set or
/// transfer.
static MemoryLocation getForDest(const MemIntrinsic *MI);
explicit MemoryLocation(const Value *Ptr = nullptr,
uint64_t Size = UnknownSize,
const AAMDNodes &AATags = AAMDNodes())
: Ptr(Ptr), Size(Size), AATags(AATags) {}
MemoryLocation getWithNewPtr(const Value *NewPtr) const {
MemoryLocation Copy(*this);
Copy.Ptr = NewPtr;
return Copy;
}
MemoryLocation getWithNewSize(uint64_t NewSize) const {
MemoryLocation Copy(*this);
Copy.Size = NewSize;
return Copy;
}
MemoryLocation getWithoutAATags() const {
MemoryLocation Copy(*this);
Copy.AATags = AAMDNodes();
return Copy;
}
bool operator==(const MemoryLocation &Other) const {
return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags;
}
};
// Specialize DenseMapInfo for MemoryLocation.
template <> struct DenseMapInfo<MemoryLocation> {
static inline MemoryLocation getEmptyKey() {
return MemoryLocation(DenseMapInfo<const Value *>::getEmptyKey(), 0);
}
static inline MemoryLocation getTombstoneKey() {
return MemoryLocation(DenseMapInfo<const Value *>::getTombstoneKey(), 0);
}
static unsigned getHashValue(const MemoryLocation &Val) {
return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags);
}
static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) {
return LHS == RHS;
}
};
}
#endif

View File

@ -75,12 +75,12 @@ public:
bool IsPotentiallyPHITranslatable() const;
/// PHITranslateValue - PHI translate the current address up the CFG from
/// CurBB to Pred, updating our state to reflect any needed changes. If the
/// dominator tree DT is non-null, the translated value must dominate
/// CurBB to Pred, updating our state to reflect any needed changes. If
/// 'MustDominate' is true, the translated value must dominate
/// PredBB. This returns true on failure and sets Addr to null.
bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
const DominatorTree *DT);
const DominatorTree *DT, bool MustDominate);
/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
/// unavailable.

View File

@ -657,6 +657,15 @@ namespace llvm {
SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end());
return getAddRecExpr(NewOp, L, Flags);
}
/// \brief Returns an expression for a GEP
///
/// \p PointeeType The type used as the basis for the pointer arithmetics
/// \p BaseExpr The expression for the pointer operand.
/// \p IndexExprs The expressions for the indices.
/// \p InBounds Whether the GEP is in bounds.
const SCEV *getGEPExpr(Type *PointeeType, const SCEV *BaseExpr,
const SmallVectorImpl<const SCEV *> &IndexExprs,
bool InBounds = false);
const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
const SCEV *getUMaxExpr(const SCEV *LHS, const SCEV *RHS);

View File

@ -221,19 +221,21 @@ public:
/// Parameters that control the generic loop unrolling transformation.
struct UnrollingPreferences {
/// The cost threshold for the unrolled loop, compared to
/// CodeMetrics.NumInsts aggregated over all basic blocks in the loop body.
/// The unrolling factor is set such that the unrolled loop body does not
/// exceed this cost. Set this to UINT_MAX to disable the loop body cost
/// The cost threshold for the unrolled loop. Should be relative to the
/// getUserCost values returned by this API, and the expectation is that
/// the unrolled loop's instructions when run through that interface should
/// not exceed this cost. However, this is only an estimate. Also, specific
/// loops may be unrolled even with a cost above this threshold if deemed
/// profitable. Set this to UINT_MAX to disable the loop body cost
/// restriction.
unsigned Threshold;
/// If complete unrolling could help other optimizations (e.g. InstSimplify)
/// to remove N% of instructions, then we can go beyond unroll threshold.
/// This value set the minimal percent for allowing that.
unsigned MinPercentOfOptimized;
/// The absolute cost threshold. We won't go beyond this even if complete
/// unrolling could result in optimizing out 90% of instructions.
unsigned AbsoluteThreshold;
/// If complete unrolling will reduce the cost of the loop below its
/// expected dynamic cost while rolled by this percentage, apply a discount
/// (below) to its unrolled cost.
unsigned PercentDynamicCostSavedThreshold;
/// The discount applied to the unrolled cost when the *dynamic* cost
/// savings of unrolling exceed the \c PercentDynamicCostSavedThreshold.
unsigned DynamicCostSavingsDiscount;
/// The cost threshold for the unrolled loop when optimizing for size (set
/// to UINT_MAX to disable).
unsigned OptSizeThreshold;
@ -303,7 +305,8 @@ public:
/// mode is legal for a load/store of any legal type.
/// TODO: Handle pre/postinc as well.
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale) const;
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace = 0) const;
/// \brief Return true if the target works with masked instruction
/// AVX2 allows masks for consecutive load and store for i32 and i64 elements.
@ -319,7 +322,8 @@ public:
/// If the AM is not supported, it returns a negative value.
/// TODO: Handle pre/postinc as well.
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale) const;
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace = 0) const;
/// \brief Return true if it's free to truncate a value of type Ty1 to type
/// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
@ -403,7 +407,7 @@ public:
/// \return The maximum interleave factor that any transform should try to
/// perform for this target. This number depends on the level of parallelism
/// and the number of execution units in the CPU.
unsigned getMaxInterleaveFactor() const;
unsigned getMaxInterleaveFactor(unsigned VF) const;
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
unsigned
@ -444,6 +448,20 @@ public:
unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
unsigned AddressSpace) const;
/// \return The cost of the interleaved memory operation.
/// \p Opcode is the memory operation code
/// \p VecTy is the vector type of the interleaved access.
/// \p Factor is the interleave factor
/// \p Indices is the indices for interleaved load members (as interleaved
/// load allows gaps)
/// \p Alignment is the alignment of the memory operation
/// \p AddressSpace is address space of the pointer.
unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
unsigned Factor,
ArrayRef<unsigned> Indices,
unsigned Alignment,
unsigned AddressSpace) const;
/// \brief Calculate the cost of performing a vector reduction.
///
/// This is the cost of reducing the vector value of type \p Ty to a scalar
@ -539,12 +557,13 @@ public:
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
int64_t Scale) = 0;
int64_t Scale,
unsigned AddrSpace) = 0;
virtual bool isLegalMaskedStore(Type *DataType, int Consecutive) = 0;
virtual bool isLegalMaskedLoad(Type *DataType, int Consecutive) = 0;
virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
int64_t Scale) = 0;
int64_t Scale, unsigned AddrSpace) = 0;
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) = 0;
virtual bool isProfitableToHoist(Instruction *I) = 0;
virtual bool isTypeLegal(Type *Ty) = 0;
@ -562,7 +581,7 @@ public:
const APInt &Imm, Type *Ty) = 0;
virtual unsigned getNumberOfRegisters(bool Vector) = 0;
virtual unsigned getRegisterBitWidth(bool Vector) = 0;
virtual unsigned getMaxInterleaveFactor() = 0;
virtual unsigned getMaxInterleaveFactor(unsigned VF) = 0;
virtual unsigned
getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
OperandValueKind Opd2Info,
@ -582,6 +601,11 @@ public:
virtual unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
unsigned Alignment,
unsigned AddressSpace) = 0;
virtual unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
unsigned Factor,
ArrayRef<unsigned> Indices,
unsigned Alignment,
unsigned AddressSpace) = 0;
virtual unsigned getReductionCost(unsigned Opcode, Type *Ty,
bool IsPairwiseForm) = 0;
virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
@ -648,9 +672,10 @@ public:
return Impl.isLegalICmpImmediate(Imm);
}
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale) override {
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace) override {
return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
Scale);
Scale, AddrSpace);
}
bool isLegalMaskedStore(Type *DataType, int Consecutive) override {
return Impl.isLegalMaskedStore(DataType, Consecutive);
@ -659,8 +684,10 @@ public:
return Impl.isLegalMaskedLoad(DataType, Consecutive);
}
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale) override {
return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale);
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace) override {
return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg,
Scale, AddrSpace);
}
bool isTruncateFree(Type *Ty1, Type *Ty2) override {
return Impl.isTruncateFree(Ty1, Ty2);
@ -703,8 +730,8 @@ public:
unsigned getRegisterBitWidth(bool Vector) override {
return Impl.getRegisterBitWidth(Vector);
}
unsigned getMaxInterleaveFactor() override {
return Impl.getMaxInterleaveFactor();
unsigned getMaxInterleaveFactor(unsigned VF) override {
return Impl.getMaxInterleaveFactor(VF);
}
unsigned
getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
@ -740,6 +767,14 @@ public:
unsigned AddressSpace) override {
return Impl.getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
}
unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
unsigned Factor,
ArrayRef<unsigned> Indices,
unsigned Alignment,
unsigned AddressSpace) override {
return Impl.getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
Alignment, AddressSpace);
}
unsigned getReductionCost(unsigned Opcode, Type *Ty,
bool IsPairwiseForm) override {
return Impl.getReductionCost(Opcode, Ty, IsPairwiseForm);

View File

@ -207,10 +207,11 @@ public:
bool isLegalICmpImmediate(int64_t Imm) { return false; }
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale) {
// Guess that reg+reg addressing is allowed. This heuristic is taken from
// the implementation of LSR.
return !BaseGV && BaseOffset == 0 && Scale <= 1;
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace) {
// Guess that only reg and reg+reg addressing is allowed. This heuristic is
// taken from the implementation of LSR.
return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1);
}
bool isLegalMaskedStore(Type *DataType, int Consecutive) { return false; }
@ -218,9 +219,10 @@ public:
bool isLegalMaskedLoad(Type *DataType, int Consecutive) { return false; }
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale) {
bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
// Guess that all legal addressing mode are free.
if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale))
if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
Scale, AddrSpace))
return 0;
return -1;
}
@ -263,7 +265,7 @@ public:
unsigned getRegisterBitWidth(bool Vector) { return 32; }
unsigned getMaxInterleaveFactor() { return 1; }
unsigned getMaxInterleaveFactor(unsigned VF) { return 1; }
unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
TTI::OperandValueKind Opd1Info,
@ -300,6 +302,14 @@ public:
return 1;
}
unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
unsigned Factor,
ArrayRef<unsigned> Indices,
unsigned Alignment,
unsigned AddressSpace) {
return 1;
}
unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
ArrayRef<Type *> Tys) {
return 1;
@ -365,7 +375,7 @@ public:
// function.
NumArgs = F->arg_size();
if (Intrinsic::ID IID = (Intrinsic::ID)F->getIntrinsicID()) {
if (Intrinsic::ID IID = F->getIntrinsicID()) {
FunctionType *FTy = F->getFunctionType();
SmallVector<Type *, 8> ParamTys(FTy->param_begin(), FTy->param_end());
return static_cast<T *>(this)

View File

@ -16,6 +16,7 @@
#define LLVM_ANALYSIS_VALUETRACKING_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/Instruction.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@ -28,6 +29,7 @@ namespace llvm {
class AssumptionCache;
class DominatorTree;
class TargetLibraryInfo;
class LoopInfo;
/// Determine which bits of V are known to be either zero or one and return
/// them in the KnownZero/KnownOne bit sets.
@ -46,6 +48,11 @@ namespace llvm {
/// \p KnownZero the set of bits that are known to be zero
void computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
APInt &KnownZero);
/// Returns true if LHS and RHS have no common bits set.
bool haveNoCommonBitsSet(Value *LHS, Value *RHS, const DataLayout &DL,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around computeKnownBits.
@ -176,16 +183,51 @@ namespace llvm {
return GetUnderlyingObject(const_cast<Value *>(V), DL, MaxLookup);
}
/// GetUnderlyingObjects - This method is similar to GetUnderlyingObject
/// except that it can look through phi and select instructions and return
/// multiple objects.
/// \brief This method is similar to GetUnderlyingObject except that it can
/// look through phi and select instructions and return multiple objects.
///
/// If LoopInfo is passed, loop phis are further analyzed. If a pointer
/// accesses different objects in each iteration, we don't look through the
/// phi node. E.g. consider this loop nest:
///
/// int **A;
/// for (i)
/// for (j) {
/// A[i][j] = A[i-1][j] * B[j]
/// }
///
/// This is transformed by Load-PRE to stash away A[i] for the next iteration
/// of the outer loop:
///
/// Curr = A[0]; // Prev_0
/// for (i: 1..N) {
/// Prev = Curr; // Prev = PHI (Prev_0, Curr)
/// Curr = A[i];
/// for (j: 0..N) {
/// Curr[j] = Prev[j] * B[j]
/// }
/// }
///
/// Since A[i] and A[i-1] are independent pointers, getUnderlyingObjects
/// should not assume that Curr and Prev share the same underlying object thus
/// it shouldn't look through the phi above.
void GetUnderlyingObjects(Value *V, SmallVectorImpl<Value *> &Objects,
const DataLayout &DL, unsigned MaxLookup = 6);
const DataLayout &DL, LoopInfo *LI = nullptr,
unsigned MaxLookup = 6);
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
/// are lifetime markers.
bool onlyUsedByLifetimeMarkers(const Value *V);
/// isDereferenceablePointer - Return true if this is always a dereferenceable
/// pointer. If the context instruction is specified perform context-sensitive
/// analysis and return true if the pointer is dereferenceable at the
/// specified instruction.
bool isDereferenceablePointer(const Value *V, const DataLayout &DL,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr,
const TargetLibraryInfo *TLI = nullptr);
/// isSafeToSpeculativelyExecute - Return true if the instruction does not
/// have any effects besides calculating the result and does not have
/// undefined behavior.
@ -199,18 +241,36 @@ namespace llvm {
/// memory leak. It also returns false for instructions related to control
/// flow, specifically terminators and PHI nodes.
///
/// This method only looks at the instruction itself and its operands, so if
/// this method returns true, it is safe to move the instruction as long as
/// the correct dominance relationships for the operands and users hold.
/// However, this method can return true for instructions that read memory;
/// If the CtxI is specified this method performs context-sensitive analysis
/// and returns true if it is safe to execute the instruction immediately
/// before the CtxI.
///
/// If the CtxI is NOT specified this method only looks at the instruction
/// itself and its operands, so if this method returns true, it is safe to
/// move the instruction as long as the correct dominance relationships for
/// the operands and users hold.
///
/// This method can return true for instructions that read memory;
/// for such instructions, moving them may change the resulting value.
bool isSafeToSpeculativelyExecute(const Value *V);
bool isSafeToSpeculativelyExecute(const Value *V,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr,
const TargetLibraryInfo *TLI = nullptr);
/// isKnownNonNull - Return true if this pointer couldn't possibly be null by
/// its definition. This returns true for allocas, non-extern-weak globals
/// and byval arguments.
bool isKnownNonNull(const Value *V, const TargetLibraryInfo *TLI = nullptr);
/// isKnownNonNullAt - Return true if this pointer couldn't possibly be null.
/// If the context instruction is specified perform context-sensitive analysis
/// and return true if the pointer couldn't possibly be null at the specified
/// instruction.
bool isKnownNonNullAt(const Value *V,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr,
const TargetLibraryInfo *TLI = nullptr);
/// Return true if it is valid to use the assumptions provided by an
/// assume intrinsic, I, at the point in the control-flow identified by the
/// context instruction, CxtI.
@ -228,6 +288,35 @@ namespace llvm {
AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT);
/// \brief Specific patterns of select instructions we can match.
enum SelectPatternFlavor {
SPF_UNKNOWN = 0,
SPF_SMIN, // Signed minimum
SPF_UMIN, // Unsigned minimum
SPF_SMAX, // Signed maximum
SPF_UMAX, // Unsigned maximum
SPF_ABS, // Absolute value
SPF_NABS // Negated absolute value
};
/// Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind
/// and providing the out parameter results if we successfully match.
///
/// If CastOp is not nullptr, also match MIN/MAX idioms where the type does
/// not match that of the original select. If this is the case, the cast
/// operation (one of Trunc,SExt,Zext) that must be done to transform the
/// type of LHS and RHS into the type of V is returned in CastOp.
///
/// For example:
/// %1 = icmp slt i32 %a, i32 4
/// %2 = sext i32 %a to i64
/// %3 = select i1 %1, i64 %2, i64 4
///
/// -> LHS = %a, RHS = i32 4, *CastOp = Instruction::SExt
///
SelectPatternFlavor matchSelectPattern(Value *V, Value *&LHS, Value *&RHS,
Instruction::CastOps *CastOp = nullptr);
} // end namespace llvm
#endif

View File

@ -113,7 +113,7 @@ public:
return *const_cast<BlockInfo*>(BI);
// Otherwise, add a new record.
BlockInfoRecords.push_back(BlockInfo());
BlockInfoRecords.emplace_back();
BlockInfoRecords.back().BlockID = BlockID;
return BlockInfoRecords.back();
}
@ -198,6 +198,8 @@ class BitstreamCursor {
public:
static const size_t MaxChunkSize = sizeof(word_t) * 8;
BitstreamCursor() { init(nullptr); }
explicit BitstreamCursor(BitstreamReader &R) { init(&R); }
@ -335,7 +337,7 @@ public:
}
word_t Read(unsigned NumBits) {
static const unsigned BitsInWord = sizeof(word_t) * 8;
static const unsigned BitsInWord = MaxChunkSize;
assert(NumBits && NumBits <= BitsInWord &&
"Cannot return zero or more than BitsInWord bits!");

View File

@ -215,7 +215,7 @@ public:
// Push the outer block's abbrev set onto the stack, start out with an
// empty abbrev set.
BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex));
BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex);
BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
// If there is a blockinfo for this BlockID, add all the predefined abbrevs
@ -503,7 +503,7 @@ private:
return *BI;
// Otherwise, add a new record.
BlockInfoRecords.push_back(BlockInfo());
BlockInfoRecords.emplace_back();
BlockInfoRecords.back().BlockID = BlockID;
return BlockInfoRecords.back();
}

View File

@ -318,7 +318,7 @@ namespace bitc {
// This store code encodes the pointer type, rather than the value type
// this is so information only available in the pointer type (e.g. address
// spaces) is retained.
FUNC_CODE_INST_STORE = 24, // STORE: [ptrty,ptr,val, align, vol]
FUNC_CODE_INST_STORE_OLD = 24, // STORE: [ptrty,ptr,val, align, vol]
// 25 is unused.
FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands]
FUNC_CODE_INST_INSERTVAL = 27, // INSERTVAL: [n x operands]
@ -336,7 +336,7 @@ namespace bitc {
FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope]
FUNC_CODE_INST_CMPXCHG = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
FUNC_CODE_INST_CMPXCHG_OLD = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
// ordering, synchscope]
FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation,
// align, vol,
@ -345,9 +345,13 @@ namespace bitc {
FUNC_CODE_INST_LANDINGPAD = 40, // LANDINGPAD: [ty,val,val,num,id0,val0...]
FUNC_CODE_INST_LOADATOMIC = 41, // LOAD: [opty, op, align, vol,
// ordering, synchscope]
FUNC_CODE_INST_STOREATOMIC = 42, // STORE: [ptrty,ptr,val, align, vol
FUNC_CODE_INST_STOREATOMIC_OLD = 42, // STORE: [ptrty,ptr,val, align, vol
// ordering, synchscope]
FUNC_CODE_INST_GEP = 43, // GEP: [inbounds, n x operands]
FUNC_CODE_INST_STORE = 44, // STORE: [ptrty,ptr,valty,val, align, vol]
FUNC_CODE_INST_STOREATOMIC = 45, // STORE: [ptrty,ptr,val, align, vol
FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty,ptr,valty,cmp,new, align,
// vol,ordering,synchscope]
};
enum UseListCodes {
@ -398,7 +402,9 @@ namespace bitc {
ATTR_KIND_NON_NULL = 39,
ATTR_KIND_JUMP_TABLE = 40,
ATTR_KIND_DEREFERENCEABLE = 41,
ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42
ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42,
ATTR_KIND_CONVERGENT = 43,
ATTR_KIND_SAFESTACK = 44,
};
enum ComdatSelectionKindCodes {

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@ -53,6 +54,7 @@ class MCSection;
class MCStreamer;
class MCSubtargetInfo;
class MCSymbol;
class MCTargetOptions;
class MDNode;
class DwarfDebug;
class Mangler;
@ -78,7 +80,7 @@ public:
/// This is the MCStreamer object for the file we are generating. This
/// contains the transient state for the current translation unit that we are
/// generating (such as the current section etc).
MCStreamer &OutStreamer;
std::unique_ptr<MCStreamer> OutStreamer;
/// The current machine function.
const MachineFunction *MF;
@ -421,6 +423,13 @@ public:
/// or by emitting it as an offset from a label at the start of the section.
void emitSectionOffset(const MCSymbol *Label) const;
/// Emit the 4-byte offset of a string from the start of its section.
///
/// When possible, emit a DwarfStringPool section offset without any
/// relocations, and without using the symbol. Otherwise, defers to \a
/// emitSectionOffset().
void emitDwarfStringOffset(DwarfStringPoolEntryRef S) const;
/// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
virtual unsigned getISAEncoding() { return 0; }
@ -493,11 +502,12 @@ private:
mutable unsigned Counter;
/// This method emits the header for the current function.
void EmitFunctionHeader();
virtual void EmitFunctionHeader();
/// Emit a blob of inline asm to the output streamer.
void
EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
const MCTargetOptions &MCOptions,
const MDNode *LocMDNode = nullptr,
InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;

View File

@ -125,23 +125,24 @@ public:
}
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale) {
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace) {
TargetLoweringBase::AddrMode AM;
AM.BaseGV = BaseGV;
AM.BaseOffs = BaseOffset;
AM.HasBaseReg = HasBaseReg;
AM.Scale = Scale;
return getTLI()->isLegalAddressingMode(AM, Ty);
return getTLI()->isLegalAddressingMode(AM, Ty, AddrSpace);
}
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale) {
bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
TargetLoweringBase::AddrMode AM;
AM.BaseGV = BaseGV;
AM.BaseOffs = BaseOffset;
AM.HasBaseReg = HasBaseReg;
AM.Scale = Scale;
return getTLI()->getScalingFactorCost(AM, Ty);
return getTLI()->getScalingFactorCost(AM, Ty, AddrSpace);
}
bool isTruncateFree(Type *Ty1, Type *Ty2) {
@ -285,7 +286,7 @@ public:
unsigned getRegisterBitWidth(bool Vector) { return 32; }
unsigned getMaxInterleaveFactor() { return 1; }
unsigned getMaxInterleaveFactor(unsigned VF) { return 1; }
unsigned getArithmeticInstrCost(
unsigned Opcode, Type *Ty,
@ -522,6 +523,73 @@ public:
return Cost;
}
unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
unsigned Factor,
ArrayRef<unsigned> Indices,
unsigned Alignment,
unsigned AddressSpace) {
VectorType *VT = dyn_cast<VectorType>(VecTy);
assert(VT && "Expect a vector type for interleaved memory op");
unsigned NumElts = VT->getNumElements();
assert(Factor > 1 && NumElts % Factor == 0 && "Invalid interleave factor");
unsigned NumSubElts = NumElts / Factor;
VectorType *SubVT = VectorType::get(VT->getElementType(), NumSubElts);
// Firstly, the cost of load/store operation.
unsigned Cost = getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace);
// Then plus the cost of interleave operation.
if (Opcode == Instruction::Load) {
// The interleave cost is similar to extract sub vectors' elements
// from the wide vector, and insert them into sub vectors.
//
// E.g. An interleaved load of factor 2 (with one member of index 0):
// %vec = load <8 x i32>, <8 x i32>* %ptr
// %v0 = shuffle %vec, undef, <0, 2, 4, 6> ; Index 0
// The cost is estimated as extract elements at 0, 2, 4, 6 from the
// <8 x i32> vector and insert them into a <4 x i32> vector.
assert(Indices.size() <= Factor &&
"Interleaved memory op has too many members");
for (unsigned Index : Indices) {
assert(Index < Factor && "Invalid index for interleaved memory op");
// Extract elements from loaded vector for each sub vector.
for (unsigned i = 0; i < NumSubElts; i++)
Cost += getVectorInstrCost(Instruction::ExtractElement, VT,
Index + i * Factor);
}
unsigned InsSubCost = 0;
for (unsigned i = 0; i < NumSubElts; i++)
InsSubCost += getVectorInstrCost(Instruction::InsertElement, SubVT, i);
Cost += Indices.size() * InsSubCost;
} else {
// The interleave cost is extract all elements from sub vectors, and
// insert them into the wide vector.
//
// E.g. An interleaved store of factor 2:
// %v0_v1 = shuffle %v0, %v1, <0, 4, 1, 5, 2, 6, 3, 7>
// store <8 x i32> %interleaved.vec, <8 x i32>* %ptr
// The cost is estimated as extract all elements from both <4 x i32>
// vectors and insert into the <8 x i32> vector.
unsigned ExtSubCost = 0;
for (unsigned i = 0; i < NumSubElts; i++)
ExtSubCost += getVectorInstrCost(Instruction::ExtractElement, SubVT, i);
Cost += Factor * ExtSubCost;
for (unsigned i = 0; i < NumElts; i++)
Cost += getVectorInstrCost(Instruction::InsertElement, VT, i);
}
return Cost;
}
unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<Type *> Tys) {
unsigned ISD = 0;

View File

@ -19,6 +19,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Target/TargetCallingConv.h"
namespace llvm {

View File

@ -16,11 +16,16 @@
#ifndef LLVM_CODEGEN_COMMANDFLAGS_H
#define LLVM_CODEGEN_COMMANDFLAGS_H
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm//MC/SubtargetFeature.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Host.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRecip.h"
#include <string>
using namespace llvm;
@ -123,11 +128,6 @@ EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
cl::desc("Force codegen to assume rounding mode can change dynamically"),
cl::init(false));
cl::opt<bool>
GenerateSoftFloatCalls("soft-float",
cl::desc("Generate software floating point library calls"),
cl::init(false));
cl::opt<llvm::FloatABI::ABIType>
FloatABIForCalls("float-abi",
cl::desc("Choose float ABI type"),
@ -151,9 +151,15 @@ FuseFPOps("fp-contract",
clEnumValN(FPOpFusion::Standard, "on",
"Only fuse 'blessed' FP ops."),
clEnumValN(FPOpFusion::Strict, "off",
"Only fuse FP ops when the result won't be effected."),
"Only fuse FP ops when the result won't be affected."),
clEnumValEnd));
cl::list<std::string>
ReciprocalOps("recip",
cl::CommaSeparated,
cl::desc("Choose reciprocal operation types and parameters."),
cl::value_desc("all,none,default,divf,!vec-sqrtd,vec-divd:0,sqrt:9..."));
cl::opt<bool>
DontPlaceZerosInBSS("nozero-initialized-in-bss",
cl::desc("Don't place zero-initialized symbols into bss section"),
@ -226,62 +232,22 @@ JTableType("jump-table-type",
"Create one table per unique function type."),
clEnumValEnd));
cl::opt<bool>
FCFI("fcfi",
cl::desc("Apply forward-edge control-flow integrity"),
cl::init(false));
cl::opt<llvm::CFIntegrity>
CFIType("cfi-type",
cl::desc("Choose the type of Control-Flow Integrity check to add"),
cl::init(CFIntegrity::Sub),
cl::values(
clEnumValN(CFIntegrity::Sub, "sub",
"Subtract the pointer from the table base, then mask."),
clEnumValN(CFIntegrity::Ror, "ror",
"Use rotate to check the offset from a table base."),
clEnumValN(CFIntegrity::Add, "add",
"Mask out the high bits and add to an aligned base."),
clEnumValEnd));
cl::opt<bool>
CFIEnforcing("cfi-enforcing",
cl::desc("Enforce CFI or pass the violation to a function."),
cl::init(false));
// Note that this option is linked to the cfi-enforcing option above: if
// cfi-enforcing is set, then the cfi-func-name option is entirely ignored. If
// cfi-enforcing is false and no cfi-func-name is set, then a default function
// will be generated that ignores all CFI violations. The expected signature for
// functions called with CFI violations is
//
// void (i8*, i8*)
//
// The first pointer is a C string containing the name of the function in which
// the violation occurs, and the second pointer is the pointer that violated
// CFI.
cl::opt<std::string>
CFIFuncName("cfi-func-name", cl::desc("The name of the CFI function to call"),
cl::init(""));
// Common utility function tightly tied to the options listed here. Initializes
// a TargetOptions object with CodeGen flags and returns it.
static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
TargetOptions Options;
Options.LessPreciseFPMADOption = EnableFPMAD;
Options.NoFramePointerElim = DisableFPElim;
Options.AllowFPOpFusion = FuseFPOps;
Options.Reciprocals = TargetRecip(ReciprocalOps);
Options.UnsafeFPMath = EnableUnsafeFPMath;
Options.NoInfsFPMath = EnableNoInfsFPMath;
Options.NoNaNsFPMath = EnableNoNaNsFPMath;
Options.HonorSignDependentRoundingFPMathOption =
EnableHonorSignDependentRoundingFPMath;
Options.UseSoftFloat = GenerateSoftFloatCalls;
if (FloatABIForCalls != FloatABI::Default)
Options.FloatABIType = FloatABIForCalls;
Options.NoZerosInBSS = DontPlaceZerosInBSS;
Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
Options.DisableTailCalls = DisableTailCalls;
Options.StackAlignmentOverride = OverrideStackAlignment;
Options.TrapFuncName = TrapFuncName;
Options.PositionIndependentExecutable = EnablePIE;
@ -292,14 +258,72 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
Options.MCOptions = InitMCTargetOptionsFromFlags();
Options.JTType = JTableType;
Options.FCFI = FCFI;
Options.CFIType = CFIType;
Options.CFIEnforcing = CFIEnforcing;
Options.CFIFuncName = CFIFuncName;
Options.ThreadModel = TMModel;
return Options;
}
static inline std::string getCPUStr() {
// If user asked for the 'native' CPU, autodetect here. If autodection fails,
// this will set the CPU to an empty string which tells the target to
// pick a basic default.
if (MCPU == "native")
return sys::getHostCPUName();
return MCPU;
}
static inline std::string getFeaturesStr() {
SubtargetFeatures Features;
// If user asked for the 'native' CPU, we need to autodetect features.
// This is necessary for x86 where the CPU might not support all the
// features the autodetected CPU name lists in the target. For example,
// not all Sandybridge processors support AVX.
if (MCPU == "native") {
StringMap<bool> HostFeatures;
if (sys::getHostCPUFeatures(HostFeatures))
for (auto &F : HostFeatures)
Features.AddFeature(F.first(), F.second);
}
for (unsigned i = 0; i != MAttrs.size(); ++i)
Features.AddFeature(MAttrs[i]);
return Features.getString();
}
/// \brief Set function attributes of functions in Module M based on CPU,
/// Features, and command line flags.
static inline void setFunctionAttributes(StringRef CPU, StringRef Features,
Module &M) {
for (auto &F : M) {
auto &Ctx = F.getContext();
AttributeSet Attrs = F.getAttributes(), NewAttrs;
if (!CPU.empty())
NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
"target-cpu", CPU);
if (!Features.empty())
NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
"target-features", Features);
if (DisableFPElim.getNumOccurrences() > 0)
NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
"no-frame-pointer-elim",
DisableFPElim ? "true" : "false");
if (DisableTailCalls.getNumOccurrences() > 0)
NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
"disable-tail-calls",
toStringRef(DisableTailCalls));
// Let NewAttrs override Attrs.
NewAttrs = Attrs.addAttributes(Ctx, AttributeSet::FunctionIndex, NewAttrs);
F.setAttributes(NewAttrs);
}
}
#endif

View File

@ -16,6 +16,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/Support/Dwarf.h"
#include <vector>
@ -103,153 +104,14 @@ public:
#endif
};
//===--------------------------------------------------------------------===//
/// DIE - A structured debug information entry. Has an abbreviation which
/// describes its organization.
class DIEValue;
class DIE {
protected:
/// Offset - Offset in debug info section.
///
unsigned Offset;
/// Size - Size of instance + children.
///
unsigned Size;
/// Abbrev - Buffer for constructing abbreviation.
///
DIEAbbrev Abbrev;
/// Children DIEs.
///
// This can't be a vector<DIE> because pointer validity is requirent for the
// Parent pointer and DIEEntry.
// It can't be a list<DIE> because some clients need pointer validity before
// the object has been added to any child list
// (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
// be more convoluted than beneficial.
std::vector<std::unique_ptr<DIE>> Children;
DIE *Parent;
/// Attribute values.
///
SmallVector<DIEValue *, 12> Values;
protected:
DIE()
: Offset(0), Size(0), Abbrev((dwarf::Tag)0, dwarf::DW_CHILDREN_no),
Parent(nullptr) {}
public:
explicit DIE(dwarf::Tag Tag)
: Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no),
Parent(nullptr) {}
// Accessors.
DIEAbbrev &getAbbrev() { return Abbrev; }
const DIEAbbrev &getAbbrev() const { return Abbrev; }
unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
dwarf::Tag getTag() const { return Abbrev.getTag(); }
unsigned getOffset() const { return Offset; }
unsigned getSize() const { return Size; }
const std::vector<std::unique_ptr<DIE>> &getChildren() const {
return Children;
}
const SmallVectorImpl<DIEValue *> &getValues() const { return Values; }
DIE *getParent() const { return Parent; }
/// Climb up the parent chain to get the compile or type unit DIE this DIE
/// belongs to.
const DIE *getUnit() const;
/// Similar to getUnit, returns null when DIE is not added to an
/// owner yet.
const DIE *getUnitOrNull() const;
void setOffset(unsigned O) { Offset = O; }
void setSize(unsigned S) { Size = S; }
/// addValue - Add a value and attributes to a DIE.
///
void addValue(dwarf::Attribute Attribute, dwarf::Form Form, DIEValue *Value) {
Abbrev.AddAttribute(Attribute, Form);
Values.push_back(Value);
}
/// addChild - Add a child to the DIE.
///
void addChild(std::unique_ptr<DIE> Child) {
assert(!Child->getParent());
Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
Child->Parent = this;
Children.push_back(std::move(Child));
}
/// findAttribute - Find a value in the DIE with the attribute given,
/// returns NULL if no such attribute exists.
DIEValue *findAttribute(dwarf::Attribute Attribute) const;
#ifndef NDEBUG
void print(raw_ostream &O, unsigned IndentCount = 0) const;
void dump();
#endif
};
//===--------------------------------------------------------------------===//
/// DIEValue - A debug information entry value. Some of these roughly correlate
/// to DWARF attribute classes.
///
class DIEValue {
virtual void anchor();
public:
enum Type {
isInteger,
isString,
isExpr,
isLabel,
isDelta,
isEntry,
isTypeSignature,
isBlock,
isLoc,
isLocList,
};
protected:
/// Ty - Type of data stored in the value.
///
Type Ty;
explicit DIEValue(Type T) : Ty(T) {}
virtual ~DIEValue() {}
public:
// Accessors
Type getType() const { return Ty; }
/// EmitValue - Emit value via the Dwarf writer.
///
virtual void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const = 0;
/// SizeOf - Return the size of a value in bytes.
///
virtual unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const = 0;
#ifndef NDEBUG
virtual void print(raw_ostream &O) const = 0;
void dump() const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEInteger - An integer value DIE.
///
class DIEInteger : public DIEValue {
class DIEInteger {
uint64_t Integer;
public:
explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
explicit DIEInteger(uint64_t I) : Integer(I) {}
/// BestForm - Choose the best form for integer.
///
@ -273,137 +135,94 @@ public:
return dwarf::DW_FORM_data8;
}
/// EmitValue - Emit integer of appropriate size.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
uint64_t getValue() const { return Integer; }
void setValue(uint64_t Val) { Integer = Val; }
/// SizeOf - Determine size of integer value in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *I) { return I->getType() == isInteger; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEExpr - An expression DIE.
//
class DIEExpr : public DIEValue {
class DIEExpr {
const MCExpr *Expr;
public:
explicit DIEExpr(const MCExpr *E) : DIEValue(isExpr), Expr(E) {}
/// EmitValue - Emit expression value.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
explicit DIEExpr(const MCExpr *E) : Expr(E) {}
/// getValue - Get MCExpr.
///
const MCExpr *getValue() const { return Expr; }
/// SizeOf - Determine size of expression value in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isExpr; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIELabel - A label DIE.
//
class DIELabel : public DIEValue {
class DIELabel {
const MCSymbol *Label;
public:
explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {}
/// EmitValue - Emit label value.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
explicit DIELabel(const MCSymbol *L) : Label(L) {}
/// getValue - Get MCSymbol.
///
const MCSymbol *getValue() const { return Label; }
/// SizeOf - Determine size of label value in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEDelta - A simple label difference DIE.
///
class DIEDelta : public DIEValue {
class DIEDelta {
const MCSymbol *LabelHi;
const MCSymbol *LabelLo;
public:
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo)
: DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {}
/// EmitValue - Emit delta value.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of delta value in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *D) { return D->getType() == isDelta; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEString - A container for string values.
///
class DIEString : public DIEValue {
const DIEValue *Access;
StringRef Str;
class DIEString {
DwarfStringPoolEntryRef S;
public:
DIEString(const DIEValue *Acc, StringRef S)
: DIEValue(isString), Access(Acc), Str(S) {}
DIEString(DwarfStringPoolEntryRef S) : S(S) {}
/// getString - Grab the string out of the object.
StringRef getString() const { return Str; }
StringRef getString() const { return S.getString(); }
/// EmitValue - Emit delta value.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of delta value in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *D) { return D->getType() == isString; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};
@ -411,72 +230,350 @@ public:
/// DIEEntry - A pointer to another debug information entry. An instance of
/// this class can also be used as a proxy for a debug information entry not
/// yet defined (ie. types.)
class DIEEntry : public DIEValue {
DIE &Entry;
class DIE;
class DIEEntry {
DIE *Entry;
DIEEntry() = delete;
public:
explicit DIEEntry(DIE &E) : DIEValue(isEntry), Entry(E) {
}
explicit DIEEntry(DIE &E) : Entry(&E) {}
DIE &getEntry() const { return Entry; }
/// EmitValue - Emit debug information entry offset.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of debug information entry in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override {
return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP)
: sizeof(int32_t);
}
DIE &getEntry() const { return *Entry; }
/// Returns size of a ref_addr entry.
static unsigned getRefAddrSize(const AsmPrinter *AP);
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isEntry; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP)
: sizeof(int32_t);
}
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// \brief A signature reference to a type unit.
class DIETypeSignature : public DIEValue {
const DwarfTypeUnit &Unit;
class DIETypeSignature {
const DwarfTypeUnit *Unit;
DIETypeSignature() = delete;
public:
explicit DIETypeSignature(const DwarfTypeUnit &Unit)
: DIEValue(isTypeSignature), Unit(Unit) {}
explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {}
/// \brief Emit type unit signature.
void EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const override;
/// Returns size of a ref_sig8 entry.
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override {
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
assert(Form == dwarf::DW_FORM_ref_sig8);
return 8;
}
// \brief Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) {
return E->getType() == isTypeSignature;
}
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIELocList - Represents a pointer to a location list in the debug_loc
/// section.
//
class DIELocList {
// Index into the .debug_loc vector.
size_t Index;
public:
DIELocList(size_t I) : Index(I) {}
/// getValue - Grab the current index out.
size_t getValue() const { return Index; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEValue - A debug information entry value. Some of these roughly correlate
/// to DWARF attribute classes.
///
class DIEBlock;
class DIELoc;
class DIEValue {
public:
enum Type {
isNone,
#define HANDLE_DIEVALUE(T) is##T,
#include "llvm/CodeGen/DIEValue.def"
};
private:
/// Ty - Type of data stored in the value.
///
Type Ty = isNone;
dwarf::Attribute Attribute = (dwarf::Attribute)0;
dwarf::Form Form = (dwarf::Form)0;
/// Storage for the value.
///
/// All values that aren't standard layout (or are larger than 8 bytes)
/// should be stored by reference instead of by value.
typedef AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
DIEDelta *, DIEEntry, DIETypeSignature,
DIEBlock *, DIELoc *, DIELocList> ValTy;
static_assert(sizeof(ValTy) <= sizeof(uint64_t) ||
sizeof(ValTy) <= sizeof(void *),
"Expected all large types to be stored via pointer");
/// Underlying stored value.
ValTy Val;
template <class T> void construct(T V) {
static_assert(std::is_standard_layout<T>::value ||
std::is_pointer<T>::value,
"Expected standard layout or pointer");
new (reinterpret_cast<void *>(Val.buffer)) T(V);
}
template <class T> T *get() { return reinterpret_cast<T *>(Val.buffer); }
template <class T> const T *get() const {
return reinterpret_cast<const T *>(Val.buffer);
}
template <class T> void destruct() { get<T>()->~T(); }
/// Destroy the underlying value.
///
/// This should get optimized down to a no-op. We could skip it if we could
/// add a static assert on \a std::is_trivially_copyable(), but we currently
/// support versions of GCC that don't understand that.
void destroyVal() {
switch (Ty) {
case isNone:
return;
#define HANDLE_DIEVALUE_SMALL(T) \
case is##T: \
destruct<DIE##T>();
return;
#define HANDLE_DIEVALUE_LARGE(T) \
case is##T: \
destruct<const DIE##T *>();
return;
#include "llvm/CodeGen/DIEValue.def"
}
}
/// Copy the underlying value.
///
/// This should get optimized down to a simple copy. We need to actually
/// construct the value, rather than calling memcpy, to satisfy strict
/// aliasing rules.
void copyVal(const DIEValue &X) {
switch (Ty) {
case isNone:
return;
#define HANDLE_DIEVALUE_SMALL(T) \
case is##T: \
construct<DIE##T>(*X.get<DIE##T>()); \
return;
#define HANDLE_DIEVALUE_LARGE(T) \
case is##T: \
construct<const DIE##T *>(*X.get<const DIE##T *>()); \
return;
#include "llvm/CodeGen/DIEValue.def"
}
}
public:
DIEValue() = default;
DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) {
copyVal(X);
}
DIEValue &operator=(const DIEValue &X) {
destroyVal();
Ty = X.Ty;
Attribute = X.Attribute;
Form = X.Form;
copyVal(X);
return *this;
}
~DIEValue() { destroyVal(); }
#define HANDLE_DIEVALUE_SMALL(T) \
DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \
: Ty(is##T), Attribute(Attribute), Form(Form) { \
construct<DIE##T>(V); \
}
#define HANDLE_DIEVALUE_LARGE(T) \
DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \
: Ty(is##T), Attribute(Attribute), Form(Form) { \
assert(V && "Expected valid value"); \
construct<const DIE##T *>(V); \
}
#include "llvm/CodeGen/DIEValue.def"
// Accessors
Type getType() const { return Ty; }
dwarf::Attribute getAttribute() const { return Attribute; }
dwarf::Form getForm() const { return Form; }
explicit operator bool() const { return Ty; }
#define HANDLE_DIEVALUE_SMALL(T) \
const DIE##T &getDIE##T() const { \
assert(getType() == is##T && "Expected " #T); \
return *get<DIE##T>(); \
}
#define HANDLE_DIEVALUE_LARGE(T) \
const DIE##T &getDIE##T() const { \
assert(getType() == is##T && "Expected " #T); \
return **get<const DIE##T *>(); \
}
#include "llvm/CodeGen/DIEValue.def"
/// EmitValue - Emit value via the Dwarf writer.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
/// SizeOf - Return the size of a value in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void dump() const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIE - A structured debug information entry. Has an abbreviation which
/// describes its organization.
class DIE {
protected:
/// Offset - Offset in debug info section.
///
unsigned Offset;
/// Size - Size of instance + children.
///
unsigned Size;
unsigned AbbrevNumber = ~0u;
/// Tag - Dwarf tag code.
///
dwarf::Tag Tag = (dwarf::Tag)0;
/// Children DIEs.
///
// This can't be a vector<DIE> because pointer validity is requirent for the
// Parent pointer and DIEEntry.
// It can't be a list<DIE> because some clients need pointer validity before
// the object has been added to any child list
// (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
// be more convoluted than beneficial.
std::vector<std::unique_ptr<DIE>> Children;
DIE *Parent;
/// Attribute values.
///
SmallVector<DIEValue, 12> Values;
protected:
DIE() : Offset(0), Size(0), Parent(nullptr) {}
public:
explicit DIE(dwarf::Tag Tag)
: Offset(0), Size(0), Tag(Tag), Parent(nullptr) {}
// Accessors.
unsigned getAbbrevNumber() const { return AbbrevNumber; }
dwarf::Tag getTag() const { return Tag; }
unsigned getOffset() const { return Offset; }
unsigned getSize() const { return Size; }
bool hasChildren() const { return !Children.empty(); }
typedef std::vector<std::unique_ptr<DIE>>::const_iterator child_iterator;
typedef iterator_range<child_iterator> child_range;
child_range children() const {
return llvm::make_range(Children.begin(), Children.end());
}
typedef SmallVectorImpl<DIEValue>::const_iterator value_iterator;
typedef iterator_range<value_iterator> value_range;
value_iterator values_begin() const { return Values.begin(); }
value_iterator values_end() const { return Values.end(); }
value_range values() const {
return llvm::make_range(values_begin(), values_end());
}
void setValue(unsigned I, DIEValue New) {
assert(I < Values.size());
Values[I] = New;
}
DIE *getParent() const { return Parent; }
/// Generate the abbreviation for this DIE.
///
/// Calculate the abbreviation for this, which should be uniqued and
/// eventually used to call \a setAbbrevNumber().
DIEAbbrev generateAbbrev() const;
/// Set the abbreviation number for this DIE.
void setAbbrevNumber(unsigned I) { AbbrevNumber = I; }
/// Climb up the parent chain to get the compile or type unit DIE this DIE
/// belongs to.
const DIE *getUnit() const;
/// Similar to getUnit, returns null when DIE is not added to an
/// owner yet.
const DIE *getUnitOrNull() const;
void setOffset(unsigned O) { Offset = O; }
void setSize(unsigned S) { Size = S; }
/// addValue - Add a value and attributes to a DIE.
///
void addValue(DIEValue Value) { Values.push_back(Value); }
template <class T>
void addValue(dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) {
Values.emplace_back(Attribute, Form, std::forward<T>(Value));
}
/// addChild - Add a child to the DIE.
///
DIE &addChild(std::unique_ptr<DIE> Child) {
assert(!Child->getParent());
Child->Parent = this;
Children.push_back(std::move(Child));
return *Children.back();
}
/// Find a value in the DIE with the attribute given.
///
/// Returns a default-constructed DIEValue (where \a DIEValue::getType()
/// gives \a DIEValue::isNone) if no such attribute exists.
DIEValue findAttribute(dwarf::Attribute Attribute) const;
#ifndef NDEBUG
void print(raw_ostream &O, unsigned IndentCount = 0) const;
void dump();
#endif
};
//===--------------------------------------------------------------------===//
/// DIELoc - Represents an expression location.
//
class DIELoc : public DIEValue, public DIE {
class DIELoc : public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
public:
DIELoc() : DIEValue(isLoc), Size(0) {}
DIELoc() : Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@ -497,29 +594,22 @@ public:
return dwarf::DW_FORM_block;
}
/// EmitValue - Emit location data.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of location data in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isLoc; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEBlock - Represents a block of values.
//
class DIEBlock : public DIEValue, public DIE {
class DIEBlock : public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
public:
DIEBlock() : DIEValue(isBlock), Size(0) {}
DIEBlock() : Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@ -537,49 +627,11 @@ public:
return dwarf::DW_FORM_block;
}
/// EmitValue - Emit location data.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of location data in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const override;
#endif
};
//===--------------------------------------------------------------------===//
/// DIELocList - Represents a pointer to a location list in the debug_loc
/// section.
//
class DIELocList : public DIEValue {
// Index into the .debug_loc vector.
size_t Index;
public:
DIELocList(size_t I) : DIEValue(isLocList), Index(I) {}
/// getValue - Grab the current index out.
size_t getValue() const { return Index; }
/// EmitValue - Emit location data.
///
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of location data in bytes.
///
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isLocList; }
#ifndef NDEBUG
void print(raw_ostream &O) const override;
void print(raw_ostream &O) const;
#endif
};

View File

@ -0,0 +1,47 @@
//===- llvm/CodeGen/DIEValue.def - DIEValue types ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Macros for running through all types of DIEValue.
//
//===----------------------------------------------------------------------===//
#if !(defined HANDLE_DIEVALUE || defined HANDLE_DIEVALUE_SMALL || \
defined HANDLE_DIEVALUE_LARGE)
#error "Missing macro definition of HANDLE_DIEVALUE"
#endif
// Handler for all values.
#ifndef HANDLE_DIEVALUE
#define HANDLE_DIEVALUE(T)
#endif
// Handler for small values.
#ifndef HANDLE_DIEVALUE_SMALL
#define HANDLE_DIEVALUE_SMALL(T) HANDLE_DIEVALUE(T)
#endif
// Handler for large values.
#ifndef HANDLE_DIEVALUE_LARGE
#define HANDLE_DIEVALUE_LARGE(T) HANDLE_DIEVALUE(T)
#endif
HANDLE_DIEVALUE_SMALL(Integer)
HANDLE_DIEVALUE_SMALL(String)
HANDLE_DIEVALUE_SMALL(Expr)
HANDLE_DIEVALUE_SMALL(Label)
HANDLE_DIEVALUE_LARGE(Delta)
HANDLE_DIEVALUE_SMALL(Entry)
HANDLE_DIEVALUE_SMALL(TypeSignature)
HANDLE_DIEVALUE_LARGE(Block)
HANDLE_DIEVALUE_LARGE(Loc)
HANDLE_DIEVALUE_SMALL(LocList)
#undef HANDLE_DIEVALUE
#undef HANDLE_DIEVALUE_SMALL
#undef HANDLE_DIEVALUE_LARGE

View File

@ -0,0 +1,51 @@
//===- llvm/CodeGen/DwarfStringPoolEntry.h - String pool entry --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_DWARFSTRINGPOOLENTRY_H
#define LLVM_CODEGEN_DWARFSTRINGPOOLENTRY_H
#include "llvm/ADT/StringMap.h"
namespace llvm {
class MCSymbol;
/// Data for a string pool entry.
struct DwarfStringPoolEntry {
MCSymbol *Symbol;
unsigned Offset;
unsigned Index;
};
/// String pool entry reference.
struct DwarfStringPoolEntryRef {
const StringMapEntry<DwarfStringPoolEntry> *I = nullptr;
public:
DwarfStringPoolEntryRef() = default;
explicit DwarfStringPoolEntryRef(
const StringMapEntry<DwarfStringPoolEntry> &I)
: I(&I) {}
explicit operator bool() const { return I; }
MCSymbol *getSymbol() const {
assert(I->second.Symbol && "No symbol available!");
return I->second.Symbol;
}
unsigned getOffset() const { return I->second.Offset; }
unsigned getIndex() const { return I->second.Index; }
StringRef getString() const { return I->first(); }
bool operator==(const DwarfStringPoolEntryRef &X) const { return I == X.I; }
bool operator!=(const DwarfStringPoolEntryRef &X) const { return I != X.I; }
};
} // end namespace llvm
#endif

View File

@ -0,0 +1,73 @@
//===------------------- FaultMaps.h - StackMaps ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_FAULTMAPS_H
#define LLVM_CODEGEN_FAULTMAPS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/MC/MCSymbol.h"
#include <vector>
#include <map>
namespace llvm {
class AsmPrinter;
class MCExpr;
class MCSymbol;
class MCStreamer;
class FaultMaps {
public:
enum FaultKind { FaultingLoad = 1, FaultKindMax };
static const char *faultTypeToString(FaultKind);
explicit FaultMaps(AsmPrinter &AP);
void recordFaultingOp(FaultKind FaultTy, const MCSymbol *HandlerLabel);
void serializeToFaultMapSection();
private:
static const char *WFMP;
struct FaultInfo {
FaultKind Kind;
const MCExpr *FaultingOffsetExpr;
const MCExpr *HandlerOffsetExpr;
FaultInfo()
: Kind(FaultKindMax), FaultingOffsetExpr(nullptr),
HandlerOffsetExpr(nullptr) {}
explicit FaultInfo(FaultMaps::FaultKind Kind, const MCExpr *FaultingOffset,
const MCExpr *HandlerOffset)
: Kind(Kind), FaultingOffsetExpr(FaultingOffset),
HandlerOffsetExpr(HandlerOffset) {}
};
typedef std::vector<FaultInfo> FunctionFaultInfos;
// We'd like to keep a stable iteration order for FunctionInfos to help
// FileCheck based testing.
struct MCSymbolComparator {
bool operator()(const MCSymbol *LHS, const MCSymbol *RHS) const {
return LHS->getName() < RHS->getName();
}
};
std::map<const MCSymbol *, FunctionFaultInfos, MCSymbolComparator>
FunctionInfos;
AsmPrinter &AP;
void emitFunctionInfo(const MCSymbol *FnLabel, const FunctionFaultInfos &FFI);
};
}
#endif

View File

@ -18,6 +18,7 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/ISDOpcodes.h"
@ -73,6 +74,16 @@ public:
/// cross-basic-block values.
DenseMap<const Value*, unsigned> ValueMap;
// Keep track of frame indices allocated for statepoints as they could be used
// across basic block boundaries.
// Key of the map is statepoint instruction, value is a map from spilled
// llvm Value to the optional stack stack slot index.
// If optional is unspecified it means that we have visited this value
// but didn't spill it.
typedef DenseMap<const Value*, Optional<int>> StatepointSpilledValueMapTy;
DenseMap<const Instruction*, StatepointSpilledValueMapTy>
StatepointRelocatedValues;
/// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in
/// the entry block. This allows the allocas to be efficiently referenced
/// anywhere in the function.
@ -221,6 +232,8 @@ public:
int getArgumentFrameIndex(const Argument *A);
private:
void addSEHHandlersForLPads(ArrayRef<const LandingPadInst *> LPads);
/// LiveOutRegInfo - Information about live out vregs.
IndexedMap<LiveOutInfo, VirtReg2IndexFunctor> LiveOutRegInfo;
};

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