diff --git a/.gitignore b/.gitignore
index dd0f148c66c9..eeebe0d05267 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,5 +45,7 @@ tools/clang
tools/lldb
# lld, which is tracked independently.
tools/lld
+# Polly, which is tracked independently.
+tools/polly
# Sphinx build tree, if building in-source dir.
docs/_build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 36e6ed8afa7e..b9fca2a386d1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -114,6 +114,12 @@ string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
# They are used as destination of target generators.
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib)
+if(WIN32 OR CYGWIN)
+ # DLL platform -- put DLLs into bin.
+ set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
+else()
+ set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
+endif()
# Each of them corresponds to llvm-config's.
set(LLVM_TOOLS_BINARY_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) # --bindir
@@ -499,7 +505,6 @@ add_subdirectory(lib)
if( LLVM_INCLUDE_UTILS )
add_subdirectory(utils/FileCheck)
- add_subdirectory(utils/FileUpdate)
add_subdirectory(utils/PerfectShuffle)
add_subdirectory(utils/count)
add_subdirectory(utils/not)
diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT
index ee9148715901..86d401ee4498 100644
--- a/CODE_OWNERS.TXT
+++ b/CODE_OWNERS.TXT
@@ -70,8 +70,8 @@ N: Justin Holewinski
E: jholewinski@nvidia.com
D: NVPTX Target (lib/Target/NVPTX/*)
-N: Andy Kaylor
-E: andrew.kaylor@intel.com
+N: Lang Hames
+E: lhames@gmail.com
D: MCJIT, RuntimeDyld and JIT event listeners
N: Galina Kistanova
diff --git a/Makefile.config.in b/Makefile.config.in
index 1c364121ca34..b98ebc6f017d 100644
--- a/Makefile.config.in
+++ b/Makefile.config.in
@@ -259,9 +259,6 @@ CLANG_PLUGIN_SUPPORT = @CLANG_PLUGIN_SUPPORT@
# When ENABLE_CLANG_ARCMT is enabled, clang will have ARCMigrationTool.
ENABLE_CLANG_ARCMT = @ENABLE_CLANG_ARCMT@
-# When ENABLE_CLANG_REWRITER is enabled, clang will have Rewriter.
-ENABLE_CLANG_REWRITER = @ENABLE_CLANG_REWRITER@
-
# When ENABLE_CLANG_STATIC_ANALYZER is enabled, clang will have StaticAnalyzer.
ENABLE_CLANG_STATIC_ANALYZER = @ENABLE_CLANG_STATIC_ANALYZER@
diff --git a/Makefile.rules b/Makefile.rules
index ff0a3e3f8191..ebebc0a85c4f 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -1725,7 +1725,7 @@ $(ObjDir)/%GenDFAPacketizer.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
# Dump all the records to .td.expanded. This is useful for debugging.
$(TARGET:%=%.td.expanded): \
-%.td.expanded : %.td $(LLVM_TBLGEN)
+%.td.expanded : %.td $(LLVM_TBLGEN) $(TDFiles)
$(Echo) "Building a fully expanded version of $(],
- [Use udis86 external x86 disassembler library]),
- [
- AC_SUBST(USE_UDIS86, [1])
- case "$withval" in
- /usr/lib|yes) ;;
- *) LDFLAGS="$LDFLAGS -L${withval}" ;;
- esac
- AC_CHECK_LIB(udis86, ud_init, [], [
- echo "Error! You need to have libudis86 around."
- exit -1
- ])
- ],
- AC_SUBST(USE_UDIS86, [0]))
-AC_DEFINE_UNQUOTED([USE_UDIS86],$USE_UDIS86,
- [Define if use udis86 library])
-
dnl Allow OProfile support for JIT output.
AC_ARG_WITH(oprofile,
AS_HELP_STRING([--with-oprofile=],
diff --git a/bindings/ocaml/executionengine/llvm_executionengine.mli b/bindings/ocaml/executionengine/llvm_executionengine.mli
index 16f08930a75b..74a606287f42 100644
--- a/bindings/ocaml/executionengine/llvm_executionengine.mli
+++ b/bindings/ocaml/executionengine/llvm_executionengine.mli
@@ -151,4 +151,6 @@ module ExecutionEngine: sig
val data_layout : t -> Llvm_target.DataLayout.t
end
+(** [initialize_native_target ()] initializes the native target corresponding
+ to the host. Returns [true] if initialization is {b not} done. *)
val initialize_native_target : unit -> bool
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index 59a89db5f489..f5f5b53e84d5 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -157,38 +157,40 @@ end
See the [llvm::ICmpInst::Predicate] enumeration. *)
module Icmp : sig
type t =
- | Eq
- | Ne
- | Ugt
- | Uge
- | Ult
- | Ule
- | Sgt
- | Sge
- | Slt
- | Sle
+ | Eq (* Equal *)
+ | Ne (* Not equal *)
+ | Ugt (* Unsigned greater than *)
+ | Uge (* Unsigned greater or equal *)
+ | Ult (* Unsigned less than *)
+ | Ule (* Unsigned less or equal *)
+ | Sgt (* Signed greater than *)
+ | Sge (* Signed greater or equal *)
+ | Slt (* Signed less than *)
+ | Sle (* Signed less or equal *)
end
(** The predicate for a floating-point comparison ([fcmp]) instruction.
+ Ordered means that neither operand is a QNAN while unordered means
+ that either operand may be a QNAN.
See the [llvm::FCmpInst::Predicate] enumeration. *)
module Fcmp : sig
type t =
- | False
- | Oeq
- | Ogt
- | Oge
- | Olt
- | Ole
- | One
- | Ord
- | Uno
- | Ueq
- | Ugt
- | Uge
- | Ult
- | Ule
- | Une
- | True
+ | False (* Always false *)
+ | Oeq (* Ordered and equal *)
+ | Ogt (* Ordered and greater than *)
+ | Oge (* Ordered and greater or equal *)
+ | Olt (* Ordered and less than *)
+ | Ole (* Ordered and less or equal *)
+ | One (* Ordered and not equal *)
+ | Ord (* Ordered (no operand is NaN) *)
+ | Uno (* Unordered (one operand at least is NaN) *)
+ | Ueq (* Unordered and equal *)
+ | Ugt (* Unordered and greater than *)
+ | Uge (* Unordered and greater or equal *)
+ | Ult (* Unordered and less than *)
+ | Ule (* Unordered and less or equal *)
+ | Une (* Unordered and not equal *)
+ | True (* Always true *)
end
(** The opcodes for LLVM instructions and constant expressions. *)
@@ -1051,12 +1053,12 @@ val const_lshr : llvalue -> llvalue -> llvalue
See the method [llvm::ConstantExpr::getAShr]. *)
val const_ashr : llvalue -> llvalue -> llvalue
-(** [const_gep pc indices] returns the constant [getElementPtr] of [p1] with the
+(** [const_gep pc indices] returns the constant [getElementPtr] of [pc] with the
constant integers indices from the array [indices].
See the method [llvm::ConstantExpr::getGetElementPtr]. *)
val const_gep : llvalue -> llvalue array -> llvalue
-(** [const_in_bounds_gep pc indices] returns the constant [getElementPtr] of [p1]
+(** [const_in_bounds_gep pc indices] returns the constant [getElementPtr] of [pc]
with the constant integers indices from the array [indices].
See the method [llvm::ConstantExpr::getInBoundsGetElementPtr]. *)
val const_in_bounds_gep : llvalue -> llvalue array -> llvalue
@@ -2360,7 +2362,7 @@ val build_insertelement : llvalue -> llvalue -> llvalue -> string ->
val build_shufflevector : llvalue -> llvalue -> llvalue -> string ->
llbuilder -> llvalue
-(** [build_insertvalue agg idx name b] creates a
+(** [build_extractvalue agg idx name b] creates a
[%name = extractvalue %agg, %idx]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateExtractValue]. *)
diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c
index d5ebdcd3e31a..2044856ef2da 100644
--- a/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/bindings/ocaml/llvm/llvm_ocaml.c
@@ -695,7 +695,7 @@ CAMLprim value llvm_append_namedmd(LLVMModuleRef M, value Name, LLVMValueRef Val
/* lltype -> int -> llvalue */
CAMLprim LLVMValueRef llvm_const_int(LLVMTypeRef IntTy, value N) {
- return LLVMConstInt(IntTy, (long long) Int_val(N), 1);
+ return LLVMConstInt(IntTy, (long long) Long_val(N), 1);
}
/* lltype -> Int64.t -> bool -> llvalue */
diff --git a/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c b/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c
index 0a71bd7cad24..47e17902baab 100644
--- a/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c
+++ b/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c
@@ -134,6 +134,12 @@ CAMLprim value llvm_add_tail_call_elimination(LLVMPassManagerRef PM) {
return Val_unit;
}
+/* [ unit */
+CAMLprim value llvm_add_merged_load_store_motion(LLVMPassManagerRef PM) {
+ LLVMAddMergedLoadStoreMotionPass(PM);
+ return Val_unit;
+}
+
/* [ unit */
CAMLprim value llvm_add_gvn(LLVMPassManagerRef PM) {
LLVMAddGVNPass(PM);
diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake
index 69ffa5b6606a..409a5d61e65b 100644
--- a/cmake/modules/AddLLVM.cmake
+++ b/cmake/modules/AddLLVM.cmake
@@ -8,8 +8,13 @@ function(llvm_update_compile_flags name)
set(update_src_props ON)
endif()
- if(LLVM_REQUIRES_EH)
- set(LLVM_REQUIRES_RTTI ON)
+ # LLVM_REQUIRES_EH is an internal flag that individual
+ # targets can use to force EH
+ if(LLVM_REQUIRES_EH OR LLVM_ENABLE_EH)
+ if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
+ message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI for ${name}")
+ set(LLVM_REQUIRES_RTTI ON)
+ endif()
else()
if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
list(APPEND LLVM_COMPILE_FLAGS "-fno-exceptions")
@@ -19,7 +24,9 @@ function(llvm_update_compile_flags name)
endif()
endif()
- if(NOT LLVM_REQUIRES_RTTI)
+ # LLVM_REQUIRES_RTTI is an internal flag that individual
+ # targets can use to force RTTI
+ if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
list(APPEND LLVM_COMPILE_DEFINITIONS GTEST_HAS_RTTI=0)
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
list(APPEND LLVM_COMPILE_FLAGS "-fno-rtti")
@@ -150,19 +157,33 @@ endfunction(add_dead_strip)
# Note: Don't set variables CMAKE_*_OUTPUT_DIRECTORY any more,
# or a certain builder, for eaxample, msbuild.exe, would be confused.
function(set_output_directory target bindir libdir)
+ # Do nothing if *_OUTPUT_INTDIR is empty.
+ if("${bindir}" STREQUAL "")
+ return()
+ endif()
+
+ # moddir -- corresponding to LIBRARY_OUTPUT_DIRECTORY.
+ # It affects output of add_library(MODULE).
+ if(WIN32 OR CYGWIN)
+ # DLL platform
+ set(moddir ${bindir})
+ else()
+ set(moddir ${libdir})
+ endif()
if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER "${build_mode}" CONFIG_SUFFIX)
string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} bi ${bindir})
string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} li ${libdir})
+ string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} mi ${moddir})
set_target_properties(${target} PROPERTIES "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${bi})
set_target_properties(${target} PROPERTIES "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li})
- set_target_properties(${target} PROPERTIES "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li})
+ set_target_properties(${target} PROPERTIES "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${mi})
endforeach()
else()
set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${bindir})
set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${libdir})
- set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${libdir})
+ set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${moddir})
endif()
endfunction()
@@ -205,7 +226,7 @@ function(llvm_add_library name)
if(ARG_SHARED OR ARG_STATIC)
message(WARNING "MODULE with SHARED|STATIC doesn't make sense.")
endif()
- if(NOT LLVM_ON_UNIX OR CYGWIN)
+ if(NOT LLVM_ENABLE_PLUGINS)
message(STATUS "${name} ignored -- Loadable modules not supported on this platform.")
return()
endif()
@@ -319,6 +340,13 @@ function(llvm_add_library name)
${lib_deps}
${llvm_libs}
)
+ elseif((CYGWIN OR WIN32) AND ARG_SHARED)
+ # Win32's import library may be unaware of its dependent libs.
+ target_link_libraries(${name} PRIVATE
+ ${ARG_LINK_LIBS}
+ ${lib_deps}
+ ${llvm_libs}
+ )
elseif(ARG_SHARED AND BUILD_SHARED_LIBS)
# FIXME: It may be PRIVATE since SO knows its dependent libs.
target_link_libraries(${name} PUBLIC
@@ -359,6 +387,7 @@ macro(add_llvm_library name)
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "LTO")
install(TARGETS ${name}
EXPORT LLVMExports
+ RUNTIME DESTINATION bin
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
endif()
@@ -377,9 +406,15 @@ macro(add_llvm_loadable_module name)
set_target_properties( ${name} PROPERTIES EXCLUDE_FROM_ALL ON)
else()
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+ if(WIN32 OR CYGWIN)
+ # DLL platform
+ set(dlldir "bin")
+ else()
+ set(dlldir "lib${LLVM_LIBDIR_SUFFIX}")
+ endif()
install(TARGETS ${name}
EXPORT LLVMExports
- LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+ LIBRARY DESTINATION ${dlldir}
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
endif()
set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
@@ -570,12 +605,6 @@ function(configure_lit_site_cfg input output)
set(SHLIBEXT "${LTDL_SHLIB_EXT}")
- if(BUILD_SHARED_LIBS)
- set(LLVM_SHARED_LIBS_ENABLED "1")
- else()
- set(LLVM_SHARED_LIBS_ENABLED "0")
- endif(BUILD_SHARED_LIBS)
-
# Configuration-time: See Unit/lit.site.cfg.in
if (CMAKE_CFG_INTDIR STREQUAL ".")
set(LLVM_BUILD_MODE ".")
@@ -590,10 +619,16 @@ function(configure_lit_site_cfg input output)
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLVM_LIBS_DIR ${LLVM_LIBRARY_DIR})
# SHLIBDIR points the build tree.
- string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} SHLIBDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
+ string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} SHLIBDIR "${LLVM_SHLIB_OUTPUT_INTDIR}")
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
- set(ENABLE_SHARED ${LLVM_SHARED_LIBS_ENABLED})
+ # FIXME: "ENABLE_SHARED" doesn't make sense, since it is used just for
+ # plugins. We may rename it.
+ if(LLVM_ENABLE_PLUGINS)
+ set(ENABLE_SHARED "1")
+ else()
+ set(ENABLE_SHARED "0")
+ endif()
if(LLVM_ENABLE_ASSERTIONS AND NOT MSVC_IDE)
set(ENABLE_ASSERTIONS "1")
@@ -604,22 +639,6 @@ function(configure_lit_site_cfg input output)
set(HOST_OS ${CMAKE_SYSTEM_NAME})
set(HOST_ARCH ${CMAKE_SYSTEM_PROCESSOR})
- if (CLANG_ENABLE_ARCMT)
- set(ENABLE_CLANG_ARCMT "1")
- else()
- set(ENABLE_CLANG_ARCMT "0")
- endif()
- if (CLANG_ENABLE_REWRITER)
- set(ENABLE_CLANG_REWRITER "1")
- else()
- set(ENABLE_CLANG_REWRITER "0")
- endif()
- if (CLANG_ENABLE_STATIC_ANALYZER)
- set(ENABLE_CLANG_STATIC_ANALYZER "1")
- else()
- set(ENABLE_CLANG_STATIC_ANALYZER "0")
- endif()
-
configure_file(${input} ${output} @ONLY)
endfunction()
diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt
index 08aeeb9a92e9..f7c54f2c0bd3 100644
--- a/cmake/modules/CMakeLists.txt
+++ b/cmake/modules/CMakeLists.txt
@@ -17,7 +17,6 @@ endforeach(lib)
set(LLVM_CONFIG_CODE "
# LLVM_BUILD_* values available only from LLVM build tree.
set(LLVM_BUILD_BINARY_DIR \"${LLVM_BINARY_DIR}\")
-set(LLVM_BUILD_ENABLE_ASSERTIONS \"${LLVM_ENABLE_ASSERTIONS}\")
set(LLVM_BUILD_LIBRARY_DIR \"${LLVM_LIBRARY_DIR}\")
set(LLVM_BUILD_MAIN_INCLUDE_DIR \"${LLVM_MAIN_INCLUDE_DIR}\")
set(LLVM_BUILD_MAIN_SRC_DIR \"${LLVM_MAIN_SRC_DIR}\")
diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake
index 447ba52ce097..8258512c42a0 100644
--- a/cmake/modules/HandleLLVMOptions.cmake
+++ b/cmake/modules/HandleLLVMOptions.cmake
@@ -67,12 +67,6 @@ if( LLVM_ENABLE_ASSERTIONS )
"${flags_var_to_scrub}" "${${flags_var_to_scrub}}")
endforeach()
endif()
-else()
- if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE" )
- if( NOT MSVC_IDE AND NOT XCODE )
- add_definitions( -DNDEBUG )
- endif()
- endif()
endif()
if(WIN32)
@@ -113,18 +107,6 @@ if(APPLE)
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
endif()
-function(add_flag_or_print_warning flag)
- check_c_compiler_flag(${flag} C_SUPPORTS_FLAG)
- check_cxx_compiler_flag(${flag} CXX_SUPPORTS_FLAG)
- if (C_SUPPORTS_FLAG AND CXX_SUPPORTS_FLAG)
- message(STATUS "Building with ${flag}")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE)
- else()
- message(WARNING "${flag} is not supported.")
- endif()
-endfunction()
-
function(append value)
foreach(variable ${ARGN})
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
@@ -139,13 +121,25 @@ function(append_if condition value)
endif()
endfunction()
-macro(add_flag_if_supported flag)
- check_c_compiler_flag(${flag} C_SUPPORTS_FLAG)
- append_if(C_SUPPORTS_FLAG "${flag}" CMAKE_C_FLAGS)
- check_cxx_compiler_flag(${flag} CXX_SUPPORTS_FLAG)
- append_if(CXX_SUPPORTS_FLAG "${flag}" CMAKE_CXX_FLAGS)
+macro(add_flag_if_supported flag name)
+ check_c_compiler_flag("-Werror ${flag}" "C_SUPPORTS_${name}")
+ append_if("C_SUPPORTS_${name}" "${flag}" CMAKE_C_FLAGS)
+ check_cxx_compiler_flag("-Werror ${flag}" "CXX_SUPPORTS_${name}")
+ append_if("CXX_SUPPORTS_${name}" "${flag}" CMAKE_CXX_FLAGS)
endmacro()
+function(add_flag_or_print_warning flag name)
+ check_c_compiler_flag("-Werror ${flag}" "C_SUPPORTS_${name}")
+ check_cxx_compiler_flag("-Werror ${flag}" "CXX_SUPPORTS_${name}")
+ if ("C_SUPPORTS_${name}" AND "CXX_SUPPORTS_${name}")
+ message(STATUS "Building with ${flag}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE)
+ else()
+ message(WARNING "${flag} is not supported.")
+ endif()
+endfunction()
+
if( LLVM_ENABLE_PIC )
if( XCODE )
# Xcode has -mdynamic-no-pic on by default, which overrides -fPIC. I don't
@@ -154,7 +148,7 @@ if( LLVM_ENABLE_PIC )
elseif( WIN32 OR CYGWIN)
# On Windows all code is PIC. MinGW warns if -fPIC is used.
else()
- add_flag_or_print_warning("-fPIC")
+ add_flag_or_print_warning("-fPIC" FPIC)
if( WIN32 OR CYGWIN)
# MinGW warns if -fvisibility-inlines-hidden is used.
@@ -290,10 +284,7 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
endif()
append_if(LLVM_ENABLE_PEDANTIC "-pedantic -Wno-long-long" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
- check_cxx_compiler_flag("-Werror -Wcovered-switch-default" CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG)
- append_if(CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG "-Wcovered-switch-default" CMAKE_CXX_FLAGS)
- check_c_compiler_flag("-Werror -Wcovered-switch-default" C_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG)
- append_if(C_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG "-Wcovered-switch-default" CMAKE_C_FLAGS)
+ add_flag_if_supported("-Wcovered-switch-default" COVERED_SWITCH_DEFAULT_FLAG)
append_if(USE_NO_UNINITIALIZED "-Wno-uninitialized" CMAKE_CXX_FLAGS)
append_if(USE_NO_MAYBE_UNINITIALIZED "-Wno-maybe-uninitialized" CMAKE_CXX_FLAGS)
check_cxx_compiler_flag("-Werror -Wnon-virtual-dtor" CXX_SUPPORTS_NON_VIRTUAL_DTOR_FLAG)
@@ -311,6 +302,9 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
endif()
endif (LLVM_ENABLE_WARNINGS)
append_if(LLVM_ENABLE_WERROR "-Werror" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if (NOT LLVM_ENABLE_TIMESTAMPS)
+ add_flag_if_supported("-Werror=date-time" WERROR_DATE_TIME)
+ endif ()
if (LLVM_ENABLE_CXX1Y)
check_cxx_compiler_flag("-std=c++1y" CXX_SUPPORTS_CXX1Y)
append_if(CXX_SUPPORTS_CXX1Y "-std=c++1y" CMAKE_CXX_FLAGS)
@@ -333,14 +327,14 @@ endif( MSVC )
macro(append_common_sanitizer_flags)
# Append -fno-omit-frame-pointer and turn on debug info to get better
# stack traces.
- add_flag_if_supported("-fno-omit-frame-pointer")
+ add_flag_if_supported("-fno-omit-frame-pointer" FNO_OMIT_FRAME_POINTER)
if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND
NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
- add_flag_if_supported("-gline-tables-only")
+ add_flag_if_supported("-gline-tables-only" GLINE_TABLES_ONLY)
endif()
# Use -O1 even in debug mode, otherwise sanitizers slowdown is too large.
if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
- add_flag_if_supported("-O1")
+ add_flag_if_supported("-O1" O1)
endif()
endmacro()
@@ -349,12 +343,12 @@ if(LLVM_USE_SANITIZER)
if (LLVM_ON_UNIX)
if (LLVM_USE_SANITIZER STREQUAL "Address")
append_common_sanitizer_flags()
- add_flag_or_print_warning("-fsanitize=address")
+ append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
elseif (LLVM_USE_SANITIZER MATCHES "Memory(WithOrigins)?")
append_common_sanitizer_flags()
- add_flag_or_print_warning("-fsanitize=memory")
+ append("-fsanitize=memory" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
if(LLVM_USE_SANITIZER STREQUAL "MemoryWithOrigins")
- add_flag_or_print_warning("-fsanitize-memory-track-origins")
+ append("-fsanitize-memory-track-origins" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
else()
message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}")
@@ -390,15 +384,9 @@ if(NOT CYGWIN AND NOT WIN32)
if (C_SUPPORTS_FNO_FUNCTION_SECTIONS)
# Don't add -ffunction-section if it can be disabled with -fno-function-sections.
# Doing so will break sanitizers.
- check_c_compiler_flag("-Werror -ffunction-sections" C_SUPPORTS_FFUNCTION_SECTIONS)
- check_cxx_compiler_flag("-Werror -ffunction-sections" CXX_SUPPORTS_FFUNCTION_SECTIONS)
- append_if(C_SUPPORTS_FFUNCTION_SECTIONS "-ffunction-sections" CMAKE_C_FLAGS)
- append_if(CXX_SUPPORTS_FFUNCTION_SECTIONS "-ffunction-sections" CMAKE_CXX_FLAGS)
+ add_flag_if_supported("-ffunction-sections" FFUNCTION_SECTIONS)
endif()
- check_c_compiler_flag("-Werror -fdata-sections" C_SUPPORTS_FDATA_SECTIONS)
- check_cxx_compiler_flag("-Werror -fdata-sections" CXX_SUPPORTS_FDATA_SECTIONS)
- append_if(C_SUPPORTS_FDATA_SECTIONS "-fdata-sections" CMAKE_C_FLAGS)
- append_if(CXX_SUPPORTS_FDATA_SECTIONS "-fdata-sections" CMAKE_CXX_FLAGS)
+ add_flag_if_supported("-fdata-sections" FDATA_SECTIONS)
endif()
endif()
@@ -419,3 +407,22 @@ if(MSVC)
string(REGEX REPLACE "(^| ) */EH[-cs]+ *( |$)" "\\1 \\2" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "(^| ) */GR-? *( |$)" "\\1 \\2" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
+
+# Provide public options to globally control RTTI and EH
+option(LLVM_ENABLE_EH "Enable Exception handling" OFF)
+option(LLVM_ENABLE_RTTI "Enable run time type information" OFF)
+if(LLVM_ENABLE_EH AND NOT LLVM_ENABLE_RTTI)
+ message(FATAL_ERROR "Exception handling requires RTTI. You must set LLVM_ENABLE_RTTI to ON")
+endif()
+
+# Plugin support
+# FIXME: Make this configurable.
+if(WIN32 OR CYGWIN)
+ if(BUILD_SHARED_LIBS)
+ set(LLVM_ENABLE_PLUGINS ON)
+ else()
+ set(LLVM_ENABLE_PLUGINS OFF)
+ endif()
+else()
+ set(LLVM_ENABLE_PLUGINS ON)
+endif()
diff --git a/cmake/modules/LLVM-Config.cmake b/cmake/modules/LLVM-Config.cmake
index 2783af807a18..faba6dfd597b 100644
--- a/cmake/modules/LLVM-Config.cmake
+++ b/cmake/modules/LLVM-Config.cmake
@@ -105,6 +105,9 @@ function(llvm_map_components_to_libnames out_libs)
if( TARGET LLVM${c}AsmParser )
list(APPEND expanded_components "LLVM${c}AsmParser")
endif()
+ if( TARGET LLVM${c}Desc )
+ list(APPEND expanded_components "LLVM${c}Desc")
+ endif()
if( TARGET LLVM${c}Info )
list(APPEND expanded_components "LLVM${c}Info")
endif()
@@ -115,6 +118,12 @@ function(llvm_map_components_to_libnames out_libs)
# already processed
elseif( c STREQUAL "nativecodegen" )
list(APPEND expanded_components "LLVM${LLVM_NATIVE_ARCH}CodeGen")
+ if( TARGET LLVM${LLVM_NATIVE_ARCH}Desc )
+ list(APPEND expanded_components "LLVM${LLVM_NATIVE_ARCH}Desc")
+ endif()
+ if( TARGET LLVM${LLVM_NATIVE_ARCH}Info )
+ list(APPEND expanded_components "LLVM${LLVM_NATIVE_ARCH}Info")
+ endif()
elseif( c STREQUAL "backend" )
# same case as in `native'.
elseif( c STREQUAL "engine" )
diff --git a/cmake/modules/LLVMConfig.cmake.in b/cmake/modules/LLVMConfig.cmake.in
index 780001a1e8d2..7c314ac7c833 100644
--- a/cmake/modules/LLVMConfig.cmake.in
+++ b/cmake/modules/LLVMConfig.cmake.in
@@ -21,6 +21,12 @@ set(LLVM_TARGETS_WITH_JIT @LLVM_TARGETS_WITH_JIT@)
set(TARGET_TRIPLE "@TARGET_TRIPLE@")
+set(LLVM_ENABLE_ASSERTIONS @LLVM_ENABLE_ASSERTIONS@)
+
+set(LLVM_ENABLE_EH @LLVM_ENABLE_EH@)
+
+set(LLVM_ENABLE_RTTI @LLVM_ENABLE_RTTI@)
+
set(LLVM_ENABLE_TERMINFO @LLVM_ENABLE_TERMINFO@)
set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@)
diff --git a/cmake/modules/Makefile b/cmake/modules/Makefile
index 265c1f8ec14b..33021bcbc9ae 100644
--- a/cmake/modules/Makefile
+++ b/cmake/modules/Makefile
@@ -15,6 +15,24 @@ include $(LEVEL)/Makefile.common
PROJ_cmake := $(DESTDIR)$(PROJ_prefix)/share/llvm/cmake
+ifeq ($(DISABLE_ASSERTIONS),1)
+ LLVM_ENABLE_ASSERTIONS := 0
+else
+ LLVM_ENABLE_ASSERTIONS := 1
+endif
+
+ifeq ($(REQUIRES_EH),1)
+ LLVM_ENABLE_EH := 1
+else
+ LLVM_ENABLE_EH := 0
+endif
+
+ifeq ($(REQUIRES_RTTI),1)
+ LLVM_ENABLE_RTTI := 1
+else
+ LLVM_ENABLE_RTTI := 0
+endif
+
OBJMODS := LLVMConfig.cmake LLVMConfigVersion.cmake LLVMExports.cmake
$(PROJ_OBJ_DIR)/LLVMConfig.cmake: LLVMConfig.cmake.in $(LLVMBuildCMakeFrag)
@@ -32,6 +50,9 @@ $(PROJ_OBJ_DIR)/LLVMConfig.cmake: LLVMConfig.cmake.in $(LLVMBuildCMakeFrag)
-e 's/@LLVM_TARGETS_TO_BUILD@/'"$(TARGETS_TO_BUILD)"'/' \
-e 's/@LLVM_TARGETS_WITH_JIT@/'"$(TARGETS_WITH_JIT)"'/' \
-e 's/@TARGET_TRIPLE@/'"$(TARGET_TRIPLE)"'/' \
+ -e 's/@LLVM_ENABLE_ASSERTIONS@/'"$(LLVM_ENABLE_ASSERTIONS)"'/' \
+ -e 's/@LLVM_ENABLE_EH@/'"$(LLVM_ENABLE_EH)"'/' \
+ -e 's/@LLVM_ENABLE_RTTI@/'"$(LLVM_ENABLE_RTTI)"'/' \
-e 's/@LLVM_ENABLE_TERMINFO@/'"$(ENABLE_TERMINFO)"'/' \
-e 's/@LLVM_ENABLE_THREADS@/'"$(ENABLE_THREADS)"'/' \
-e 's/@LLVM_ENABLE_ZLIB@/'"$(ENABLE_ZLIB)"'/' \
diff --git a/cmake/modules/TableGen.cmake b/cmake/modules/TableGen.cmake
index 34b03430b26e..845c986ae2e0 100644
--- a/cmake/modules/TableGen.cmake
+++ b/cmake/modules/TableGen.cmake
@@ -77,9 +77,18 @@ if(CMAKE_CROSSCOMPILING)
COMMAND ${CMAKE_COMMAND} -E make_directory ${CX_NATIVE_TG_DIR}
COMMENT "Creating ${CX_NATIVE_TG_DIR}...")
+ # Forward a subset of configure options to discover additional tablegen modules.
+ get_cmake_property(_variableNames CACHE_VARIABLES)
+ foreach (_variableName ${_variableNames})
+ if (_variableName MATCHES "^(LLVM_EXTERNAL_.*_SOURCE_DIR)$")
+ list(APPEND CX_CMAKE_ARGUMENTS "-D${_variableName}=\"${${_variableName}}\"")
+ endif ()
+ endforeach()
+
add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR}/CMakeCache.txt
+ # TODO: Clear the old CMakeCache.txt somehow without breaking restat.
COMMAND ${CMAKE_COMMAND} -UMAKE_TOOLCHAIN_FILE -DCMAKE_BUILD_TYPE=Release
- -DLLVM_BUILD_POLLY=OFF
+ -DLLVM_BUILD_POLLY=OFF ${CX_CMAKE_ARGUMENTS}
-G "${CMAKE_GENERATOR}" ${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY ${CX_NATIVE_TG_DIR}
DEPENDS ${CX_NATIVE_TG_DIR}
diff --git a/docs/CMake.rst b/docs/CMake.rst
index 988e12b73502..2c8323875389 100644
--- a/docs/CMake.rst
+++ b/docs/CMake.rst
@@ -218,10 +218,18 @@ LLVM-specific variables
Enables code assertions. Defaults to OFF if and only if ``CMAKE_BUILD_TYPE``
is *Release*.
+**LLVM_ENABLE_EH**:BOOL
+ Build LLVM with exception handling support. This is necessary if you wish to
+ link against LLVM libraries and make use of C++ exceptions in your own code
+ that need to propagate through LLVM code. Defaults to OFF.
+
**LLVM_ENABLE_PIC**:BOOL
Add the ``-fPIC`` flag for the compiler command-line, if the compiler supports
this flag. Some systems, like Windows, do not need this flag. Defaults to ON.
+**LLVM_ENABLE_RTTI**:BOOL
+ Build LLVM with run time type information. Defaults to OFF.
+
**LLVM_ENABLE_WARNINGS**:BOOL
Enable all compiler warnings. Defaults to ON.
@@ -487,7 +495,7 @@ into LLVM source tree. You can achieve it in two easy steps:
#. Adding ``add_subdirectory()`` line into
``/lib/Transform/CMakeLists.txt``.
-Compiler/Platform specific topics
+Compiler/Platform-specific topics
=================================
Notes for specific compilers and/or platforms.
diff --git a/docs/CodeGenerator.rst b/docs/CodeGenerator.rst
index cc099465b8ea..5736e4378d72 100644
--- a/docs/CodeGenerator.rst
+++ b/docs/CodeGenerator.rst
@@ -1228,7 +1228,7 @@ used. Each virtual register can only be mapped to physical registers of a
particular class. For instance, in the X86 architecture, some virtuals can only
be allocated to 8 bit registers. A register class is described by
``TargetRegisterClass`` objects. To discover if a virtual register is
-compatible with a given physical, this code can be used:
+compatible with a given physical, this code can be used:
.. code-block:: c++
@@ -1683,7 +1683,7 @@ ones supported by the matcher), through a Requires clause:
def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
-In this example, the mnemonic gets mapped into different a new one depending on
+In this example, the mnemonic gets mapped into a different one depending on
the current instruction set.
Instruction Aliases
@@ -2027,7 +2027,7 @@ supported on x86/x86-64 and PowerPC. It is performed if:
* Option ``-tailcallopt`` is enabled.
-* Platform specific constraints are met.
+* Platform-specific constraints are met.
x86/x86-64 constraints:
diff --git a/docs/CodingStandards.rst b/docs/CodingStandards.rst
index edbef3ace53c..3cfa1f66ab4e 100644
--- a/docs/CodingStandards.rst
+++ b/docs/CodingStandards.rst
@@ -107,10 +107,7 @@ unlikely to be supported by our host compilers.
* Trailing return types: N2541_
* Lambdas: N2927_
- * But *not* ``std::function``, until Clang implements `MSVC-compatible RTTI`_.
- In many cases, you may be able to use ``llvm::function_ref`` instead, and it
- is a superior choice in those cases.
- * And *not* lambdas with default arguments.
+ * But *not* lambdas with default arguments.
* ``decltype``: N2343_
* Nested closing right angle brackets: N1757_
diff --git a/docs/CommandGuide/FileCheck.rst b/docs/CommandGuide/FileCheck.rst
index 5a60d60ae3df..af01503792e8 100644
--- a/docs/CommandGuide/FileCheck.rst
+++ b/docs/CommandGuide/FileCheck.rst
@@ -49,6 +49,17 @@ OPTIONS
The :option:`--strict-whitespace` argument disables this behavior. End-of-line
sequences are canonicalized to UNIX-style ``\n`` in all modes.
+.. option:: --implicit-check-not check-pattern
+
+ Adds implicit negative checks for the specified patterns between positive
+ checks. The option allows writing stricter tests without stuffing them with
+ ``CHECK-NOT``\ s.
+
+ For example, "``--implicit-check-not warning:``" can be useful when testing
+ diagnostic messages from tools that don't have an option similar to ``clang
+ -verify``. With this option FileCheck will verify that input does not contain
+ warnings not covered by any ``CHECK:`` patterns.
+
.. option:: -version
Show the version number of this program.
diff --git a/docs/GarbageCollection.rst b/docs/GarbageCollection.rst
index 323a6ea81659..dc6dab1d336c 100644
--- a/docs/GarbageCollection.rst
+++ b/docs/GarbageCollection.rst
@@ -633,7 +633,7 @@ Threaded
Denotes a multithreaded mutator; the collector must still stop the mutator
("stop the world") before beginning reachability analysis. Stopping a
multithreaded mutator is a complicated problem. It generally requires highly
- platform specific code in the runtime, and the production of carefully
+ platform-specific code in the runtime, and the production of carefully
designed machine code at safe points.
Concurrent
diff --git a/docs/GettingStarted.rst b/docs/GettingStarted.rst
index 6de9b9004e0f..d409f623f868 100644
--- a/docs/GettingStarted.rst
+++ b/docs/GettingStarted.rst
@@ -713,13 +713,6 @@ The following options can be used to set or enable LLVM specific options:
generating the documentation can take a long time and producess 100s of
megabytes of output.
-``--with-udis86``
-
- LLVM can use external disassembler library for various purposes (now it's used
- only for examining code produced by JIT). This option will enable usage of
- `udis86 `_ x86 (both 32 and 64 bits)
- disassembler library.
-
To configure LLVM, follow these steps:
#. Change directory into the object root directory:
diff --git a/docs/HowToReleaseLLVM.rst b/docs/HowToReleaseLLVM.rst
index 61aa9e869f27..26e9f3b2ee87 100644
--- a/docs/HowToReleaseLLVM.rst
+++ b/docs/HowToReleaseLLVM.rst
@@ -146,25 +146,25 @@ following commands:
::
- $ svn mkdir https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XY
+ $ svn mkdir https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XYZ
$ svn copy https://llvm.org/svn/llvm-project/llvm/branches/release_XY \
- https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XY/rc1
+ https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XYZ/rc1
- $ svn mkdir https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY
+ $ svn mkdir https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XYZ
$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
- https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY/rc1
+ https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XYZ/rc1
- $ svn mkdir https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XY
+ $ svn mkdir https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XYZ
$ svn copy https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY \
- https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XY/rc1
+ https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XYZ/rc1
- $ svn mkdir https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY
+ $ svn mkdir https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XYZ
$ svn copy https://llvm.org/svn/llvm-project/test-suite/branches/release_XY \
- https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY/rc1
+ https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XYZ/rc1
Similarly, **Release Candidate 2** would be named ``RC2`` and so on. This keeps
a permanent copy of the release candidate around for people to export and build
-as they wish. The final released sources will be tagged in the ``RELEASE_XY``
+as they wish. The final released sources will be tagged in the ``RELEASE_XYZ``
directory as ``Final`` (c.f. :ref:`tag`).
The Release Manager may supply pre-packaged source tarballs for users. This can
@@ -172,10 +172,10 @@ be done with the following commands:
::
- $ svn export https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XY/rc1 llvm-X.Yrc1
- $ svn export https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY/rc1 clang-X.Yrc1
- $ svn export https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XY/rc1 dragonegg-X.Yrc1
- $ svn export https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY/rc1 llvm-test-X.Yrc1
+ $ svn export https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XYZ/rc1 llvm-X.Yrc1
+ $ svn export https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XYZ/rc1 clang-X.Yrc1
+ $ svn export https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XYZ/rc1 dragonegg-X.Yrc1
+ $ svn export https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XYZ/rc1 llvm-test-X.Yrc1
$ tar -cvf - llvm-X.Yrc1 | gzip > llvm-X.Yrc1.src.tar.gz
$ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.gz
@@ -389,16 +389,16 @@ Tag the final release sources using the following procedure:
::
$ svn copy https://llvm.org/svn/llvm-project/llvm/branches/release_XY \
- https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XY/Final
+ https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XYZ/Final
$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
- https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY/Final
+ https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XYZ/Final
$ svn copy https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY \
- https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XY/Final
+ https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XYZ/Final
$ svn copy https://llvm.org/svn/llvm-project/test-suite/branches/release_XY \
- https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY/Final
+ https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XYZ/Final
Update the LLVM Demo Page
-------------------------
diff --git a/docs/LangRef.rst b/docs/LangRef.rst
index cb94d3967b13..867ef741da17 100644
--- a/docs/LangRef.rst
+++ b/docs/LangRef.rst
@@ -562,6 +562,8 @@ is zero. The address space qualifier must precede any other attributes.
LLVM allows an explicit section to be specified for globals. If the
target supports it, it will emit globals to the section specified.
+Additionally, the global can placed in a comdat if the target has the necessary
+support.
By default, global initializers are optimized by assuming that global
variables defined within the module are not modified from their
@@ -580,7 +582,7 @@ to over-align the global if the global has an assigned section. In this
case, the extra alignment could be observable: for example, code could
assume that the globals are densely packed in their section and try to
iterate over them as an array, alignment padding would break this
-iteration.
+iteration. The maximum alignment is ``1 << 29``.
Globals can also have a :ref:`DLL storage class `.
@@ -627,8 +629,9 @@ an optional ``unnamed_addr`` attribute, a return type, an optional
:ref:`parameter attribute ` for the return type, a function
name, a (possibly empty) argument list (each with optional :ref:`parameter
attributes `), optional :ref:`function attributes `,
-an optional section, an optional alignment, an optional :ref:`garbage
-collector name `, an optional :ref:`prefix `, an opening
+an optional section, an optional alignment,
+an optional :ref:`comdat `,
+an optional :ref:`garbage collector name `, an optional :ref:`prefix `, an opening
curly brace, a list of basic blocks, and a closing curly brace.
LLVM function declarations consist of the "``declare``" keyword, an
@@ -658,6 +661,7 @@ predecessors, it also cannot have any :ref:`PHI nodes `.
LLVM allows an explicit section to be specified for functions. If the
target supports it, it will emit functions to the section specified.
+Additionally, the function can placed in a COMDAT.
An explicit alignment may be specified for a function. If not present,
or if the alignment is set to zero, the alignment of the function is set
@@ -673,8 +677,8 @@ Syntax::
define [linkage] [visibility] [DLLStorageClass]
[cconv] [ret attrs]
@ ([argument list])
- [unnamed_addr] [fn Attrs] [section "name"] [align N]
- [gc] [prefix Constant] { ... }
+ [unnamed_addr] [fn Attrs] [section "name"] [comdat $]
+ [align N] [gc] [prefix Constant] { ... }
.. _langref_aliases:
@@ -716,6 +720,89 @@ some can only be checked when producing an object file:
* No global value in the expression can be a declaration, since that
would require a relocation, which is not possible.
+.. _langref_comdats:
+
+Comdats
+-------
+
+Comdat IR provides access to COFF and ELF object file COMDAT functionality.
+
+Comdats have a name which represents the COMDAT key. All global objects which
+specify this key will only end up in the final object file if the linker chooses
+that key over some other key. Aliases are placed in the same COMDAT that their
+aliasee computes to, if any.
+
+Comdats have a selection kind to provide input on how the linker should
+choose between keys in two different object files.
+
+Syntax::
+
+ $ = comdat SelectionKind
+
+The selection kind must be one of the following:
+
+``any``
+ The linker may choose any COMDAT key, the choice is arbitrary.
+``exactmatch``
+ The linker may choose any COMDAT key but the sections must contain the
+ same data.
+``largest``
+ The linker will choose the section containing the largest COMDAT key.
+``noduplicates``
+ The linker requires that only section with this COMDAT key exist.
+``samesize``
+ The linker may choose any COMDAT key but the sections must contain the
+ same amount of data.
+
+Note that the Mach-O platform doesn't support COMDATs and ELF only supports
+``any`` as a selection kind.
+
+Here is an example of a COMDAT group where a function will only be selected if
+the COMDAT key's section is the largest:
+
+.. code-block:: llvm
+
+ $foo = comdat largest
+ @foo = global i32 2, comdat $foo
+
+ define void @bar() comdat $foo {
+ ret void
+ }
+
+In a COFF object file, this will create a COMDAT section with selection kind
+``IMAGE_COMDAT_SELECT_LARGEST`` containing the contents of the ``@foo`` symbol
+and another COMDAT section with selection kind
+``IMAGE_COMDAT_SELECT_ASSOCIATIVE`` which is associated with the first COMDAT
+section and contains the contents of the ``@baz`` symbol.
+
+There are some restrictions on the properties of the global object.
+It, or an alias to it, must have the same name as the COMDAT group when
+targeting COFF.
+The contents and size of this object may be used during link-time to determine
+which COMDAT groups get selected depending on the selection kind.
+Because the name of the object must match the name of the COMDAT group, the
+linkage of the global object must not be local; local symbols can get renamed
+if a collision occurs in the symbol table.
+
+The combined use of COMDATS and section attributes may yield surprising results.
+For example:
+
+.. code-block:: llvm
+
+ $foo = comdat any
+ $bar = comdat any
+ @g1 = global i32 42, section "sec", comdat $foo
+ @g2 = global i32 42, section "sec", comdat $bar
+
+From the object file perspective, this requires the creation of two sections
+with the same name. This is necessary because both globals belong to different
+COMDAT groups and COMDATs, at the object file level, are represented by
+sections.
+
+Note that certain IR constructs like global variables and functions may create
+COMDATs in the object file in addition to any which are specified using COMDAT
+IR. This arises, for example, when a global variable has linkonce_odr linkage.
+
.. _namedmetadatastructure:
Named Metadata
@@ -804,7 +891,7 @@ Currently, only the following parameter attributes are defined:
address of outgoing stack arguments. An ``inalloca`` argument must
be a pointer to stack memory produced by an ``alloca`` instruction.
The alloca, or argument allocation, must also be tagged with the
- inalloca keyword. Only the past argument may have the ``inalloca``
+ inalloca keyword. Only the last argument may have the ``inalloca``
attribute, and that argument is guaranteed to be passed in memory.
An argument allocation may be used by a call at most once because
@@ -882,6 +969,17 @@ Currently, only the following parameter attributes are defined:
passed in is non-null, or the callee must ensure that the returned pointer
is non-null.
+``dereferenceable()``
+ This indicates that the parameter or return pointer is dereferenceable. This
+ attribute may only be applied to pointer typed parameters. A pointer that
+ is dereferenceable can be loaded from speculatively without a risk of
+ trapping. The number of bytes known to be dereferenceable must be provided
+ in parentheses. It is legal for the number of bytes to be less than the
+ size of the pointee type. The ``nonnull`` attribute does not imply
+ dereferenceability (consider a pointer to one element past the end of an
+ array), however ``dereferenceable()`` does imply ``nonnull`` in
+ ``addrspace(0)`` (which is the default address space).
+
.. _gc:
Garbage Collector Names
@@ -2749,11 +2847,12 @@ number representing the maximum relative error, for example:
'``range``' Metadata
^^^^^^^^^^^^^^^^^^^^
-``range`` metadata may be attached only to loads of integer types. It
-expresses the possible ranges the loaded value is in. The ranges are
-represented with a flattened list of integers. The loaded value is known
-to be in the union of the ranges defined by each consecutive pair. Each
-pair has the following properties:
+``range`` metadata may be attached only to ``load``, ``call`` and ``invoke`` of
+integer types. It expresses the possible ranges the loaded value or the value
+returned by the called function at this call site is in. The ranges are
+represented with a flattened list of integers. The loaded value or the value
+returned is known to be in the union of the ranges defined by each consecutive
+pair. Each pair has the following properties:
- The type must match the type loaded by the instruction.
- The pair ``a,b`` represents the range ``[a,b)``.
@@ -2771,8 +2870,9 @@ Examples:
%a = load i8* %x, align 1, !range !0 ; Can only be 0 or 1
%b = load i8* %y, align 1, !range !1 ; Can only be 255 (-1), 0 or 1
- %c = load i8* %z, align 1, !range !2 ; Can only be 0, 1, 3, 4 or 5
- %d = load i8* %z, align 1, !range !3 ; Can only be -2, -1, 3, 4 or 5
+ %c = call i8 @foo(), !range !2 ; Can only be 0, 1, 3, 4 or 5
+ %d = invoke i8 @bar() to label %cont
+ unwind label %lpad, !range !3 ; Can only be -2, -1, 3, 4 or 5
...
!0 = metadata !{ i8 0, i8 2 }
!1 = metadata !{ i8 255, i8 2 }
@@ -2800,17 +2900,121 @@ constructs:
!0 = metadata !{ metadata !0 }
!1 = metadata !{ metadata !1 }
-The loop identifier metadata can be used to specify additional per-loop
-metadata. Any operands after the first operand can be treated as user-defined
-metadata. For example the ``llvm.vectorizer.unroll`` metadata is understood
-by the loop vectorizer to indicate how many times to unroll the loop:
+The loop identifier metadata can be used to specify additional
+per-loop metadata. Any operands after the first operand can be treated
+as user-defined metadata. For example the ``llvm.loop.unroll.count``
+suggests an unroll factor to the loop unroller:
.. code-block:: llvm
br i1 %exitcond, label %._crit_edge, label %.lr.ph, !llvm.loop !0
...
!0 = metadata !{ metadata !0, metadata !1 }
- !1 = metadata !{ metadata !"llvm.vectorizer.unroll", i32 2 }
+ !1 = metadata !{ metadata !"llvm.loop.unroll.count", i32 4 }
+
+'``llvm.loop.vectorize``' and '``llvm.loop.interleave``'
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Metadata prefixed with ``llvm.loop.vectorize`` or ``llvm.loop.interleave`` are
+used to control per-loop vectorization and interleaving parameters such as
+vectorization width and interleave count. These metadata should be used in
+conjunction with ``llvm.loop`` loop identification metadata. The
+``llvm.loop.vectorize`` and ``llvm.loop.interleave`` metadata are only
+optimization hints and the optimizer will only interleave and vectorize loops if
+it believes it is safe to do so. The ``llvm.mem.parallel_loop_access`` metadata
+which contains information about loop-carried memory dependencies can be helpful
+in determining the safety of these transformations.
+
+'``llvm.loop.interleave.count``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This metadata suggests an interleave count to the loop interleaver.
+The first operand is the string ``llvm.loop.interleave.count`` and the
+second operand is an integer specifying the interleave count. For
+example:
+
+.. code-block:: llvm
+
+ !0 = metadata !{ metadata !"llvm.loop.interleave.count", i32 4 }
+
+Note that setting ``llvm.loop.interleave.count`` to 1 disables interleaving
+multiple iterations of the loop. If ``llvm.loop.interleave.count`` is set to 0
+then the interleave count will be determined automatically.
+
+'``llvm.loop.vectorize.enable``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This metadata selectively enables or disables vectorization for the loop. The
+first operand is the string ``llvm.loop.vectorize.enable`` and the second operand
+is a bit. If the bit operand value is 1 vectorization is enabled. A value of
+0 disables vectorization:
+
+.. code-block:: llvm
+
+ !0 = metadata !{ metadata !"llvm.loop.vectorize.enable", i1 0 }
+ !1 = metadata !{ metadata !"llvm.loop.vectorize.enable", i1 1 }
+
+'``llvm.loop.vectorize.width``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This metadata sets the target width of the vectorizer. The first
+operand is the string ``llvm.loop.vectorize.width`` and the second
+operand is an integer specifying the width. For example:
+
+.. code-block:: llvm
+
+ !0 = metadata !{ metadata !"llvm.loop.vectorize.width", i32 4 }
+
+Note that setting ``llvm.loop.vectorize.width`` to 1 disables
+vectorization of the loop. If ``llvm.loop.vectorize.width`` is set to
+0 or if the loop does not have this metadata the width will be
+determined automatically.
+
+'``llvm.loop.unroll``'
+^^^^^^^^^^^^^^^^^^^^^^
+
+Metadata prefixed with ``llvm.loop.unroll`` are loop unrolling
+optimization hints such as the unroll factor. ``llvm.loop.unroll``
+metadata should be used in conjunction with ``llvm.loop`` loop
+identification metadata. The ``llvm.loop.unroll`` metadata are only
+optimization hints and the unrolling will only be performed if the
+optimizer believes it is safe to do so.
+
+'``llvm.loop.unroll.enable``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This metadata either disables loop unrolling or suggests that the loop
+be unrolled fully. The first operand is the string
+``llvm.loop.unroll.enable`` and the second operand is a bit. If the
+bit operand value is 0 loop unrolling is disabled. A value of 1
+indicates that the loop should be fully unrolled. For example:
+
+.. code-block:: llvm
+
+ !0 = metadata !{ metadata !"llvm.loop.unroll.enable", i1 0 }
+ !1 = metadata !{ metadata !"llvm.loop.unroll.enable", i1 1 }
+
+'``llvm.loop.unroll.count``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This metadata suggests an unroll factor to the loop unroller. The
+first operand is the string ``llvm.loop.unroll.count`` and the second
+operand is a positive integer specifying the unroll factor. For
+example:
+
+.. code-block:: llvm
+
+ !0 = metadata !{ metadata !"llvm.loop.unroll.count", i32 4 }
+
+If the trip count of the loop is less than the unroll count the loop
+will be partially unrolled.
+
+If a loop has both a ``llvm.loop.unroll.enable`` metadata and
+``llvm.loop.unroll.count`` metadata the behavior depends upon the
+value of the ``llvm.loop.unroll.enable`` operand. If the value is 0,
+the loop will not be unrolled. If the value is 1, the loop will be
+unrolled with a factor determined by the ``llvm.loop.unroll.count``
+operand effectively ignoring the ``llvm.loop.unroll.enable`` metadata.
'``llvm.mem``'
^^^^^^^^^^^^^^^
@@ -2895,55 +3099,6 @@ the loop identifier metadata node directly:
!1 = metadata !{ metadata !1 } ; an identifier for the inner loop
!2 = metadata !{ metadata !2 } ; an identifier for the outer loop
-'``llvm.vectorizer``'
-^^^^^^^^^^^^^^^^^^^^^
-
-Metadata prefixed with ``llvm.vectorizer`` is used to control per-loop
-vectorization parameters such as vectorization factor and unroll factor.
-
-``llvm.vectorizer`` metadata should be used in conjunction with ``llvm.loop``
-loop identification metadata.
-
-'``llvm.vectorizer.unroll``' Metadata
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This metadata instructs the loop vectorizer to unroll the specified
-loop exactly ``N`` times.
-
-The first operand is the string ``llvm.vectorizer.unroll`` and the second
-operand is an integer specifying the unroll factor. For example:
-
-.. code-block:: llvm
-
- !0 = metadata !{ metadata !"llvm.vectorizer.unroll", i32 4 }
-
-Note that setting ``llvm.vectorizer.unroll`` to 1 disables unrolling of the
-loop.
-
-If ``llvm.vectorizer.unroll`` is set to 0 then the amount of unrolling will be
-determined automatically.
-
-'``llvm.vectorizer.width``' Metadata
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This metadata sets the target width of the vectorizer to ``N``. Without
-this metadata, the vectorizer will choose a width automatically.
-Regardless of this metadata, the vectorizer will only vectorize loops if
-it believes it is valid to do so.
-
-The first operand is the string ``llvm.vectorizer.width`` and the second
-operand is an integer specifying the width. For example:
-
-.. code-block:: llvm
-
- !0 = metadata !{ metadata !"llvm.vectorizer.width", i32 4 }
-
-Note that setting ``llvm.vectorizer.width`` to 1 disables vectorization of the
-loop.
-
-If ``llvm.vectorizer.width`` is set to 0 then the width will be determined
-automatically.
-
Module Flags Metadata
=====================
@@ -3144,6 +3299,42 @@ Each individual option is required to be either a valid option for the target's
linker, or an option that is reserved by the target specific assembly writer or
object file emitter. No other aspect of these options is defined by the IR.
+C type width Module Flags Metadata
+----------------------------------
+
+The ARM backend emits a section into each generated object file describing the
+options that it was compiled with (in a compiler-independent way) to prevent
+linking incompatible objects, and to allow automatic library selection. Some
+of these options are not visible at the IR level, namely wchar_t width and enum
+width.
+
+To pass this information to the backend, these options are encoded in module
+flags metadata, using the following key-value pairs:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Key
+ - Value
+
+ * - short_wchar
+ - * 0 --- sizeof(wchar_t) == 4
+ * 1 --- sizeof(wchar_t) == 2
+
+ * - short_enum
+ - * 0 --- Enums are at least as large as an ``int``.
+ * 1 --- Enums are stored in the smallest integer type which can
+ represent all of its values.
+
+For example, the following metadata section specifies that the module was
+compiled with a ``wchar_t`` width of 4 bytes, and the underlying type of an
+enum is the smallest type which can represent all of its values::
+
+ !llvm.module.flags = !{!0, !1}
+ !0 = metadata !{i32 1, metadata !"short_wchar", i32 1}
+ !1 = metadata !{i32 1, metadata !"short_enum", i32 0}
+
.. _intrinsicglobalvariables:
Intrinsic Global Variables
@@ -4800,9 +4991,10 @@ bytes of memory on the runtime stack, returning a pointer of the
appropriate type to the program. If "NumElements" is specified, it is
the number of elements allocated, otherwise "NumElements" is defaulted
to be one. If a constant alignment is specified, the value result of the
-allocation is guaranteed to be aligned to at least that boundary. If not
-specified, or if zero, the target can choose to align the allocation on
-any convenient boundary compatible with the type.
+allocation is guaranteed to be aligned to at least that boundary. The
+alignment may not be greater than ``1 << 29``. If not specified, or if
+zero, the target can choose to align the allocation on any convenient
+boundary compatible with the type.
'``type``' may be any sized type.
@@ -4876,7 +5068,8 @@ or an omitted ``align`` argument means that the operation has the ABI
alignment for the target. It is the responsibility of the code emitter
to ensure that the alignment information is correct. Overestimating the
alignment results in undefined behavior. Underestimating the alignment
-may produce less efficient code. An alignment of 1 is always safe.
+may produce less efficient code. An alignment of 1 is always safe. The
+maximum possible alignment is ``1 << 29``.
The optional ``!nontemporal`` metadata must reference a single
metadata name ```` corresponding to a metadata node with one
@@ -4962,7 +5155,7 @@ alignment for the target. It is the responsibility of the code emitter
to ensure that the alignment information is correct. Overestimating the
alignment results in undefined behavior. Underestimating the
alignment may produce less efficient code. An alignment of 1 is always
-safe.
+safe. The maximum possible alignment is ``1 << 29``.
The optional ``!nontemporal`` metadata must reference a single metadata
name ```` corresponding to a metadata node with one ``i32`` entry of
@@ -6283,7 +6476,7 @@ This instruction requires several arguments:
uses value of call or is void).
- Option ``-tailcallopt`` is enabled, or
``llvm::GuaranteedTailCallOpt`` is ``true``.
- - `Platform specific constraints are
+ - `Platform-specific constraints are
met. `_
#. The optional "cconv" marker indicates which :ref:`calling
@@ -8526,14 +8719,14 @@ Syntax:
::
- declare i16 @llvm.convert.to.fp16(f32 %a)
+ declare i16 @llvm.convert.to.fp16.f32(float %a)
+ declare i16 @llvm.convert.to.fp16.f64(double %a)
Overview:
"""""""""
-The '``llvm.convert.to.fp16``' intrinsic function performs a conversion
-from single precision floating point format to half precision floating
-point format.
+The '``llvm.convert.to.fp16``' intrinsic function performs a conversion from a
+conventional floating point type to half precision floating point format.
Arguments:
""""""""""
@@ -8544,17 +8737,16 @@ converted.
Semantics:
""""""""""
-The '``llvm.convert.to.fp16``' intrinsic function performs a conversion
-from single precision floating point format to half precision floating
-point format. The return value is an ``i16`` which contains the
-converted number.
+The '``llvm.convert.to.fp16``' intrinsic function performs a conversion from a
+conventional floating point format to half precision floating point format. The
+return value is an ``i16`` which contains the converted number.
Examples:
"""""""""
.. code-block:: llvm
- %res = call i16 @llvm.convert.to.fp16(f32 %a)
+ %res = call i16 @llvm.convert.to.fp16.f32(float %a)
store i16 %res, i16* @x, align 2
.. _int_convert_from_fp16:
@@ -8567,7 +8759,8 @@ Syntax:
::
- declare f32 @llvm.convert.from.fp16(i16 %a)
+ declare float @llvm.convert.from.fp16.f32(i16 %a)
+ declare double @llvm.convert.from.fp16.f64(i16 %a)
Overview:
"""""""""
@@ -8596,7 +8789,7 @@ Examples:
.. code-block:: llvm
%a = load i16* @x, align 2
- %res = call f32 @llvm.convert.from.fp16(i16 %a)
+ %res = call float @llvm.convert.from.fp16(i16 %a)
Debugger Intrinsics
-------------------
@@ -8717,7 +8910,7 @@ Semantics:
""""""""""
On some architectures the address of the code to be executed needs to be
-different to the address where the trampoline is actually stored. This
+different than the address where the trampoline is actually stored. This
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 `.
@@ -8725,7 +8918,7 @@ returned can then be :ref:`bitcast and executed `.
Memory Use Markers
------------------
-This class of intrinsics exists to information about the lifetime of
+This class of intrinsics provides information about the lifetime of
memory objects and ranges where variables are immutable.
.. _int_lifestart:
diff --git a/docs/Lexicon.rst b/docs/Lexicon.rst
index 11f1341f5cbd..65b7a3e84cda 100644
--- a/docs/Lexicon.rst
+++ b/docs/Lexicon.rst
@@ -50,7 +50,7 @@ C
Common Subexpression Elimination. An optimization that removes common
subexpression compuation. For example ``(a+b)*(a+b)`` has two subexpressions
that are the same: ``(a+b)``. This optimization would perform the addition
- only once and then perform the multiply (but only if it's compulationally
+ only once and then perform the multiply (but only if it's computationally
correct/safe).
D
@@ -159,7 +159,7 @@ R
``Constant::replaceUsesOfWithOnConstant()`` implement the replacement of one
Value with another by iterating over its def/use chain and fixing up all of
the pointers to point to the new value. See
- also `def/use chains `_.
+ also `def/use chains `_.
**Reassociation**
Rearranging associative expressions to promote better redundancy elimination
diff --git a/docs/Makefile.sphinx b/docs/Makefile.sphinx
index 21f66488b2b7..b12168cfed8c 100644
--- a/docs/Makefile.sphinx
+++ b/docs/Makefile.sphinx
@@ -10,7 +10,7 @@ BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) -W .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
diff --git a/docs/Phabricator.rst b/docs/Phabricator.rst
index 18b2817fc041..8ac9afec6c39 100644
--- a/docs/Phabricator.rst
+++ b/docs/Phabricator.rst
@@ -5,18 +5,29 @@ Code Reviews with Phabricator
.. contents::
:local:
-If you prefer to use a web user interface for code reviews,
-you can now submit your patches for Clang and LLVM at
-`LLVM's Phabricator`_.
+If you prefer to use a web user interface for code reviews, you can now submit
+your patches for Clang and LLVM at `LLVM's Phabricator`_ instance.
+
+While Phabricator is a useful tool for some, the relevant -commits mailing list
+is the system of record for all LLVM code review. The mailing list should be
+added as a subscriber on all reviews, and Phabricator users should be prepared
+to respond to free-form comments in mail sent to the commits list.
Sign up
-------
+To get started with Phabricator, navigate to `http://reviews.llvm.org`_ and
+click the power icon in the top right. You can register with a GitHub account,
+a Google account, or you can create your own profile.
+
+Make *sure* that the email address registered with Phabricator is subscribed
+to the relevant -commits mailing list. If your are not subscribed to the commit
+list, all mail sent by Phabricator on your behalf will be held for moderation.
+
Note that if you use your Subversion user name as Phabricator user name,
Phabricator will automatically connect your submits to your Phabricator user in
the `Code Repository Browser`_.
-
Requesting a review via the command line
----------------------------------------
@@ -90,6 +101,15 @@ a change from Phabricator.
Committing a change
-------------------
+Arcanist can manage the commit transparently. It will retrieve the description,
+reviewers, the ``Differential Revision``, etc from the review and commit it to the repository.
+
+::
+
+ arc patch D
+ arc commit --revision D
+
+
When committing an LLVM change that has been reviewed using
Phabricator, the convention is for the commit message to end with the
line:
@@ -113,6 +133,7 @@ Status
Please let us know whether you like it and what could be improved!
.. _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
diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst
index 4973e5c66719..46ec15f93a32 100644
--- a/docs/ProgrammersManual.rst
+++ b/docs/ProgrammersManual.rst
@@ -298,7 +298,9 @@ The ``function_ref``
(`doxygen `__) class
template represents a reference to a callable object, templated over the type
of the callable. This is a good choice for passing a callback to a function,
-if you don't need to hold onto the callback after the function returns.
+if you don't need to hold onto the callback after the function returns. In this
+way, ``function_ref`` is to ``std::function`` as ``StringRef`` is to
+``std::string``.
``function_ref`` can be implicitly constructed from
any callable object that can be called with arguments of type ``Param1``,
@@ -323,17 +325,11 @@ can be called using:
return false;
});
-Note that a ``function_ref`` object contains pointers to external memory, so
-it is not generally safe to store an instance of the class (unless you know
-that the external storage will not be freed).
-``function_ref`` is small enough that it should always be passed by value.
-
-``std::function``
-^^^^^^^^^^^^^^^^^
-
-You cannot use ``std::function`` within LLVM code, because it is not supported
-by all our target toolchains.
-
+Note that a ``function_ref`` object contains pointers to external memory, so it
+is not generally safe to store an instance of the class (unless you know that
+the external storage will not be freed). If you need this ability, consider
+using ``std::function``. ``function_ref`` is small enough that it should always
+be passed by value.
.. _DEBUG:
@@ -1441,8 +1437,10 @@ order, making it an easy (but somewhat expensive) solution for non-deterministic
iteration over maps of pointers.
It is implemented by mapping from key to an index in a vector of key,value
-pairs. This provides fast lookup and iteration, but has two main drawbacks: The
-key is stored twice and it doesn't support removing elements.
+pairs. This provides fast lookup and iteration, but has two main drawbacks:
+the key is stored twice and removing elements takes linear time. If it is
+necessary to remove elements, it's best to remove them in bulk using
+``remove_if()``.
.. _dss_inteqclasses:
@@ -2170,46 +2168,13 @@ compiler, consider compiling LLVM and LLVM-GCC in single-threaded mode, and
using the resultant compiler to build a copy of LLVM with multithreading
support.
-.. _startmultithreaded:
-
-Entering and Exiting Multithreaded Mode
----------------------------------------
-
-In order to properly protect its internal data structures while avoiding
-excessive locking overhead in the single-threaded case, the LLVM must intialize
-certain data structures necessary to provide guards around its internals. To do
-so, the client program must invoke ``llvm_start_multithreaded()`` before making
-any concurrent LLVM API calls. To subsequently tear down these structures, use
-the ``llvm_stop_multithreaded()`` call. You can also use the
-``llvm_is_multithreaded()`` call to check the status of multithreaded mode.
-
-Note that both of these calls must be made *in isolation*. That is to say that
-no other LLVM API calls may be executing at any time during the execution of
-``llvm_start_multithreaded()`` or ``llvm_stop_multithreaded``. It is the
-client's responsibility to enforce this isolation.
-
-The return value of ``llvm_start_multithreaded()`` indicates the success or
-failure of the initialization. Failure typically indicates that your copy of
-LLVM was built without multithreading support, typically because GCC atomic
-intrinsics were not found in your system compiler. In this case, the LLVM API
-will not be safe for concurrent calls. However, it *will* be safe for hosting
-threaded applications in the JIT, though :ref:`care must be taken
-` to ensure that side exits and the like do not accidentally
-result in concurrent LLVM API calls.
-
.. _shutdown:
Ending Execution with ``llvm_shutdown()``
-----------------------------------------
When you are done using the LLVM APIs, you should call ``llvm_shutdown()`` to
-deallocate memory used for internal structures. This will also invoke
-``llvm_stop_multithreaded()`` if LLVM is operating in multithreaded mode. As
-such, ``llvm_shutdown()`` requires the same isolation guarantees as
-``llvm_stop_multithreaded()``.
-
-Note that, if you use scope-based shutdown, you can use the
-``llvm_shutdown_obj`` class, which calls ``llvm_shutdown()`` in its destructor.
+deallocate memory used for internal structures.
.. _managedstatic:
@@ -2217,20 +2182,11 @@ Lazy Initialization with ``ManagedStatic``
------------------------------------------
``ManagedStatic`` is a utility class in LLVM used to implement static
-initialization of static resources, such as the global type tables. Before the
-invocation of ``llvm_shutdown()``, it implements a simple lazy initialization
-scheme. Once ``llvm_start_multithreaded()`` returns, however, it uses
+initialization of static resources, such as the global type tables. In a
+single-threaded environment, it implements a simple lazy initialization scheme.
+When LLVM is compiled with support for multi-threading, however, it uses
double-checked locking to implement thread-safe lazy initialization.
-Note that, because no other threads are allowed to issue LLVM API calls before
-``llvm_start_multithreaded()`` returns, it is possible to have
-``ManagedStatic``\ s of ``llvm::sys::Mutex``\ s.
-
-The ``llvm_acquire_global_lock()`` and ``llvm_release_global_lock`` APIs provide
-access to the global lock used to implement the double-checked locking for lazy
-initialization. These should only be used internally to LLVM, and only if you
-know what you're doing!
-
.. _llvmcontext:
Achieving Isolation with ``LLVMContext``
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 8dc16813580e..c76b9d946073 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -50,11 +50,21 @@ Non-comprehensive list of changes in this release
the ``-no-integrated-as`` option,
* llvm-ar now handles IR files like regular object files. In particular, a
- regular symbol table is created for symbols defined in IR files.
+ regular symbol table is created for symbols defined in IR files, including
+ those in file scope inline assembly.
* LLVM now always uses cfi directives for producing most stack
unwinding information.
+* The prefix for loop vectorizer hint metadata has been changed from
+ ``llvm.vectorizer`` to ``llvm.loop.vectorize``. In addition,
+ ``llvm.vectorizer.unroll`` metadata has been renamed
+ ``llvm.loop.interleave.count``.
+
+* Some backends previously implemented Atomic NAND(x,y) as ``x & ~y``. Now
+ all backends implement it as ``~(x & y)``, matching the semantics of GCC 4.4
+ and later.
+
.. NOTE
For small 1-3 sentence descriptions, just add an entry at the end of
this list. If your description won't fit comfortably in one bullet
diff --git a/docs/SourceLevelDebugging.rst b/docs/SourceLevelDebugging.rst
index a4fbd72167f0..869d3a383107 100644
--- a/docs/SourceLevelDebugging.rst
+++ b/docs/SourceLevelDebugging.rst
@@ -570,6 +570,7 @@ Local variables
metadata, ;; Reference to the type descriptor
i32, ;; flags
metadata ;; (optional) Reference to inline location
+ metadata ;; (optional) Reference to a complex expression (see below)
}
These descriptors are used to define variables local to a sub program. The
diff --git a/docs/TableGen/LangIntro.rst b/docs/TableGen/LangIntro.rst
index 3e74dffb00e2..54d88731012b 100644
--- a/docs/TableGen/LangIntro.rst
+++ b/docs/TableGen/LangIntro.rst
@@ -208,6 +208,9 @@ supported include:
on string, int and bit objects. Use !cast to compare other types of
objects.
+``!shl(a,b)`` ``!srl(a,b)`` ``!sra(a,b)`` ``!add(a,b)``
+ The usual logical and arithmetic operators.
+
Note that all of the values have rules specifying how they convert to values
for different types. These rules allow you to assign a value like "``7``"
to a "``bits<4>``" value, for example.
diff --git a/docs/Vectorizers.rst b/docs/Vectorizers.rst
index 887ccaa8f815..2b702179bf28 100644
--- a/docs/Vectorizers.rst
+++ b/docs/Vectorizers.rst
@@ -51,6 +51,89 @@ Users can control the unroll factor using the command line flag "-force-vector-u
$ clang -mllvm -force-vector-unroll=2 ...
$ opt -loop-vectorize -force-vector-unroll=2 ...
+Pragma loop hint directives
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``#pragma clang loop`` directive allows loop vectorization hints to be
+specified for the subsequent for, while, do-while, or c++11 range-based for
+loop. The directive allows vectorization and interleaving to be enabled or
+disabled. Vector width as well as interleave count can also be manually
+specified. The following example explicitly enables vectorization and
+interleaving:
+
+.. code-block:: c++
+
+ #pragma clang loop vectorize(enable) interleave(enable)
+ while(...) {
+ ...
+ }
+
+The following example implicitly enables vectorization and interleaving by
+specifying a vector width and interleaving count:
+
+.. code-block:: c++
+
+ #pragma clang loop vectorize_width(2) interleave_count(2)
+ for(...) {
+ ...
+ }
+
+See the Clang
+`language extensions
+`_
+for details.
+
+Diagnostics
+-----------
+
+Many loops cannot be vectorized including loops with complicated control flow,
+unvectorizable types, and unvectorizable calls. The loop vectorizer generates
+optimization remarks which can be queried using command line options to identify
+and diagnose loops that are skipped by the loop-vectorizer.
+
+Optimization remarks are enabled using:
+
+``-Rpass=loop-vectorize`` identifies loops that were successfully vectorized.
+
+``-Rpass-missed=loop-vectorize`` identifies loops that failed vectorization and
+indicates if vectorization was specified.
+
+``-Rpass-analysis=loop-vectorize`` identifies the statements that caused
+vectorization to fail.
+
+Consider the following loop:
+
+.. code-block:: c++
+
+ #pragma clang loop vectorize(enable)
+ for (int i = 0; i < Length; i++) {
+ switch(A[i]) {
+ case 0: A[i] = i*2; break;
+ case 1: A[i] = i; break;
+ default: A[i] = 0;
+ }
+ }
+
+The command line ``-Rpass-missed=loop-vectorized`` prints the remark:
+
+.. code-block:: console
+
+ no_switch.cpp:4:5: remark: loop not vectorized: vectorization is explicitly enabled [-Rpass-missed=loop-vectorize]
+
+And the command line ``-Rpass-analysis=loop-vectorize`` indicates that the
+switch statement cannot be vectorized.
+
+.. code-block:: console
+
+ no_switch.cpp:4:5: remark: loop not vectorized: loop contains a switch statement [-Rpass-analysis=loop-vectorize]
+ switch(A[i]) {
+ ^
+
+To ensure line and column numbers are produced include the command line options
+``-gline-tables-only`` and ``-gcolumn-info``. See the Clang `user manual
+`_
+for details
+
Features
--------
diff --git a/examples/BrainF/CMakeLists.txt b/examples/BrainF/CMakeLists.txt
index 025d09336405..65589d9f39f2 100644
--- a/examples/BrainF/CMakeLists.txt
+++ b/examples/BrainF/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
Core
ExecutionEngine
JIT
+ MC
Support
nativecodegen
)
diff --git a/examples/ExceptionDemo/CMakeLists.txt b/examples/ExceptionDemo/CMakeLists.txt
index 5324acd21eab..a08a7c30bd8a 100644
--- a/examples/ExceptionDemo/CMakeLists.txt
+++ b/examples/ExceptionDemo/CMakeLists.txt
@@ -6,7 +6,9 @@ set(LLVM_LINK_COMPONENTS
nativecodegen
)
+# Enable EH and RTTI for this demo
set(LLVM_REQUIRES_EH 1)
+set(LLVM_REQUIRES_RTTI 1)
add_llvm_example(ExceptionDemo
ExceptionDemo.cpp
diff --git a/examples/Fibonacci/CMakeLists.txt b/examples/Fibonacci/CMakeLists.txt
index 724a0f6715d3..c015e50ac350 100644
--- a/examples/Fibonacci/CMakeLists.txt
+++ b/examples/Fibonacci/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
Interpreter
JIT
+ MC
Support
nativecodegen
)
diff --git a/examples/HowToUseJIT/CMakeLists.txt b/examples/HowToUseJIT/CMakeLists.txt
index 88aed026bf6f..237cbea861d2 100644
--- a/examples/HowToUseJIT/CMakeLists.txt
+++ b/examples/HowToUseJIT/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
Interpreter
JIT
+ MC
Support
nativecodegen
)
diff --git a/examples/Kaleidoscope/Chapter4/CMakeLists.txt b/examples/Kaleidoscope/Chapter4/CMakeLists.txt
index 72a9f0512cd2..2b87e8684986 100644
--- a/examples/Kaleidoscope/Chapter4/CMakeLists.txt
+++ b/examples/Kaleidoscope/Chapter4/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
InstCombine
JIT
+ MC
ScalarOpts
Support
nativecodegen
diff --git a/examples/Kaleidoscope/Chapter5/CMakeLists.txt b/examples/Kaleidoscope/Chapter5/CMakeLists.txt
index c7d0276194cf..c3e7c43cb411 100644
--- a/examples/Kaleidoscope/Chapter5/CMakeLists.txt
+++ b/examples/Kaleidoscope/Chapter5/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
InstCombine
JIT
+ MC
ScalarOpts
Support
nativecodegen
diff --git a/examples/Kaleidoscope/Chapter6/CMakeLists.txt b/examples/Kaleidoscope/Chapter6/CMakeLists.txt
index 669c7eb171b8..cd61cec89d55 100644
--- a/examples/Kaleidoscope/Chapter6/CMakeLists.txt
+++ b/examples/Kaleidoscope/Chapter6/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
InstCombine
JIT
+ MC
ScalarOpts
Support
nativecodegen
diff --git a/examples/Kaleidoscope/Chapter7/CMakeLists.txt b/examples/Kaleidoscope/Chapter7/CMakeLists.txt
index 0a0c8e7cab58..cdb13c465d14 100644
--- a/examples/Kaleidoscope/Chapter7/CMakeLists.txt
+++ b/examples/Kaleidoscope/Chapter7/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
InstCombine
JIT
+ MC
ScalarOpts
Support
TransformUtils
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 0e78ed71fa9a..fdff77bc5e51 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -168,6 +168,7 @@ typedef enum {
LLVMInAllocaAttribute = 1ULL << 36,
LLVMNonNullAttribute = 1ULL << 37,
LLVMJumpTableAttribute = 1ULL << 38,
+ LLVMDereferenceableAttribute = 1ULL << 39,
*/
} LLVMAttribute;
@@ -2848,16 +2849,13 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM);
* @{
*/
-/** Allocate and initialize structures needed to make LLVM safe for
- multithreading. The return value indicates whether multithreaded
- initialization succeeded. Must be executed in isolation from all
- other LLVM api calls.
- @see llvm::llvm_start_multithreaded */
+/** Deprecated: Multi-threading can only be enabled/disabled with the compile
+ time define LLVM_ENABLE_THREADS. This function always returns
+ LLVMIsMultithreaded(). */
LLVMBool LLVMStartMultithreaded(void);
-/** Deallocate structures necessary to make LLVM safe for multithreading.
- Must be executed in isolation from all other LLVM api calls.
- @see llvm::llvm_stop_multithreaded */
+/** Deprecated: Multi-threading can only be enabled/disabled with the compile
+ time define LLVM_ENABLE_THREADS. */
void LLVMStopMultithreaded(void);
/** Check whether LLVM is executing in thread-safe mode or not.
diff --git a/include/llvm-c/Transforms/Scalar.h b/include/llvm-c/Transforms/Scalar.h
index 9b820b2334ca..0ca72cec0cd2 100644
--- a/include/llvm-c/Transforms/Scalar.h
+++ b/include/llvm-c/Transforms/Scalar.h
@@ -44,6 +44,9 @@ void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM);
/** See llvm::createScalarizerPass function. */
void LLVMAddScalarizerPass(LLVMPassManagerRef PM);
+/** See llvm::createMergedLoadStoreMotionPass function. */
+void LLVMAddMergedLoadStoreMotionPass(LLVMPassManagerRef PM);
+
/** See llvm::createGVNPass function. */
void LLVMAddGVNPass(LLVMPassManagerRef PM);
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index 1b64fee9a597..0fff505d8d01 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -147,6 +147,12 @@ namespace llvm {
return ArrayRef(data()+N, M);
}
+ // \brief Drop the last \p N elements of the array.
+ ArrayRef drop_back(unsigned N = 1) const {
+ assert(size() >= N && "Dropping more elements than exist");
+ return slice(0, size() - N);
+ }
+
/// @}
/// @name Operator Overloads
/// @{
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index da2b3ad7e7c8..34e2284311b3 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -34,6 +34,7 @@ class BitVector {
unsigned Capacity; // Size of allocated memory in BitWord.
public:
+ typedef unsigned size_type;
// Encapsulation of a single bit.
class reference {
friend class BitVector;
@@ -111,10 +112,10 @@ class BitVector {
bool empty() const { return Size == 0; }
/// size - Returns the number of bits in this bitvector.
- unsigned size() const { return Size; }
+ size_type size() const { return Size; }
/// count - Returns the number of bits which are set.
- unsigned count() const {
+ size_type count() const {
unsigned NumBits = 0;
for (unsigned i = 0; i < NumBitWords(size()); ++i)
if (sizeof(BitWord) == 4)
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 826913289e99..85f37b9051b1 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -43,6 +43,7 @@ class DenseMapBase {
typedef std::pair BucketT;
public:
+ typedef unsigned size_type;
typedef KeyT key_type;
typedef ValueT mapped_type;
typedef BucketT value_type;
@@ -70,7 +71,7 @@ class DenseMapBase {
unsigned size() const { return getNumEntries(); }
/// Grow the densemap so that it has at least Size buckets. Does not shrink
- void resize(size_t Size) {
+ void resize(size_type Size) {
if (Size > getNumBuckets())
grow(Size);
}
@@ -99,10 +100,10 @@ class DenseMapBase {
setNumTombstones(0);
}
- /// count - Return true if the specified key is in the map.
- bool count(const KeyT &Val) const {
+ /// Return 1 if the specified key is in the map, 0 otherwise.
+ size_type count(const KeyT &Val) const {
const BucketT *TheBucket;
- return LookupBucketFor(Val, TheBucket);
+ return LookupBucketFor(Val, TheBucket) ? 1 : 0;
}
iterator find(const KeyT &Val) {
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index 1d8c39c1441b..37a81b0c7ee2 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -29,11 +29,12 @@ class DenseSet {
public:
typedef ValueT key_type;
typedef ValueT value_type;
+ typedef unsigned size_type;
explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
bool empty() const { return TheMap.empty(); }
- unsigned size() const { return TheMap.size(); }
+ size_type size() const { return TheMap.size(); }
size_t getMemorySize() const { return TheMap.getMemorySize(); }
/// Grow the DenseSet so that it has at least Size buckets. Will not shrink
@@ -44,7 +45,8 @@ class DenseSet {
TheMap.clear();
}
- bool count(const ValueT &V) const {
+ /// Return 1 if the specified key is in the set, 0 otherwise.
+ size_type count(const ValueT &V) const {
return TheMap.count(V);
}
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index 128ada0ec835..f9df3781257e 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -154,13 +154,13 @@ class ThreadSafeRefCountedBase {
}
template
- IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.getPtr()) {
+ IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.get()) {
S.Obj = 0;
}
template
IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S)
- : Obj(S.getPtr()) {
+ : Obj(S.get()) {
retain();
}
@@ -175,7 +175,7 @@ class ThreadSafeRefCountedBase {
T* operator->() const { return Obj; }
- T* getPtr() const { return Obj; }
+ T* get() const { return Obj; }
LLVM_EXPLICIT operator bool() const { return Obj; }
@@ -203,42 +203,42 @@ class ThreadSafeRefCountedBase {
inline bool operator==(const IntrusiveRefCntPtr& A,
const IntrusiveRefCntPtr& B)
{
- return A.getPtr() == B.getPtr();
+ return A.get() == B.get();
}
template
inline bool operator!=(const IntrusiveRefCntPtr& A,
const IntrusiveRefCntPtr& B)
{
- return A.getPtr() != B.getPtr();
+ return A.get() != B.get();
}
template
inline bool operator==(const IntrusiveRefCntPtr& A,
U* B)
{
- return A.getPtr() == B;
+ return A.get() == B;
}
template
inline bool operator!=(const IntrusiveRefCntPtr& A,
U* B)
{
- return A.getPtr() != B;
+ return A.get() != B;
}
template
inline bool operator==(T* A,
const IntrusiveRefCntPtr& B)
{
- return A == B.getPtr();
+ return A == B.get();
}
template
inline bool operator!=(T* A,
const IntrusiveRefCntPtr& B)
{
- return A != B.getPtr();
+ return A != B.get();
}
template
@@ -268,14 +268,14 @@ class ThreadSafeRefCountedBase {
template struct simplify_type > {
typedef T* SimpleType;
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr& Val) {
- return Val.getPtr();
+ return Val.get();
}
};
template struct simplify_type > {
typedef /*const*/ T* SimpleType;
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr& Val) {
- return Val.getPtr();
+ return Val.get();
}
};
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
index 7fd1570cbf12..4e1fc1527270 100644
--- a/include/llvm/ADT/MapVector.h
+++ b/include/llvm/ADT/MapVector.h
@@ -29,7 +29,7 @@ template,
typename VectorType = std::vector > >
class MapVector {
- typedef typename VectorType::size_type SizeType;
+ typedef typename VectorType::size_type size_type;
MapType Map;
VectorType Vector;
@@ -38,7 +38,7 @@ class MapVector {
typedef typename VectorType::iterator iterator;
typedef typename VectorType::const_iterator const_iterator;
- SizeType size() const {
+ size_type size() const {
return Vector.size();
}
@@ -100,7 +100,7 @@ class MapVector {
return std::make_pair(begin() + I, false);
}
- unsigned count(const KeyT &Key) const {
+ size_type count(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? 0 : 1;
}
@@ -123,8 +123,59 @@ class MapVector {
Map.erase(Pos);
Vector.pop_back();
}
+
+ /// \brief Remove the element given by Iterator.
+ ///
+ /// Returns an iterator to the element following the one which was removed,
+ /// which may be end().
+ ///
+ /// \note This is a deceivingly expensive operation (linear time). It's
+ /// usually better to use \a remove_if() if possible.
+ typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
+ Map.erase(Iterator->first);
+ auto Next = Vector.erase(Iterator);
+ if (Next == Vector.end())
+ return Next;
+
+ // Update indices in the map.
+ size_t Index = Next - Vector.begin();
+ for (auto &I : Map) {
+ assert(I.second != Index && "Index was already erased!");
+ if (I.second > Index)
+ --I.second;
+ }
+ return Next;
+ }
+
+ /// \brief Remove the elements that match the predicate.
+ ///
+ /// Erase all elements that match \c Pred in a single pass. Takes linear
+ /// time.
+ template void remove_if(Predicate Pred);
};
+template
+template
+void MapVector::remove_if(Function Pred) {
+ auto O = Vector.begin();
+ for (auto I = O, E = Vector.end(); I != E; ++I) {
+ if (Pred(*I)) {
+ // Erase from the map.
+ Map.erase(I->first);
+ continue;
+ }
+
+ if (I != O) {
+ // Move the value and update the index in the map.
+ *O = std::move(*I);
+ Map[O->first] = O - Vector.begin();
+ }
+ ++O;
+ }
+ // Erase trailing entries in the vector.
+ Vector.erase(O, Vector.end());
}
+} // end namespace llvm
+
#endif
diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h
deleted file mode 100644
index 5e83358fc071..000000000000
--- a/include/llvm/ADT/OwningPtr.h
+++ /dev/null
@@ -1,165 +0,0 @@
-//===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines and implements the OwningPtr class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_OWNINGPTR_H
-#define LLVM_ADT_OWNINGPTR_H
-
-#include "llvm/Support/Compiler.h"
-#include
-#include
-#include
-
-namespace llvm {
-
-/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it
-/// guarantees deletion of the object pointed to, either on destruction of the
-/// OwningPtr or via an explicit reset(). Once created, ownership of the
-/// pointee object can be taken away from OwningPtr by using the take method.
-template
-class OwningPtr {
- OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
- OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
- T *Ptr;
-public:
- explicit OwningPtr(T *P = 0) : Ptr(P) {}
-
- OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
-
- OwningPtr &operator=(OwningPtr &&Other) {
- reset(Other.take());
- return *this;
- }
-
- OwningPtr(std::unique_ptr Other) : Ptr(Other.release()) {}
-
- OwningPtr &operator=(std::unique_ptr Other) {
- reset(Other.release());
- return *this;
- }
-
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
- operator std::unique_ptr() && { return std::unique_ptr(take()); }
-#endif
-
- ~OwningPtr() {
- delete Ptr;
- }
-
- /// reset - Change the current pointee to the specified pointer. Note that
- /// calling this with any pointer (including a null pointer) deletes the
- /// current pointer.
- void reset(T *P = 0) {
- if (P == Ptr) return;
- T *Tmp = Ptr;
- Ptr = P;
- delete Tmp;
- }
-
- /// take - Reset the owning pointer to null and return its pointer. This does
- /// not delete the pointer before returning it.
- T *take() {
- T *Tmp = Ptr;
- Ptr = nullptr;
- return Tmp;
- }
-
- T *release() { return take(); }
-
- std::unique_ptr take_unique() { return std::unique_ptr(take()); }
-
- T &operator*() const {
- assert(Ptr && "Cannot dereference null pointer");
- return *Ptr;
- }
-
- T *operator->() const { return Ptr; }
- T *get() const { return Ptr; }
- LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; }
- bool operator!() const { return Ptr == nullptr; }
- bool isValid() const { return Ptr != nullptr; }
-
- void swap(OwningPtr &RHS) {
- T *Tmp = RHS.Ptr;
- RHS.Ptr = Ptr;
- Ptr = Tmp;
- }
-};
-
-template
-inline void swap(OwningPtr &a, OwningPtr &b) {
- a.swap(b);
-}
-
-/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
-/// functionality as OwningPtr, except that it works for array types.
-template
-class OwningArrayPtr {
- OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
- OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
- T *Ptr;
-public:
- explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
-
- OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
-
- OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
- reset(Other.take());
- return *this;
- }
-
- ~OwningArrayPtr() {
- delete [] Ptr;
- }
-
- /// reset - Change the current pointee to the specified pointer. Note that
- /// calling this with any pointer (including a null pointer) deletes the
- /// current pointer.
- void reset(T *P = 0) {
- if (P == Ptr) return;
- T *Tmp = Ptr;
- Ptr = P;
- delete [] Tmp;
- }
-
- /// take - Reset the owning pointer to null and return its pointer. This does
- /// not delete the pointer before returning it.
- T *take() {
- T *Tmp = Ptr;
- Ptr = 0;
- return Tmp;
- }
-
- T &operator[](std::ptrdiff_t i) const {
- assert(Ptr && "Cannot dereference null pointer");
- return Ptr[i];
- }
-
- T *get() const { return Ptr; }
- LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
- bool operator!() const { return Ptr == nullptr; }
-
- void swap(OwningArrayPtr &RHS) {
- T *Tmp = RHS.Ptr;
- RHS.Ptr = Ptr;
- Ptr = Tmp;
- }
-};
-
-template
-inline void swap(OwningArrayPtr &a, OwningArrayPtr &b) {
- a.swap(b);
-}
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
index 3cc7738df8aa..02a6ea345834 100644
--- a/include/llvm/ADT/ScopedHashTable.h
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -148,6 +148,7 @@ class ScopedHashTable {
/// ScopeTy - This is a helpful typedef that allows clients to get easy access
/// to the name of the scope for this hash table.
typedef ScopedHashTableScope ScopeTy;
+ typedef unsigned size_type;
private:
typedef ScopedHashTableVal ValTy;
DenseMap TopLevelMap;
@@ -170,7 +171,8 @@ class ScopedHashTable {
AllocatorTy &getAllocator() { return Allocator; }
const AllocatorTy &getAllocator() const { return Allocator; }
- bool count(const K &Key) const {
+ /// Return 1 if the specified key is in the table, 0 otherwise.
+ size_type count(const K &Key) const {
return TopLevelMap.count(Key);
}
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index e965bc464326..0922017ea61a 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -54,6 +54,7 @@ class SmallBitVector {
};
public:
+ typedef unsigned size_type;
// Encapsulation of a single bit.
class reference {
SmallBitVector &TheVector;
@@ -173,7 +174,7 @@ class SmallBitVector {
}
/// count - Returns the number of bits which are set.
- unsigned count() const {
+ size_type count() const {
if (isSmall()) {
uintptr_t Bits = getSmallBits();
if (NumBaseBits == 32)
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index 67104f3cae50..74f3fd43cec4 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -73,8 +73,9 @@ class SmallPtrSetImplBase {
~SmallPtrSetImplBase();
public:
+ typedef unsigned size_type;
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; }
- unsigned size() const { return NumElements; }
+ size_type size() const { return NumElements; }
void clear() {
// If the capacity of the array is huge, and the # elements used is small,
@@ -263,7 +264,7 @@ class SmallPtrSetImpl : public SmallPtrSetImplBase {
}
/// count - Return 1 if the specified pointer is in the set, 0 otherwise.
- unsigned count(PtrType Ptr) const {
+ size_type count(PtrType Ptr) const {
return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0;
}
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
index 6f36234cb4dd..bb1971eb7c5d 100644
--- a/include/llvm/ADT/SmallSet.h
+++ b/include/llvm/ADT/SmallSet.h
@@ -37,18 +37,19 @@ class SmallSet {
typedef typename SmallVector::const_iterator VIterator;
typedef typename SmallVector::iterator mutable_iterator;
public:
+ typedef size_t size_type;
SmallSet() {}
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
return Vector.empty() && Set.empty();
}
- unsigned size() const {
+ size_type size() const {
return isSmall() ? Vector.size() : Set.size();
}
/// count - Return 1 if the element is in the set, 0 otherwise.
- unsigned count(const T &V) const {
+ size_type count(const T &V) const {
if (isSmall()) {
// Since the collection is small, just do a linear search.
return vfind(V) == Vector.end() ? 0 : 1;
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 706f24862264..36754d682355 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -45,6 +45,7 @@ struct SparseBitVectorElement
: public ilist_node > {
public:
typedef unsigned long BitWord;
+ typedef unsigned size_type;
enum {
BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
@@ -120,7 +121,7 @@ struct SparseBitVectorElement
return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
}
- unsigned count() const {
+ size_type count() const {
unsigned NumBits = 0;
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
if (sizeof(BitWord) == 4)
diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h
index d2b2f8d9b6bd..dc1273eb7ff6 100644
--- a/include/llvm/ADT/SparseMultiSet.h
+++ b/include/llvm/ADT/SparseMultiSet.h
@@ -185,6 +185,7 @@ class SparseMultiSet {
typedef const ValueT &const_reference;
typedef ValueT *pointer;
typedef const ValueT *const_pointer;
+ typedef unsigned size_type;
SparseMultiSet()
: Sparse(nullptr), Universe(0), FreelistIdx(SMSNode::INVALID), NumFree(0) {}
@@ -327,7 +328,7 @@ class SparseMultiSet {
/// This is not the same as BitVector::size() which returns the size of the
/// universe.
///
- unsigned size() const {
+ size_type size() const {
assert(NumFree <= Dense.size() && "Out-of-bounds free entries");
return Dense.size() - NumFree;
}
@@ -378,7 +379,7 @@ class SparseMultiSet {
/// Returns the number of elements identified by Key. This will be linear in
/// the number of elements of that key.
- unsigned count(const KeyT &Key) const {
+ size_type count(const KeyT &Key) const {
unsigned Ret = 0;
for (const_iterator It = find(Key); It != end(); ++It)
++Ret;
diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h
index 899f2e4da03c..632d52ad9d82 100644
--- a/include/llvm/ADT/SparseSet.h
+++ b/include/llvm/ADT/SparseSet.h
@@ -124,6 +124,7 @@ class SparseSet {
typedef typename KeyFunctorT::argument_type KeyT;
typedef SmallVector DenseT;
+ typedef unsigned size_type;
DenseT Dense;
SparseT *Sparse;
unsigned Universe;
@@ -186,7 +187,7 @@ class SparseSet {
/// This is not the same as BitVector::size() which returns the size of the
/// universe.
///
- unsigned size() const { return Dense.size(); }
+ size_type size() const { return Dense.size(); }
/// clear - Clears the set. This is a very fast constant time operation.
///
@@ -231,7 +232,7 @@ class SparseSet {
/// count - Returns 1 if this set contains an element identified by Key,
/// 0 otherwise.
///
- unsigned count(const KeyT &Key) const {
+ size_type count(const KeyT &Key) const {
return find(Key) == end() ? 0 : 1;
}
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index a152f4d3c2ad..0992f5d4a549 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -53,7 +53,7 @@ static inline unsigned hexDigitValue(char C) {
/// This should only be used with unsigned types.
///
template
-static inline char *utohex_buffer(IntTy X, char *BufferEnd) {
+static inline char *utohex_buffer(IntTy X, char *BufferEnd, bool LowerCase = false) {
char *BufPtr = BufferEnd;
*--BufPtr = 0; // Null terminate buffer.
if (X == 0) {
@@ -63,15 +63,15 @@ static inline char *utohex_buffer(IntTy X, char *BufferEnd) {
while (X) {
unsigned char Mod = static_cast(X) & 15;
- *--BufPtr = hexdigit(Mod);
+ *--BufPtr = hexdigit(Mod, LowerCase);
X >>= 4;
}
return BufPtr;
}
-static inline std::string utohexstr(uint64_t X) {
+static inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
char Buffer[17];
- return utohex_buffer(X, Buffer+17);
+ return utohex_buffer(X, Buffer+17, LowerCase);
}
static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index 5b1868187986..c40e5e2b3d87 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -64,7 +64,7 @@ class StringMapImpl {
}
StringMapImpl(unsigned InitSize, unsigned ItemSize);
- void RehashTable();
+ unsigned RehashTable(unsigned BucketNo = 0);
/// LookupBucketFor - Look up the bucket that the specified string should end
/// up in. If it already exists as a key in the map, the Item pointer for the
@@ -323,6 +323,28 @@ class StringMap : public StringMapImpl {
return true;
}
+ /// insert - Inserts the specified key/value pair into the map if the key
+ /// isn't already in the map. The bool component of the returned pair is true
+ /// if and only if the insertion takes place, and the iterator component of
+ /// the pair points to the element with key equivalent to the key of the pair.
+ std::pair insert(std::pair KV) {
+ unsigned BucketNo = LookupBucketFor(KV.first);
+ StringMapEntryBase *&Bucket = TheTable[BucketNo];
+ if (Bucket && Bucket != getTombstoneVal())
+ return std::make_pair(iterator(TheTable + BucketNo, false),
+ false); // Already exists in map.
+
+ if (Bucket == getTombstoneVal())
+ --NumTombstones;
+ Bucket =
+ MapEntryTy::Create(KV.first, Allocator, std::move(KV.second));
+ ++NumItems;
+ assert(NumItems + NumTombstones <= NumBuckets);
+
+ BucketNo = RehashTable(BucketNo);
+ return std::make_pair(iterator(TheTable + BucketNo, false), true);
+ }
+
// clear - Empties out the StringMap
void clear() {
if (empty()) return;
@@ -346,24 +368,7 @@ class StringMap : public StringMapImpl {
/// return.
template
MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) {
- unsigned BucketNo = LookupBucketFor(Key);
- StringMapEntryBase *&Bucket = TheTable[BucketNo];
- if (Bucket && Bucket != getTombstoneVal())
- return *static_cast(Bucket);
-
- MapEntryTy *NewItem = MapEntryTy::Create(Key, Allocator, std::move(Val));
-
- if (Bucket == getTombstoneVal())
- --NumTombstones;
- ++NumItems;
- assert(NumItems + NumTombstones <= NumBuckets);
-
- // Fill in the bucket for the hash table. The FullHashValue was already
- // filled in by LookupBucketFor.
- Bucket = NewItem;
-
- RehashTable();
- return *NewItem;
+ return *insert(std::make_pair(Key, std::move(Val))).first;
}
MapEntryTy &GetOrCreateValue(StringRef Key) {
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index a10bc734da2c..b96f11435520 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -76,7 +76,23 @@ class Triple {
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil, // amdil: amd IL
spir, // SPIR: standard portable IR for OpenCL 32-bit version
- spir64 // SPIR: standard portable IR for OpenCL 64-bit version
+ spir64, // SPIR: standard portable IR for OpenCL 64-bit version
+ kalimba // Kalimba: generic kalimba
+ };
+ enum SubArchType {
+ NoSubArch,
+
+ ARMSubArch_v8,
+ ARMSubArch_v7,
+ ARMSubArch_v7em,
+ ARMSubArch_v7m,
+ ARMSubArch_v7s,
+ ARMSubArch_v6,
+ ARMSubArch_v6m,
+ ARMSubArch_v6t2,
+ ARMSubArch_v5,
+ ARMSubArch_v5te,
+ ARMSubArch_v4t
};
enum VendorType {
UnknownVendor,
@@ -88,7 +104,10 @@ class Triple {
BGQ,
Freescale,
IBM,
- NVIDIA
+ ImaginationTechnologies,
+ MipsTechnologies,
+ NVIDIA,
+ CSR
};
enum OSType {
UnknownOS,
@@ -148,6 +167,9 @@ class Triple {
/// The parsed arch type.
ArchType Arch;
+ /// The parsed subarchitecture type.
+ SubArchType SubArch;
+
/// The parsed vendor type.
VendorType Vendor;
@@ -190,6 +212,9 @@ class Triple {
/// getArch - Get the parsed architecture type of this triple.
ArchType getArch() const { return Arch; }
+ /// getSubArch - get the parsed subarchitecture type for this triple.
+ SubArchType getSubArch() const { return SubArch; }
+
/// getVendor - Get the parsed vendor type of this triple.
VendorType getVendor() const { return Vendor; }
@@ -474,6 +499,12 @@ class Triple {
/// architecture if no such variant can be found.
llvm::Triple get64BitArchVariant() const;
+ /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
+ ///
+ /// \param Arch the architecture name (e.g., "armv7s"). If it is an empty
+ /// string then the triple's arch name is used.
+ const char* getARMCPUForArch(StringRef Arch = StringRef()) const;
+
/// @}
/// @name Static helpers for IDs.
/// @{
diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h
index 2d02d1ce166f..a9cb2f5709eb 100644
--- a/include/llvm/ADT/UniqueVector.h
+++ b/include/llvm/ADT/UniqueVector.h
@@ -22,13 +22,18 @@ namespace llvm {
/// class should have an implementation of operator== and of operator<.
/// Entries can be fetched using operator[] with the entry ID.
template class UniqueVector {
+public:
+ typedef typename std::vector VectorType;
+ typedef typename VectorType::iterator iterator;
+ typedef typename VectorType::const_iterator const_iterator;
+
private:
// Map - Used to handle the correspondence of entry to ID.
std::map Map;
// Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
//
- std::vector Vector;
+ VectorType Vector;
public:
/// insert - Append entry to the vector if it doesn't already exist. Returns
@@ -68,6 +73,18 @@ template class UniqueVector {
return Vector[ID - 1];
}
+ /// \brief Return an iterator to the start of the vector.
+ iterator begin() { return Vector.begin(); }
+
+ /// \brief Return an iterator to the start of the vector.
+ const_iterator begin() const { return Vector.begin(); }
+
+ /// \brief Return an iterator to the end of the vector.
+ iterator end() { return Vector.end(); }
+
+ /// \brief Return an iterator to the end of the vector.
+ const_iterator end() const { return Vector.end(); }
+
/// size - Returns the number of entries in the vector.
///
size_t size() const { return Vector.size(); }
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index 885286604ccb..689766446445 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -274,6 +274,14 @@ class AliasAnalysis {
UnknownModRefBehavior = Anywhere | ModRef
};
+ /// Get the location associated with a pointer argument of a callsite.
+ /// The mask bits are set to indicate the allowed aliasing ModRef kinds.
+ /// Note that these mask bits do not necessarily account for the overall
+ /// behavior of the function, but rather only provide additional
+ /// per-argument information.
+ virtual Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
+ ModRefResult &Mask);
+
/// getModRefBehavior - Return the behavior when calling the given call site.
virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
@@ -597,6 +605,13 @@ bool isNoAliasArgument(const Value *V);
///
bool isIdentifiedObject(const Value *V);
+/// isIdentifiedFunctionLocal - Return true if V is umabigously identified
+/// at the function-level. Different IdentifiedFunctionLocals can't alias.
+/// Further, an IdentifiedFunctionLocal can not alias with any function
+/// arguments other than itself, which is not necessarily true for
+/// IdentifiedObjects.
+bool isIdentifiedFunctionLocal(const Value *V);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index bd72d3ed6d4d..bb256c7bbcc8 100644
--- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -22,6 +22,7 @@
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ScaledNumber.h"
#include "llvm/Support/raw_ostream.h"
#include
#include
@@ -30,684 +31,25 @@
#define DEBUG_TYPE "block-freq"
-//===----------------------------------------------------------------------===//
-//
-// UnsignedFloat definition.
-//
-// TODO: Make this private to BlockFrequencyInfoImpl or delete.
-//
-//===----------------------------------------------------------------------===//
namespace llvm {
-class UnsignedFloatBase {
-public:
- static const int32_t MaxExponent = 16383;
- static const int32_t MinExponent = -16382;
- static const int DefaultPrecision = 10;
-
- static void dump(uint64_t D, int16_t E, int Width);
- static raw_ostream &print(raw_ostream &OS, uint64_t D, int16_t E, int Width,
- unsigned Precision);
- static std::string toString(uint64_t D, int16_t E, int Width,
- unsigned Precision);
- static int countLeadingZeros32(uint32_t N) { return countLeadingZeros(N); }
- static int countLeadingZeros64(uint64_t N) { return countLeadingZeros(N); }
- static uint64_t getHalf(uint64_t N) { return (N >> 1) + (N & 1); }
-
- static std::pair splitSigned(int64_t N) {
- if (N >= 0)
- return std::make_pair(N, false);
- uint64_t Unsigned = N == INT64_MIN ? UINT64_C(1) << 63 : uint64_t(-N);
- return std::make_pair(Unsigned, true);
- }
- static int64_t joinSigned(uint64_t U, bool IsNeg) {
- if (U > uint64_t(INT64_MAX))
- return IsNeg ? INT64_MIN : INT64_MAX;
- return IsNeg ? -int64_t(U) : int64_t(U);
- }
-
- static int32_t extractLg(const std::pair &Lg) {
- return Lg.first;
- }
- static int32_t extractLgFloor(const std::pair &Lg) {
- return Lg.first - (Lg.second > 0);
- }
- static int32_t extractLgCeiling(const std::pair &Lg) {
- return Lg.first + (Lg.second < 0);
- }
-
- static std::pair divide64(uint64_t L, uint64_t R);
- static std::pair multiply64(uint64_t L, uint64_t R);
-
- static int compare(uint64_t L, uint64_t R, int Shift) {
- assert(Shift >= 0);
- assert(Shift < 64);
-
- uint64_t L_adjusted = L >> Shift;
- if (L_adjusted < R)
- return -1;
- if (L_adjusted > R)
- return 1;
-
- return L > L_adjusted << Shift ? 1 : 0;
- }
-};
-
-/// \brief Simple representation of an unsigned floating point.
-///
-/// UnsignedFloat is a unsigned floating point number. It uses simple
-/// saturation arithmetic, and every operation is well-defined for every value.
-///
-/// The number is split into a signed exponent and unsigned digits. The number
-/// represented is \c getDigits()*2^getExponent(). In this way, the digits are
-/// much like the mantissa in the x87 long double, but there is no canonical
-/// form, so the same number can be represented by many bit representations
-/// (it's always in "denormal" mode).
-///
-/// UnsignedFloat is templated on the underlying integer type for digits, which
-/// is expected to be one of uint64_t, uint32_t, uint16_t or uint8_t.
-///
-/// Unlike builtin floating point types, UnsignedFloat is portable.
-///
-/// Unlike APFloat, UnsignedFloat does not model architecture floating point
-/// behaviour (this should make it a little faster), and implements most
-/// operators (this makes it usable).
-///
-/// UnsignedFloat is totally ordered. However, there is no canonical form, so
-/// there are multiple representations of most scalars. E.g.:
-///
-/// UnsignedFloat(8u, 0) == UnsignedFloat(4u, 1)
-/// UnsignedFloat(4u, 1) == UnsignedFloat(2u, 2)
-/// UnsignedFloat(2u, 2) == UnsignedFloat(1u, 3)
-///
-/// UnsignedFloat implements most arithmetic operations. Precision is kept
-/// where possible. Uses simple saturation arithmetic, so that operations
-/// saturate to 0.0 or getLargest() rather than under or overflowing. It has
-/// some extra arithmetic for unit inversion. 0.0/0.0 is defined to be 0.0.
-/// Any other division by 0.0 is defined to be getLargest().
-///
-/// As a convenience for modifying the exponent, left and right shifting are
-/// both implemented, and both interpret negative shifts as positive shifts in
-/// the opposite direction.
-///
-/// Exponents are limited to the range accepted by x87 long double. This makes
-/// it trivial to add functionality to convert to APFloat (this is already
-/// relied on for the implementation of printing).
-///
-/// The current plan is to gut this and make the necessary parts of it (even
-/// more) private to BlockFrequencyInfo.
-template class UnsignedFloat : UnsignedFloatBase {
-public:
- static_assert(!std::numeric_limits::is_signed,
- "only unsigned floats supported");
-
- typedef DigitsT DigitsType;
-
-private:
- typedef std::numeric_limits DigitsLimits;
-
- static const int Width = sizeof(DigitsType) * 8;
- static_assert(Width <= 64, "invalid integer width for digits");
-
-private:
- DigitsType Digits;
- int16_t Exponent;
-
-public:
- UnsignedFloat() : Digits(0), Exponent(0) {}
-
- UnsignedFloat(DigitsType Digits, int16_t Exponent)
- : Digits(Digits), Exponent(Exponent) {}
-
-private:
- UnsignedFloat(const std::pair &X)
- : Digits(X.first), Exponent(X.second) {}
-
-public:
- static UnsignedFloat getZero() { return UnsignedFloat(0, 0); }
- static UnsignedFloat getOne() { return UnsignedFloat(1, 0); }
- static UnsignedFloat getLargest() {
- return UnsignedFloat(DigitsLimits::max(), MaxExponent);
- }
- static UnsignedFloat getFloat(uint64_t N) { return adjustToWidth(N, 0); }
- static UnsignedFloat getInverseFloat(uint64_t N) {
- return getFloat(N).invert();
- }
- static UnsignedFloat getFraction(DigitsType N, DigitsType D) {
- return getQuotient(N, D);
- }
-
- int16_t getExponent() const { return Exponent; }
- DigitsType getDigits() const { return Digits; }
-
- /// \brief Convert to the given integer type.
- ///
- /// Convert to \c IntT using simple saturating arithmetic, truncating if
- /// necessary.
- template IntT toInt() const;
-
- bool isZero() const { return !Digits; }
- bool isLargest() const { return *this == getLargest(); }
- bool isOne() const {
- if (Exponent > 0 || Exponent <= -Width)
- return false;
- return Digits == DigitsType(1) << -Exponent;
- }
-
- /// \brief The log base 2, rounded.
- ///
- /// Get the lg of the scalar. lg 0 is defined to be INT32_MIN.
- int32_t lg() const { return extractLg(lgImpl()); }
-
- /// \brief The log base 2, rounded towards INT32_MIN.
- ///
- /// Get the lg floor. lg 0 is defined to be INT32_MIN.
- int32_t lgFloor() const { return extractLgFloor(lgImpl()); }
-
- /// \brief The log base 2, rounded towards INT32_MAX.
- ///
- /// Get the lg ceiling. lg 0 is defined to be INT32_MIN.
- int32_t lgCeiling() const { return extractLgCeiling(lgImpl()); }
-
- bool operator==(const UnsignedFloat &X) const { return compare(X) == 0; }
- bool operator<(const UnsignedFloat &X) const { return compare(X) < 0; }
- bool operator!=(const UnsignedFloat &X) const { return compare(X) != 0; }
- bool operator>(const UnsignedFloat &X) const { return compare(X) > 0; }
- bool operator<=(const UnsignedFloat &X) const { return compare(X) <= 0; }
- bool operator>=(const UnsignedFloat &X) const { return compare(X) >= 0; }
-
- bool operator!() const { return isZero(); }
-
- /// \brief Convert to a decimal representation in a string.
- ///
- /// Convert to a string. Uses scientific notation for very large/small
- /// numbers. Scientific notation is used roughly for numbers outside of the
- /// range 2^-64 through 2^64.
- ///
- /// \c Precision indicates the number of decimal digits of precision to use;
- /// 0 requests the maximum available.
- ///
- /// As a special case to make debugging easier, if the number is small enough
- /// to convert without scientific notation and has more than \c Precision
- /// digits before the decimal place, it's printed accurately to the first
- /// digit past zero. E.g., assuming 10 digits of precision:
- ///
- /// 98765432198.7654... => 98765432198.8
- /// 8765432198.7654... => 8765432198.8
- /// 765432198.7654... => 765432198.8
- /// 65432198.7654... => 65432198.77
- /// 5432198.7654... => 5432198.765
- std::string toString(unsigned Precision = DefaultPrecision) {
- return UnsignedFloatBase::toString(Digits, Exponent, Width, Precision);
- }
-
- /// \brief Print a decimal representation.
- ///
- /// Print a string. See toString for documentation.
- raw_ostream &print(raw_ostream &OS,
- unsigned Precision = DefaultPrecision) const {
- return UnsignedFloatBase::print(OS, Digits, Exponent, Width, Precision);
- }
- void dump() const { return UnsignedFloatBase::dump(Digits, Exponent, Width); }
-
- UnsignedFloat &operator+=(const UnsignedFloat &X);
- UnsignedFloat &operator-=(const UnsignedFloat &X);
- UnsignedFloat &operator*=(const UnsignedFloat &X);
- UnsignedFloat &operator/=(const UnsignedFloat &X);
- UnsignedFloat &operator<<=(int16_t Shift) { shiftLeft(Shift); return *this; }
- UnsignedFloat &operator>>=(int16_t Shift) { shiftRight(Shift); return *this; }
-
-private:
- void shiftLeft(int32_t Shift);
- void shiftRight(int32_t Shift);
-
- /// \brief Adjust two floats to have matching exponents.
- ///
- /// Adjust \c this and \c X to have matching exponents. Returns the new \c X
- /// by value. Does nothing if \a isZero() for either.
- ///
- /// The value that compares smaller will lose precision, and possibly become
- /// \a isZero().
- UnsignedFloat matchExponents(UnsignedFloat X);
-
- /// \brief Increase exponent to match another float.
- ///
- /// Increases \c this to have an exponent matching \c X. May decrease the
- /// exponent of \c X in the process, and \c this may possibly become \a
- /// isZero().
- void increaseExponentToMatch(UnsignedFloat &X, int32_t ExponentDiff);
-
-public:
- /// \brief Scale a large number accurately.
- ///
- /// Scale N (multiply it by this). Uses full precision multiplication, even
- /// if Width is smaller than 64, so information is not lost.
- uint64_t scale(uint64_t N) const;
- uint64_t scaleByInverse(uint64_t N) const {
- // TODO: implement directly, rather than relying on inverse. Inverse is
- // expensive.
- return inverse().scale(N);
- }
- int64_t scale(int64_t N) const {
- std::pair Unsigned = splitSigned(N);
- return joinSigned(scale(Unsigned.first), Unsigned.second);
- }
- int64_t scaleByInverse(int64_t N) const {
- std::pair Unsigned = splitSigned(N);
- return joinSigned(scaleByInverse(Unsigned.first), Unsigned.second);
- }
-
- int compare(const UnsignedFloat &X) const;
- int compareTo(uint64_t N) const {
- UnsignedFloat Float = getFloat(N);
- int Compare = compare(Float);
- if (Width == 64 || Compare != 0)
- return Compare;
-
- // Check for precision loss. We know *this == RoundTrip.
- uint64_t RoundTrip = Float.template toInt();
- return N == RoundTrip ? 0 : RoundTrip < N ? -1 : 1;
- }
- int compareTo(int64_t N) const { return N < 0 ? 1 : compareTo(uint64_t(N)); }
-
- UnsignedFloat &invert() { return *this = UnsignedFloat::getFloat(1) / *this; }
- UnsignedFloat inverse() const { return UnsignedFloat(*this).invert(); }
-
-private:
- static UnsignedFloat getProduct(DigitsType L, DigitsType R);
- static UnsignedFloat getQuotient(DigitsType Dividend, DigitsType Divisor);
-
- std::pair lgImpl() const;
- static int countLeadingZerosWidth(DigitsType Digits) {
- if (Width == 64)
- return countLeadingZeros64(Digits);
- if (Width == 32)
- return countLeadingZeros32(Digits);
- return countLeadingZeros32(Digits) + Width - 32;
- }
-
- static UnsignedFloat adjustToWidth(uint64_t N, int32_t S) {
- assert(S >= MinExponent);
- assert(S <= MaxExponent);
- if (Width == 64 || N <= DigitsLimits::max())
- return UnsignedFloat(N, S);
-
- // Shift right.
- int Shift = 64 - Width - countLeadingZeros64(N);
- DigitsType Shifted = N >> Shift;
-
- // Round.
- assert(S + Shift <= MaxExponent);
- return getRounded(UnsignedFloat(Shifted, S + Shift),
- N & UINT64_C(1) << (Shift - 1));
- }
-
- static UnsignedFloat getRounded(UnsignedFloat P, bool Round) {
- if (!Round)
- return P;
- if (P.Digits == DigitsLimits::max())
- // Careful of overflow in the exponent.
- return UnsignedFloat(1, P.Exponent) <<= Width;
- return UnsignedFloat(P.Digits + 1, P.Exponent);
- }
-};
-
-#define UNSIGNED_FLOAT_BOP(op, base) \
- template \
- UnsignedFloat operator op(const UnsignedFloat &L, \
- const UnsignedFloat &R) { \
- return UnsignedFloat(L) base R; \
- }
-UNSIGNED_FLOAT_BOP(+, += )
-UNSIGNED_FLOAT_BOP(-, -= )
-UNSIGNED_FLOAT_BOP(*, *= )
-UNSIGNED_FLOAT_BOP(/, /= )
-UNSIGNED_FLOAT_BOP(<<, <<= )
-UNSIGNED_FLOAT_BOP(>>, >>= )
-#undef UNSIGNED_FLOAT_BOP
-
-template
-raw_ostream &operator<<(raw_ostream &OS, const UnsignedFloat &X) {
- return X.print(OS, 10);
-}
-
-#define UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, T1, T2) \
- template \
- bool operator op(const UnsignedFloat &L, T1 R) { \
- return L.compareTo(T2(R)) op 0; \
- } \
- template \
- bool operator op(T1 L, const UnsignedFloat &R) { \
- return 0 op R.compareTo(T2(L)); \
- }
-#define UNSIGNED_FLOAT_COMPARE_TO(op) \
- UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, uint64_t, uint64_t) \
- UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, uint32_t, uint64_t) \
- UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, int64_t, int64_t) \
- UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, int32_t, int64_t)
-UNSIGNED_FLOAT_COMPARE_TO(< )
-UNSIGNED_FLOAT_COMPARE_TO(> )
-UNSIGNED_FLOAT_COMPARE_TO(== )
-UNSIGNED_FLOAT_COMPARE_TO(!= )
-UNSIGNED_FLOAT_COMPARE_TO(<= )
-UNSIGNED_FLOAT_COMPARE_TO(>= )
-#undef UNSIGNED_FLOAT_COMPARE_TO
-#undef UNSIGNED_FLOAT_COMPARE_TO_TYPE
-
-template
-uint64_t UnsignedFloat::scale(uint64_t N) const {
- if (Width == 64 || N <= DigitsLimits::max())
- return (getFloat(N) * *this).template toInt();
-
- // Defer to the 64-bit version.
- return UnsignedFloat(Digits, Exponent).scale(N);
-}
-
-template
-UnsignedFloat UnsignedFloat::getProduct(DigitsType L,
- DigitsType R) {
- // Check for zero.
- if (!L || !R)
- return getZero();
-
- // Check for numbers that we can compute with 64-bit math.
- if (Width <= 32 || (L <= UINT32_MAX && R <= UINT32_MAX))
- return adjustToWidth(uint64_t(L) * uint64_t(R), 0);
-
- // Do the full thing.
- return UnsignedFloat(multiply64(L, R));
-}
-template
-UnsignedFloat UnsignedFloat::getQuotient(DigitsType Dividend,
- DigitsType Divisor) {
- // Check for zero.
- if (!Dividend)
- return getZero();
- if (!Divisor)
- return getLargest();
-
- if (Width == 64)
- return UnsignedFloat(divide64(Dividend, Divisor));
-
- // We can compute this with 64-bit math.
- int Shift = countLeadingZeros64(Dividend);
- uint64_t Shifted = uint64_t(Dividend) << Shift;
- uint64_t Quotient = Shifted / Divisor;
-
- // If Quotient needs to be shifted, then adjustToWidth will round.
- if (Quotient > DigitsLimits::max())
- return adjustToWidth(Quotient, -Shift);
-
- // Round based on the value of the next bit.
- return getRounded(UnsignedFloat(Quotient, -Shift),
- Shifted % Divisor >= getHalf(Divisor));
-}
-
-template
-template
-IntT UnsignedFloat::toInt() const {
- typedef std::numeric_limits Limits;
- if (*this < 1)
- return 0;
- if (*this >= Limits::max())
- return Limits::max();
-
- IntT N = Digits;
- if (Exponent > 0) {
- assert(size_t(Exponent) < sizeof(IntT) * 8);
- return N << Exponent;
- }
- if (Exponent < 0) {
- assert(size_t(-Exponent) < sizeof(IntT) * 8);
- return N >> -Exponent;
- }
- return N;
-}
-
-template
-std::pair UnsignedFloat::lgImpl() const {
- if (isZero())
- return std::make_pair(INT32_MIN, 0);
-
- // Get the floor of the lg of Digits.
- int32_t LocalFloor = Width - countLeadingZerosWidth(Digits) - 1;
-
- // Get the floor of the lg of this.
- int32_t Floor = Exponent + LocalFloor;
- if (Digits == UINT64_C(1) << LocalFloor)
- return std::make_pair(Floor, 0);
-
- // Round based on the next digit.
- assert(LocalFloor >= 1);
- bool Round = Digits & UINT64_C(1) << (LocalFloor - 1);
- return std::make_pair(Floor + Round, Round ? 1 : -1);
-}
-
-template
-UnsignedFloat UnsignedFloat::matchExponents(UnsignedFloat X) {
- if (isZero() || X.isZero() || Exponent == X.Exponent)
- return X;
-
- int32_t Diff = int32_t(X.Exponent) - int32_t(Exponent);
- if (Diff > 0)
- increaseExponentToMatch(X, Diff);
- else
- X.increaseExponentToMatch(*this, -Diff);
- return X;
-}
-template
-void UnsignedFloat::increaseExponentToMatch(UnsignedFloat &X,
- int32_t ExponentDiff) {
- assert(ExponentDiff > 0);
- if (ExponentDiff >= 2 * Width) {
- *this = getZero();
- return;
- }
-
- // Use up any leading zeros on X, and then shift this.
- int32_t ShiftX = std::min(countLeadingZerosWidth(X.Digits), ExponentDiff);
- assert(ShiftX < Width);
-
- int32_t ShiftThis = ExponentDiff - ShiftX;
- if (ShiftThis >= Width) {
- *this = getZero();
- return;
- }
-
- X.Digits <<= ShiftX;
- X.Exponent -= ShiftX;
- Digits >>= ShiftThis;
- Exponent += ShiftThis;
- return;
-}
-
-template
-UnsignedFloat &UnsignedFloat::
-operator+=(const UnsignedFloat &X) {
- if (isLargest() || X.isZero())
- return *this;
- if (isZero() || X.isLargest())
- return *this = X;
-
- // Normalize exponents.
- UnsignedFloat Scaled = matchExponents(X);
-
- // Check for zero again.
- if (isZero())
- return *this = Scaled;
- if (Scaled.isZero())
- return *this;
-
- // Compute sum.
- DigitsType Sum = Digits + Scaled.Digits;
- bool DidOverflow = Sum < Digits;
- Digits = Sum;
- if (!DidOverflow)
- return *this;
-
- if (Exponent == MaxExponent)
- return *this = getLargest();
-
- ++Exponent;
- Digits = UINT64_C(1) << (Width - 1) | Digits >> 1;
-
- return *this;
-}
-template
-UnsignedFloat &UnsignedFloat::
-operator-=(const UnsignedFloat &X) {
- if (X.isZero())
- return *this;
- if (*this <= X)
- return *this = getZero();
-
- // Normalize exponents.
- UnsignedFloat Scaled = matchExponents(X);
- assert(Digits >= Scaled.Digits);
-
- // Compute difference.
- if (!Scaled.isZero()) {
- Digits -= Scaled.Digits;
- return *this;
- }
-
- // Check if X just barely lost its last bit. E.g., for 32-bit:
- //
- // 1*2^32 - 1*2^0 == 0xffffffff != 1*2^32
- if (*this == UnsignedFloat(1, X.lgFloor() + Width)) {
- Digits = DigitsType(0) - 1;
- --Exponent;
- }
- return *this;
-}
-template
-UnsignedFloat &UnsignedFloat::
-operator*=(const UnsignedFloat &X) {
- if (isZero())
- return *this;
- if (X.isZero())
- return *this = X;
-
- // Save the exponents.
- int32_t Exponents = int32_t(Exponent) + int32_t(X.Exponent);
-
- // Get the raw product.
- *this = getProduct(Digits, X.Digits);
-
- // Combine with exponents.
- return *this <<= Exponents;
-}
-template
-UnsignedFloat &UnsignedFloat::
-operator/=(const UnsignedFloat &X) {
- if (isZero())
- return *this;
- if (X.isZero())
- return *this = getLargest();
-
- // Save the exponents.
- int32_t Exponents = int32_t(Exponent) - int32_t(X.Exponent);
-
- // Get the raw quotient.
- *this = getQuotient(Digits, X.Digits);
-
- // Combine with exponents.
- return *this <<= Exponents;
-}
-template
-void UnsignedFloat::shiftLeft(int32_t Shift) {
- if (!Shift || isZero())
- return;
- assert(Shift != INT32_MIN);
- if (Shift < 0) {
- shiftRight(-Shift);
- return;
- }
-
- // Shift as much as we can in the exponent.
- int32_t ExponentShift = std::min(Shift, MaxExponent - Exponent);
- Exponent += ExponentShift;
- if (ExponentShift == Shift)
- return;
-
- // Check this late, since it's rare.
- if (isLargest())
- return;
-
- // Shift the digits themselves.
- Shift -= ExponentShift;
- if (Shift > countLeadingZerosWidth(Digits)) {
- // Saturate.
- *this = getLargest();
- return;
- }
-
- Digits <<= Shift;
- return;
-}
-
-template
-void UnsignedFloat::shiftRight(int32_t Shift) {
- if (!Shift || isZero())
- return;
- assert(Shift != INT32_MIN);
- if (Shift < 0) {
- shiftLeft(-Shift);
- return;
- }
-
- // Shift as much as we can in the exponent.
- int32_t ExponentShift = std::min(Shift, Exponent - MinExponent);
- Exponent -= ExponentShift;
- if (ExponentShift == Shift)
- return;
-
- // Shift the digits themselves.
- Shift -= ExponentShift;
- if (Shift >= Width) {
- // Saturate.
- *this = getZero();
- return;
- }
-
- Digits >>= Shift;
- return;
-}
+class BasicBlock;
+class BranchProbabilityInfo;
+class Function;
+class Loop;
+class LoopInfo;
+class MachineBasicBlock;
+class MachineBranchProbabilityInfo;
+class MachineFunction;
+class MachineLoop;
+class MachineLoopInfo;
-template
-int UnsignedFloat::compare(const UnsignedFloat &X) const {
- // Check for zero.
- if (isZero())
- return X.isZero() ? 0 : -1;
- if (X.isZero())
- return 1;
-
- // Check for the scale. Use lgFloor to be sure that the exponent difference
- // is always lower than 64.
- int32_t lgL = lgFloor(), lgR = X.lgFloor();
- if (lgL != lgR)
- return lgL < lgR ? -1 : 1;
-
- // Compare digits.
- if (Exponent < X.Exponent)
- return UnsignedFloatBase::compare(Digits, X.Digits, X.Exponent - Exponent);
-
- return -UnsignedFloatBase::compare(X.Digits, Digits, Exponent - X.Exponent);
-}
+namespace bfi_detail {
-template struct isPodLike> {
- static const bool value = true;
-};
-}
+struct IrreducibleGraph;
-//===----------------------------------------------------------------------===//
-//
-// BlockMass definition.
-//
-// TODO: Make this private to BlockFrequencyInfoImpl or delete.
-//
-//===----------------------------------------------------------------------===//
-namespace llvm {
+// This is part of a workaround for a GCC 4.7 crash on lambdas.
+template struct BlockEdgesAdder;
/// \brief Mass of a block.
///
@@ -770,11 +112,11 @@ class BlockMass {
bool operator<(const BlockMass &X) const { return Mass < X.Mass; }
bool operator>(const BlockMass &X) const { return Mass > X.Mass; }
- /// \brief Convert to floating point.
+ /// \brief Convert to scaled number.
///
- /// Convert to a float. \a isFull() gives 1.0, while \a isEmpty() gives
- /// slightly above 0.0.
- UnsignedFloat toFloat() const;
+ /// Convert to \a ScaledNumber. \a isFull() gives 1.0, while \a isEmpty()
+ /// gives slightly above 0.0.
+ ScaledNumber toScaled() const;
void dump() const;
raw_ostream &print(raw_ostream &OS) const;
@@ -797,35 +139,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, const BlockMass &X) {
return X.print(OS);
}
-template <> struct isPodLike {
+} // end namespace bfi_detail
+
+template <> struct isPodLike {
static const bool value = true;
};
-}
-
-//===----------------------------------------------------------------------===//
-//
-// BlockFrequencyInfoImpl definition.
-//
-//===----------------------------------------------------------------------===//
-namespace llvm {
-
-class BasicBlock;
-class BranchProbabilityInfo;
-class Function;
-class Loop;
-class LoopInfo;
-class MachineBasicBlock;
-class MachineBranchProbabilityInfo;
-class MachineFunction;
-class MachineLoop;
-class MachineLoopInfo;
-
-namespace bfi_detail {
-struct IrreducibleGraph;
-
-// This is part of a workaround for a GCC 4.7 crash on lambdas.
-template struct BlockEdgesAdder;
-}
/// \brief Base class for BlockFrequencyInfoImpl
///
@@ -837,7 +155,8 @@ template struct BlockEdgesAdder;
/// BlockFrequencyInfoImpl. See there for details.
class BlockFrequencyInfoImplBase {
public:
- typedef UnsignedFloat Float;
+ typedef ScaledNumber Scaled64;
+ typedef bfi_detail::BlockMass BlockMass;
/// \brief Representative of a block.
///
@@ -866,7 +185,7 @@ class BlockFrequencyInfoImplBase {
/// \brief Stats about a block itself.
struct FrequencyData {
- Float Floating;
+ Scaled64 Scaled;
uint64_t Integer;
};
@@ -884,7 +203,7 @@ class BlockFrequencyInfoImplBase {
NodeList Nodes; ///< Header and the members of the loop.
BlockMass BackedgeMass; ///< Mass returned to loop header.
BlockMass Mass;
- Float Scale;
+ Scaled64 Scale;
LoopData(LoopData *Parent, const BlockNode &Header)
: Parent(Parent), IsPackaged(false), NumHeaders(1), Nodes(1, Header) {}
@@ -1003,6 +322,8 @@ class BlockFrequencyInfoImplBase {
BlockNode TargetNode;
uint64_t Amount;
Weight() : Type(Local), Amount(0) {}
+ Weight(DistType Type, BlockNode TargetNode, uint64_t Amount)
+ : Type(Type), TargetNode(TargetNode), Amount(Amount) {}
};
/// \brief Distribution of unscaled probability weight.
@@ -1131,7 +452,7 @@ class BlockFrequencyInfoImplBase {
virtual raw_ostream &print(raw_ostream &OS) const { return OS; }
void dump() const { print(dbgs()); }
- Float getFloatingBlockFreq(const BlockNode &Node) const;
+ Scaled64 getFloatingBlockFreq(const BlockNode &Node) const;
BlockFrequency getBlockFreq(const BlockNode &Node) const;
@@ -1310,7 +631,7 @@ void IrreducibleGraph::addEdges(const BlockNode &Node,
/// entries point to this block. Its successors are the headers, which split
/// the frequency evenly.
///
-/// This algorithm leverages BlockMass and UnsignedFloat to maintain precision,
+/// This algorithm leverages BlockMass and ScaledNumber to maintain precision,
/// separates mass distribution from loop scaling, and dithers to eliminate
/// probability mass loss.
///
@@ -1568,7 +889,7 @@ template class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase {
BlockFrequency getBlockFreq(const BlockT *BB) const {
return BlockFrequencyInfoImplBase::getBlockFreq(getNode(BB));
}
- Float getFloatingBlockFreq(const BlockT *BB) const {
+ Scaled64 getFloatingBlockFreq(const BlockT *BB) const {
return BlockFrequencyInfoImplBase::getFloatingBlockFreq(getNode(BB));
}
@@ -1852,7 +1173,8 @@ raw_ostream &BlockFrequencyInfoImpl::print(raw_ostream &OS) const {
OS << "\n";
return OS;
}
-}
+
+} // end namespace llvm
#undef DEBUG_TYPE
diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h
index eccf1f811381..8b7c7a90f7c0 100644
--- a/include/llvm/Analysis/CaptureTracking.h
+++ b/include/llvm/Analysis/CaptureTracking.h
@@ -18,6 +18,8 @@ namespace llvm {
class Value;
class Use;
+ class Instruction;
+ class DominatorTree;
/// PointerMayBeCaptured - Return true if this pointer value may be captured
/// by the enclosing function (which is required to exist). This routine can
@@ -30,6 +32,20 @@ namespace llvm {
bool ReturnCaptures,
bool StoreCaptures);
+ /// PointerMayBeCapturedBefore - Return true if this pointer value may be
+ /// captured by the enclosing function (which is required to exist). If a
+ /// DominatorTree is provided, only captures which happen before the given
+ /// instruction are considered. This routine can be expensive, so consider
+ /// caching the results. The boolean ReturnCaptures specifies whether
+ /// returning the value (or part of it) from the function counts as capturing
+ /// it or not. The boolean StoreCaptures specified whether storing the value
+ /// (or part of it) into memory anywhere automatically counts as capturing it
+ /// or not. Captures by the provided instruction are considered if the
+ /// final parameter is true.
+ bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
+ bool StoreCaptures, const Instruction *I,
+ DominatorTree *DT, bool IncludeI = false);
+
/// This callback is used in conjunction with PointerMayBeCaptured. In
/// addition to the interface here, you'll need to provide your own getters
/// to see whether anything was captured.
diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h
index 0fbaa13bd3ba..f42b9cbbfedd 100644
--- a/include/llvm/Analysis/DominanceFrontier.h
+++ b/include/llvm/Analysis/DominanceFrontier.h
@@ -23,168 +23,186 @@
#include
namespace llvm {
-
+
//===----------------------------------------------------------------------===//
/// DominanceFrontierBase - Common base class for computing forward and inverse
/// dominance frontiers for a function.
///
-class DominanceFrontierBase : public FunctionPass {
+template
+class DominanceFrontierBase {
public:
- typedef std::set DomSetType; // Dom set for a bb
- typedef std::map DomSetMapType; // Dom set map
+ typedef std::set DomSetType; // Dom set for a bb
+ typedef std::map DomSetMapType; // Dom set map
+
protected:
+ typedef GraphTraits BlockTraits;
+
DomSetMapType Frontiers;
- std::vector Roots;
+ std::vector Roots;
const bool IsPostDominators;
public:
- DominanceFrontierBase(char &ID, bool isPostDom)
- : FunctionPass(ID), IsPostDominators(isPostDom) {}
+ DominanceFrontierBase(bool isPostDom) : IsPostDominators(isPostDom) {}
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
- inline const std::vector &getRoots() const { return Roots; }
+ inline const std::vector &getRoots() const {
+ return Roots;
+ }
+
+ BlockT *getRoot() const {
+ assert(Roots.size() == 1 && "Should always have entry node!");
+ return Roots[0];
+ }
/// isPostDominator - Returns true if analysis based of postdoms
///
- bool isPostDominator() const { return IsPostDominators; }
+ bool isPostDominator() const {
+ return IsPostDominators;
+ }
- void releaseMemory() override { Frontiers.clear(); }
+ void releaseMemory() {
+ Frontiers.clear();
+ }
// Accessor interface:
- typedef DomSetMapType::iterator iterator;
- typedef DomSetMapType::const_iterator const_iterator;
- iterator begin() { return Frontiers.begin(); }
+ typedef typename DomSetMapType::iterator iterator;
+ typedef typename DomSetMapType::const_iterator const_iterator;
+ iterator begin() { return Frontiers.begin(); }
const_iterator begin() const { return Frontiers.begin(); }
- iterator end() { return Frontiers.end(); }
- const_iterator end() const { return Frontiers.end(); }
- iterator find(BasicBlock *B) { return Frontiers.find(B); }
- const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
+ iterator end() { return Frontiers.end(); }
+ const_iterator end() const { return Frontiers.end(); }
+ iterator find(BlockT *B) { return Frontiers.find(B); }
+ const_iterator find(BlockT *B) const { return Frontiers.find(B); }
- iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
+ iterator addBasicBlock(BlockT *BB, const DomSetType &frontier) {
assert(find(BB) == end() && "Block already in DominanceFrontier!");
return Frontiers.insert(std::make_pair(BB, frontier)).first;
}
/// removeBlock - Remove basic block BB's frontier.
- void removeBlock(BasicBlock *BB) {
- assert(find(BB) != end() && "Block is not in DominanceFrontier!");
- for (iterator I = begin(), E = end(); I != E; ++I)
- I->second.erase(BB);
- Frontiers.erase(BB);
- }
+ void removeBlock(BlockT *BB);
- void addToFrontier(iterator I, BasicBlock *Node) {
- assert(I != end() && "BB is not in DominanceFrontier!");
- I->second.insert(Node);
- }
+ void addToFrontier(iterator I, BlockT *Node);
- void removeFromFrontier(iterator I, BasicBlock *Node) {
- assert(I != end() && "BB is not in DominanceFrontier!");
- assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
- I->second.erase(Node);
- }
+ void removeFromFrontier(iterator I, BlockT *Node);
/// compareDomSet - Return false if two domsets match. Otherwise
/// return true;
- bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
- std::set tmpSet;
- for (DomSetType::const_iterator I = DS2.begin(),
- E = DS2.end(); I != E; ++I)
- tmpSet.insert(*I);
-
- for (DomSetType::const_iterator I = DS1.begin(),
- E = DS1.end(); I != E; ) {
- BasicBlock *Node = *I++;
-
- if (tmpSet.erase(Node) == 0)
- // Node is in DS1 but not in DS2.
- return true;
- }
-
- if (!tmpSet.empty())
- // There are nodes that are in DS2 but not in DS1.
- return true;
-
- // DS1 and DS2 matches.
- return false;
- }
+ bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const;
/// compare - Return true if the other dominance frontier base matches
/// this dominance frontier base. Otherwise return false.
- bool compare(DominanceFrontierBase &Other) const {
- DomSetMapType tmpFrontiers;
- for (DomSetMapType::const_iterator I = Other.begin(),
- E = Other.end(); I != E; ++I)
- tmpFrontiers.insert(std::make_pair(I->first, I->second));
-
- for (DomSetMapType::iterator I = tmpFrontiers.begin(),
- E = tmpFrontiers.end(); I != E; ) {
- BasicBlock *Node = I->first;
- const_iterator DFI = find(Node);
- if (DFI == end())
- return true;
-
- if (compareDomSet(I->second, DFI->second))
- return true;
-
- ++I;
- tmpFrontiers.erase(Node);
- }
-
- if (!tmpFrontiers.empty())
- return true;
-
- return false;
- }
+ bool compare(DominanceFrontierBase &Other) const;
/// print - Convert to human readable form
///
- void print(raw_ostream &OS, const Module* = nullptr) const override;
+ void print(raw_ostream &OS) const;
/// dump - Dump the dominance frontier to dbgs().
void dump() const;
};
-
//===-------------------------------------
/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
/// used to compute a forward dominator frontiers.
///
-class DominanceFrontier : public DominanceFrontierBase {
- virtual void anchor();
+template
+class ForwardDominanceFrontierBase : public DominanceFrontierBase {
+private:
+ typedef GraphTraits BlockTraits;
+
public:
+ typedef DominatorTreeBase DomTreeT;
+ typedef DomTreeNodeBase DomTreeNodeT;
+ typedef typename DominanceFrontierBase::DomSetType DomSetType;
+
+ ForwardDominanceFrontierBase() : DominanceFrontierBase(false) {}
+
+ void analyze(DomTreeT &DT) {
+ this->Roots = DT.getRoots();
+ assert(this->Roots.size() == 1 &&
+ "Only one entry block for forward domfronts!");
+ calculate(DT, DT[this->Roots[0]]);
+ }
+
+ const DomSetType &calculate(const DomTreeT &DT, const DomTreeNodeT *Node);
+};
+
+class DominanceFrontier : public FunctionPass {
+ ForwardDominanceFrontierBase Base;
+
+public:
+ typedef DominatorTreeBase DomTreeT;
+ typedef DomTreeNodeBase DomTreeNodeT;
+ typedef DominanceFrontierBase::DomSetType DomSetType;
+ typedef DominanceFrontierBase::iterator iterator;
+ typedef DominanceFrontierBase::const_iterator const_iterator;
+
static char ID; // Pass ID, replacement for typeid
- DominanceFrontier() :
- DominanceFrontierBase(ID, false) {
- initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
- }
- BasicBlock *getRoot() const {
- assert(Roots.size() == 1 && "Should always have entry node!");
- return Roots[0];
+ DominanceFrontier();
+
+ ForwardDominanceFrontierBase &getBase() { return Base; }
+
+ inline const std::vector &getRoots() const {
+ return Base.getRoots();
}
- bool runOnFunction(Function &) override {
- Frontiers.clear();
- DominatorTree &DT = getAnalysis().getDomTree();
- Roots = DT.getRoots();
- assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
- calculate(DT, DT[Roots[0]]);
- return false;
+ BasicBlock *getRoot() const { return Base.getRoot(); }
+
+ bool isPostDominator() const { return Base.isPostDominator(); }
+
+ iterator begin() { return Base.begin(); }
+
+ const_iterator begin() const { return Base.begin(); }
+
+ iterator end() { return Base.end(); }
+
+ const_iterator end() const { return Base.end(); }
+
+ iterator find(BasicBlock *B) { return Base.find(B); }
+
+ const_iterator find(BasicBlock *B) const { return Base.find(B); }
+
+ iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
+ return Base.addBasicBlock(BB, frontier);
+ }
+
+ void removeBlock(BasicBlock *BB) { return Base.removeBlock(BB); }
+
+ void addToFrontier(iterator I, BasicBlock *Node) {
+ return Base.addToFrontier(I, Node);
+ }
+
+ void removeFromFrontier(iterator I, BasicBlock *Node) {
+ return Base.removeFromFrontier(I, Node);
}
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired();
+ bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
+ return Base.compareDomSet(DS1, DS2);
}
- const DomSetType &calculate(const DominatorTree &DT,
- const DomTreeNode *Node);
+ bool compare(DominanceFrontierBase &Other) const {
+ return Base.compare(Other);
+ }
+
+ void releaseMemory() override;
+
+ bool runOnFunction(Function &) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ void print(raw_ostream &OS, const Module * = nullptr) const override;
+
+ void dump() const;
};
+EXTERN_TEMPLATE_INSTANTIATION(class DominanceFrontierBase);
+EXTERN_TEMPLATE_INSTANTIATION(class ForwardDominanceFrontierBase);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Analysis/DominanceFrontierImpl.h b/include/llvm/Analysis/DominanceFrontierImpl.h
new file mode 100644
index 000000000000..04df2cc35d46
--- /dev/null
+++ b/include/llvm/Analysis/DominanceFrontierImpl.h
@@ -0,0 +1,228 @@
+//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the generic implementation of the DominanceFrontier class, which
+// calculate and holds the dominance frontier for a function for.
+//
+// This should be considered deprecated, don't add any more uses of this data
+// structure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_IMPL_H
+#define LLVM_ANALYSIS_DOMINANCEFRONTIER_IMPL_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Debug.h"
+
+namespace llvm {
+
+namespace {
+template
+class DFCalculateWorkObject {
+public:
+ typedef DomTreeNodeBase DomTreeNodeT;
+
+ DFCalculateWorkObject(BlockT *B, BlockT *P, const DomTreeNodeT *N,
+ const DomTreeNodeT *PN)
+ : currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
+ BlockT *currentBB;
+ BlockT *parentBB;
+ const DomTreeNodeT *Node;
+ const DomTreeNodeT *parentNode;
+};
+}
+
+template
+void DominanceFrontierBase::removeBlock(BlockT *BB) {
+ assert(find(BB) != end() && "Block is not in DominanceFrontier!");
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ I->second.erase(BB);
+ Frontiers.erase(BB);
+}
+
+template
+void DominanceFrontierBase::addToFrontier(iterator I,
+ BlockT *Node) {
+ assert(I != end() && "BB is not in DominanceFrontier!");
+ assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
+ I->second.erase(Node);
+}
+
+template
+void DominanceFrontierBase::removeFromFrontier(iterator I,
+ BlockT *Node) {
+ assert(I != end() && "BB is not in DominanceFrontier!");
+ assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
+ I->second.erase(Node);
+}
+
+template
+bool DominanceFrontierBase::compareDomSet(DomSetType &DS1,
+ const DomSetType &DS2) const {
+ std::set tmpSet;
+ for (BlockT *BB : DS2)
+ tmpSet.insert(BB);
+
+ for (typename DomSetType::const_iterator I = DS1.begin(), E = DS1.end();
+ I != E;) {
+ BlockT *Node = *I++;
+
+ if (tmpSet.erase(Node) == 0)
+ // Node is in DS1 but tnot in DS2.
+ return true;
+ }
+
+ if (!tmpSet.empty()) {
+ // There are nodes that are in DS2 but not in DS1.
+ return true;
+ }
+
+ // DS1 and DS2 matches.
+ return false;
+}
+
+template
+bool DominanceFrontierBase::compare(
+ DominanceFrontierBase &Other) const {
+ DomSetMapType tmpFrontiers;
+ for (typename DomSetMapType::const_iterator I = Other.begin(),
+ E = Other.end();
+ I != E; ++I)
+ tmpFrontiers.insert(std::make_pair(I->first, I->second));
+
+ for (typename DomSetMapType::iterator I = tmpFrontiers.begin(),
+ E = tmpFrontiers.end();
+ I != E;) {
+ BlockT *Node = I->first;
+ const_iterator DFI = find(Node);
+ if (DFI == end())
+ return true;
+
+ if (compareDomSet(I->second, DFI->second))
+ return true;
+
+ ++I;
+ tmpFrontiers.erase(Node);
+ }
+
+ if (!tmpFrontiers.empty())
+ return true;
+
+ return false;
+}
+
+template
+void DominanceFrontierBase::print(raw_ostream &OS) const {
+ for (const_iterator I = begin(), E = end(); I != E; ++I) {
+ OS << " DomFrontier for BB ";
+ if (I->first)
+ I->first->printAsOperand(OS, false);
+ else
+ OS << " <>";
+ OS << " is:\t";
+
+ const std::set &BBs = I->second;
+
+ for (const BlockT *BB : BBs) {
+ OS << ' ';
+ if (BB)
+ BB->printAsOperand(OS, false);
+ else
+ OS << "<>";
+ }
+ OS << '\n';
+ }
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+template
+void DominanceFrontierBase::dump() const {
+ print(dbgs());
+}
+#endif
+
+template
+const typename ForwardDominanceFrontierBase::DomSetType &
+ForwardDominanceFrontierBase::calculate(const DomTreeT &DT,
+ const DomTreeNodeT *Node) {
+ BlockT *BB = Node->getBlock();
+ DomSetType *Result = nullptr;
+
+ std::vector> workList;
+ SmallPtrSet visited;
+
+ workList.push_back(DFCalculateWorkObject(BB, nullptr, Node, nullptr));
+ do {
+ DFCalculateWorkObject *currentW = &workList.back();
+ assert(currentW && "Missing work object.");
+
+ BlockT *currentBB = currentW->currentBB;
+ BlockT *parentBB = currentW->parentBB;
+ const DomTreeNodeT *currentNode = currentW->Node;
+ const DomTreeNodeT *parentNode = currentW->parentNode;
+ assert(currentBB && "Invalid work object. Missing current Basic Block");
+ assert(currentNode && "Invalid work object. Missing current Node");
+ DomSetType &S = this->Frontiers[currentBB];
+
+ // Visit each block only once.
+ if (visited.count(currentBB) == 0) {
+ visited.insert(currentBB);
+
+ // Loop over CFG successors to calculate DFlocal[currentNode]
+ for (auto SI = BlockTraits::child_begin(currentBB),
+ SE = BlockTraits::child_end(currentBB);
+ SI != SE; ++SI) {
+ // Does Node immediately dominate this successor?
+ if (DT[*SI]->getIDom() != currentNode)
+ S.insert(*SI);
+ }
+ }
+
+ // At this point, S is DFlocal. Now we union in DFup's of our children...
+ // Loop through and visit the nodes that Node immediately dominates (Node's
+ // children in the IDomTree)
+ bool visitChild = false;
+ for (typename DomTreeNodeT::const_iterator NI = currentNode->begin(),
+ NE = currentNode->end();
+ NI != NE; ++NI) {
+ DomTreeNodeT *IDominee = *NI;
+ BlockT *childBB = IDominee->getBlock();
+ if (visited.count(childBB) == 0) {
+ workList.push_back(DFCalculateWorkObject(
+ childBB, currentBB, IDominee, currentNode));
+ visitChild = true;
+ }
+ }
+
+ // If all children are visited or there is any child then pop this block
+ // from the workList.
+ if (!visitChild) {
+ if (!parentBB) {
+ Result = &S;
+ break;
+ }
+
+ typename DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
+ DomSetType &parentSet = this->Frontiers[parentBB];
+ for (; CDFI != CDFE; ++CDFI) {
+ if (!DT.properlyDominates(parentNode, DT[*CDFI]))
+ parentSet.insert(*CDFI);
+ }
+ workList.pop_back();
+ }
+
+ } while (!workList.empty());
+
+ return *Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 82a788d1bb82..49c88fd5caeb 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -22,26 +22,77 @@
// itself is not, but in practice runtime seems to be in the order of magnitude
// of dominance tree calculation.
//
+// WARNING: LLVM is generally very concerned about compile time such that
+// the use of additional analysis passes in the default
+// optimization sequence is avoided as much as possible.
+// Specifically, if you do not need the RegionInfo, but dominance
+// information could be sufficient please base your work only on
+// the dominator tree. Most passes maintain it, such that using
+// it has often near zero cost. In contrast RegionInfo is by
+// default not available, is not maintained by existing
+// transformations and there is no intention to do so.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGIONINFO_H
#define LLVM_ANALYSIS_REGIONINFO_H
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Analysis/DominanceFrontier.h"
-#include "llvm/Analysis/PostDominators.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
#include