Import LLVM 3.5svn r198450.

This commit is contained in:
joerg 2014-01-05 16:02:49 +00:00
parent eaac9e3d28
commit d149ea39d0
81 changed files with 2351 additions and 773 deletions

View File

@ -11,7 +11,7 @@ set(CMAKE_MODULE_PATH
)
set(LLVM_VERSION_MAJOR 3)
set(LLVM_VERSION_MINOR 4)
set(LLVM_VERSION_MINOR 5)
if (NOT PACKAGE_VERSION)
set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}svn")
@ -94,8 +94,12 @@ set(LLVM_MAIN_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/include)
set(LLVM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(LLVM_TOOLS_BINARY_DIR ${LLVM_BINARY_DIR}/bin)
set(LLVM_EXAMPLES_BINARY_DIR ${LLVM_BINARY_DIR}/examples)
set(LLVM_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
set(LLVM_LIBDIR_SUFFIX "" CACHE STRING "Define suffix of library directory name (32/64)" )
set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib)
set(LLVM_ALL_TARGETS
AArch64
ARM
@ -166,8 +170,6 @@ set(LLVM_TARGETS_TO_BUILD
${LLVM_EXPERIMENTAL_TARGETS_TO_BUILD})
list(REMOVE_DUPLICATES LLVM_TARGETS_TO_BUILD)
set(llvm_builded_incs_dir ${LLVM_BINARY_DIR}/include/llvm)
include(AddLLVMDefinitions)
option(LLVM_ENABLE_PIC "Build Position-Independent Code" ON)
@ -179,6 +181,7 @@ else( MSVC )
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
endif()
option(LLVM_ENABLE_CXX11 "Compile with C++11 enabled." OFF)
option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
option(LLVM_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
@ -378,39 +381,43 @@ endforeach(t)
# include various classes of targets.
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/AsmPrinters.def.in
${LLVM_BINARY_DIR}/include/llvm/Config/AsmPrinters.def
${LLVM_INCLUDE_DIR}/llvm/Config/AsmPrinters.def
)
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/AsmParsers.def.in
${LLVM_BINARY_DIR}/include/llvm/Config/AsmParsers.def
${LLVM_INCLUDE_DIR}/llvm/Config/AsmParsers.def
)
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/Disassemblers.def.in
${LLVM_BINARY_DIR}/include/llvm/Config/Disassemblers.def
${LLVM_INCLUDE_DIR}/llvm/Config/Disassemblers.def
)
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/Targets.def.in
${LLVM_BINARY_DIR}/include/llvm/Config/Targets.def
${LLVM_INCLUDE_DIR}/llvm/Config/Targets.def
)
# Configure the three LLVM configuration header files.
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/config.h.cmake
${LLVM_BINARY_DIR}/include/llvm/Config/config.h)
${LLVM_INCLUDE_DIR}/llvm/Config/config.h)
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/llvm-config.h.cmake
${LLVM_BINARY_DIR}/include/llvm/Config/llvm-config.h)
${LLVM_INCLUDE_DIR}/llvm/Config/llvm-config.h)
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Support/DataTypes.h.cmake
${LLVM_BINARY_DIR}/include/llvm/Support/DataTypes.h)
${LLVM_INCLUDE_DIR}/llvm/Support/DataTypes.h)
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR} )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib )
if( NOT DEFINED CMAKE_INSTALL_RPATH )
set( CMAKE_INSTALL_RPATH "\$ORIGIN/../lib")
endif( NOT DEFINED CMAKE_INSTALL_RPATH )
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories( ${LLVM_BINARY_DIR}/include ${LLVM_MAIN_INCLUDE_DIR})
include_directories( ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR})
if( ${CMAKE_SYSTEM_NAME} MATCHES FreeBSD )
# On FreeBSD, /usr/local/* is not used by default. In order to build LLVM
@ -506,7 +513,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
PATTERN ".svn" EXCLUDE
)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
install(DIRECTORY ${LLVM_INCLUDE_DIR}/
DESTINATION include
FILES_MATCHING
PATTERN "*.def"

View File

@ -45,7 +45,7 @@ D: Hexagon Backend
N: Hal Finkel
E: hfinkel@anl.gov
D: BBVectorize and the PowerPC target
D: BBVectorize, the loop reroller and the PowerPC target
N: Venkatraman Govindaraju
E: venkatra@cs.wisc.edu
@ -143,7 +143,7 @@ E: atrick@apple.com
D: IndVar Simplify, Loop Strength Reduction, Instruction Scheduling
N: Bill Wendling
E: wendling@apple.com
E: isanbard@gmail.com
D: libLTO, IR Linker
N: Peter Zotov

View File

@ -256,7 +256,7 @@ E: sylvestre@debian.org
W: http://sylvestre.ledru.info/
W: http://llvm.org/apt/
D: Debian and Ubuntu packaging
D: Continous integration with jenkins
D: Continuous integration with jenkins
N: Andrew Lenharth
E: alenhar2@cs.uiuc.edu

View File

@ -4,7 +4,7 @@ LLVM Release License
University of Illinois/NCSA
Open Source License
Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign.
Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:

View File

@ -126,6 +126,7 @@ cross-compile-build-tools:
SDKROOT= \
TARGET_NATIVE_ARCH="$(TARGET_NATIVE_ARCH)" \
TARGETS_TO_BUILD="$(TARGETS_TO_BUILD)" \
TARGET_LIBS="$(LIBS)" \
ENABLE_OPTIMIZED=$(ENABLE_OPTIMIZED) \
ENABLE_PROFILING=$(ENABLE_PROFILING) \
ENABLE_COVERAGE=$(ENABLE_COVERAGE) \

View File

@ -608,6 +608,22 @@ ifndef KEEP_SYMBOLS
Install.StripFlag += -s
endif
# By default, strip dead symbols at link time
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
ifneq ($(HOST_OS),Darwin)
CXX.Flags += -ffunction-sections -fdata-sections
endif
endif
ifndef NO_DEAD_STRIP
ifeq ($(HOST_OS),Darwin)
LD.Flags += -Wl,-dead_strip
else
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
LD.Flags += -Wl,--gc-sections
endif
endif
endif
# Adjust linker flags for building an executable
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
ifndef TOOL_NO_EXPORTS

View File

@ -2,10 +2,125 @@ include(LLVMParseArguments)
include(LLVMProcessSources)
include(LLVM-Config)
function(add_llvm_symbol_exports target_name export_file)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(native_export_file "${target_name}.exports")
add_custom_command(OUTPUT ${native_export_file}
COMMAND sed -e "s/^/_/" < ${export_file} > ${native_export_file}
DEPENDS ${export_file}
VERBATIM
COMMENT "Creating export file for ${target_name}")
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,-exported_symbols_list,${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
elseif(LLVM_HAVE_LINK_VERSION_SCRIPT)
# Gold and BFD ld require a version script rather than a plain list.
set(native_export_file "${target_name}.exports")
# FIXME: Don't write the "local:" line on OpenBSD.
add_custom_command(OUTPUT ${native_export_file}
COMMAND echo "{" > ${native_export_file}
COMMAND grep -q "[[:alnum:]]" ${export_file} && echo " global:" >> ${native_export_file} || :
COMMAND sed -e "s/$/;/" -e "s/^/ /" < ${export_file} >> ${native_export_file}
COMMAND echo " local: *;" >> ${native_export_file}
COMMAND echo "};" >> ${native_export_file}
DEPENDS ${export_file}
VERBATIM
COMMENT "Creating export file for ${target_name}")
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
else()
set(native_export_file "${target_name}.def")
set(CAT "type")
if(CYGWIN)
set(CAT "cat")
endif()
# Using ${export_file} in add_custom_command directly confuses cmd.exe.
file(TO_NATIVE_PATH ${export_file} export_file_backslashes)
add_custom_command(OUTPUT ${native_export_file}
COMMAND ${CMAKE_COMMAND} -E echo "EXPORTS" > ${native_export_file}
COMMAND ${CAT} ${export_file_backslashes} >> ${native_export_file}
DEPENDS ${export_file}
VERBATIM
COMMENT "Creating export file for ${target_name}")
if(CYGWIN OR MINGW)
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " ${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
else()
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " /DEF:${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
endif()
endif()
add_custom_target(${target_name}_exports DEPENDS ${native_export_file})
get_property(srcs TARGET ${target_name} PROPERTY SOURCES)
foreach(src ${srcs})
get_filename_component(extension ${src} EXT)
if(extension STREQUAL ".cpp")
set(first_source_file ${src})
break()
endif()
endforeach()
# Force re-linking when the exports file changes. Actually, it
# forces recompilation of the source file. The LINK_DEPENDS target
# property only works for makefile-based generators.
set_property(SOURCE ${first_source_file} APPEND PROPERTY
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${native_export_file})
set_property(DIRECTORY APPEND
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${native_export_file})
add_dependencies(${target_name} ${target_name}_exports)
endfunction(add_llvm_symbol_exports)
function(add_dead_strip target_name)
if(NOT CYGWIN AND NOT MINGW AND NOT MSVC)
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
SET(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections"
PARENT_SCOPE)
endif()
endif()
if(NOT LLVM_NO_DEAD_STRIP)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,-dead_strip")
elseif(NOT WIN32)
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,--gc-sections")
endif()
endif()
endfunction(add_dead_strip)
# Set each output directory according to ${CMAKE_CONFIGURATION_TYPES}.
# 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)
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})
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})
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})
endif()
endfunction()
macro(add_llvm_library name)
llvm_process_sources( ALL_FILES ${ARGN} )
add_library( ${name} ${ALL_FILES} )
set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
set_property( GLOBAL APPEND PROPERTY LLVM_LIBS ${name} )
add_dead_strip( ${name} )
if( LLVM_COMMON_DEPENDS )
add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
endif( LLVM_COMMON_DEPENDS )
@ -17,6 +132,10 @@ macro(add_llvm_library name)
PROPERTIES
IMPORT_SUFFIX ".imp")
endif ()
if (LLVM_EXPORTED_SYMBOL_FILE)
add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
endif()
endif()
# Ensure that the system libraries always comes last on the
@ -58,15 +177,21 @@ ${name} ignored.")
endif()
add_library( ${name} ${libkind} ${ALL_FILES} )
set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
set_target_properties( ${name} PROPERTIES PREFIX "" )
add_dead_strip( ${name} )
if (LLVM_EXPORTED_SYMBOL_FILE)
add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
endif(LLVM_EXPORTED_SYMBOL_FILE)
llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
link_system_libs( ${name} )
if (APPLE)
# Darwin-specific linker flags for loadable modules.
set_target_properties(${name} PROPERTIES
LINK_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
set_property(TARGET ${name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
endif()
if( EXCLUDE_FROM_ALL )
@ -91,7 +216,14 @@ macro(add_llvm_executable name)
else()
add_executable(${name} ${ALL_FILES})
endif()
add_dead_strip( ${name} )
if (LLVM_EXPORTED_SYMBOL_FILE)
add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
endif(LLVM_EXPORTED_SYMBOL_FILE)
set(EXCLUDE_FROM_ALL OFF)
set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
if( LLVM_COMMON_DEPENDS )
add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
@ -152,7 +284,7 @@ endmacro(add_llvm_target)
# Add external project that may want to be built as part of llvm such as Clang,
# lld, and Polly. This adds two options. One for the source directory of the
# project, which defaults to ${CMAKE_CURRENT_SOURCE_DIR}/${name}. Another to
# enable or disable building it with everthing else.
# enable or disable building it with everything else.
# Additional parameter can be specified as the name of directory.
macro(add_llvm_external_project name)
set(add_llvm_external_dir "${ARGN}")
@ -204,12 +336,13 @@ endfunction(add_llvm_implicit_external_projects)
# Generic support for adding a unittest.
function(add_unittest test_suite test_name)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if( NOT LLVM_BUILD_TESTS )
set(EXCLUDE_FROM_ALL ON)
endif()
add_llvm_executable(${test_name} ${ARGN})
set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
set_output_directory(${test_name} ${outdir} ${outdir})
target_link_libraries(${test_name}
gtest
gtest_main
@ -248,7 +381,7 @@ function(add_unittest test_suite test_name)
endfunction()
# This function provides an automatic way to 'configure'-like generate a file
# based on a set of common and custom variables, specifically targetting the
# based on a set of common and custom variables, specifically targeting the
# variables needed for the 'lit.site.cfg' files. This function bundles the
# common variables that any Lit instance is likely to need, and custom
# variables can be passed in.
@ -259,7 +392,6 @@ function(configure_lit_site_cfg input output)
set(TARGETS_TO_BUILD ${TARGETS_BUILT})
set(SHLIBEXT "${LTDL_SHLIB_EXT}")
set(SHLIBDIR "${LLVM_BINARY_DIR}/lib/${CMAKE_CFG_INTDIR}")
if(BUILD_SHARED_LIBS)
set(LLVM_SHARED_LIBS_ENABLED "1")
@ -277,12 +409,17 @@ function(configure_lit_site_cfg input output)
endif()
# Configuration-time: See Unit/lit.site.cfg.in
set(LLVM_BUILD_MODE "%(build_mode)s")
if (CMAKE_CFG_INTDIR STREQUAL ".")
set(LLVM_BUILD_MODE ".")
else ()
set(LLVM_BUILD_MODE "%(build_mode)s")
endif ()
set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR})
set(LLVM_BINARY_DIR ${LLVM_BINARY_DIR})
set(LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}/%(build_mode)s")
set(LLVM_LIBS_DIR "${LLVM_BINARY_DIR}/lib/%(build_mode)s")
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLVM_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLVM_LIBS_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} SHLIBDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
set(ENABLE_SHARED ${LLVM_SHARED_LIBS_ENABLED})
set(SHLIBPATH_VAR ${SHLIBPATH_VAR})
@ -321,10 +458,12 @@ function(add_lit_target target comment)
parse_arguments(ARG "PARAMS;DEPENDS;ARGS" "" ${ARGN})
set(LIT_ARGS "${ARG_ARGS} ${LLVM_LIT_ARGS}")
separate_arguments(LIT_ARGS)
if (NOT CMAKE_CFG_INTDIR STREQUAL ".")
list(APPEND LIT_ARGS --param build_mode=${CMAKE_CFG_INTDIR})
endif ()
set(LIT_COMMAND
${PYTHON_EXECUTABLE}
${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py
--param build_mode=${CMAKE_CFG_INTDIR}
${LIT_ARGS}
)
foreach(param ${ARG_PARAMS})
@ -338,9 +477,12 @@ function(add_lit_target target comment)
add_dependencies(${target} ${ARG_DEPENDS})
else()
add_custom_target(${target}
COMMAND cmake -E echo "${target} does nothing, no tools built.")
COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, no tools built.")
message(STATUS "${target} does nothing.")
endif()
# Tests should be excluded from "Build Solution".
set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)
endfunction()
# A function to add a set of lit test suites to be driven through 'check-*' targets.

View File

@ -24,13 +24,13 @@ if( LLVM_ENABLE_ASSERTIONS )
if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
add_definitions( -UNDEBUG )
# Also remove /D NDEBUG to avoid MSVC warnings about conflicting defines.
set(REGEXP_NDEBUG "(^| )[/-]D *NDEBUG($| )")
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
set(REGEXP_NDEBUG "(^| )[/-]D *NDEBUG($| )")
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
string (REGEX REPLACE "${REGEXP_NDEBUG}" " "
CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
endif()
else()
if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE" )
@ -41,6 +41,7 @@ else()
endif()
if(WIN32)
set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
if(CYGWIN)
set(LLVM_ON_WIN32 0)
set(LLVM_ON_UNIX 1)
@ -57,8 +58,10 @@ else(WIN32)
set(LLVM_ON_WIN32 0)
set(LLVM_ON_UNIX 1)
if(APPLE)
set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
set(LTDL_SHLIB_EXT ".dylib")
else(APPLE)
set(LLVM_HAVE_LINK_VERSION_SCRIPT 1)
set(LTDL_SHLIB_EXT ".so")
endif(APPLE)
set(EXEEXT "")
@ -246,6 +249,10 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
if (LLVM_ENABLE_WERROR)
add_llvm_definitions( -Werror )
endif (LLVM_ENABLE_WERROR)
if (LLVM_ENABLE_CXX11)
check_cxx_compiler_flag("-std=c++11" CXX_SUPPORTS_CXX11)
append_if(CXX_SUPPORTS_CXX11 "-std=c++11" CMAKE_CXX_FLAGS)
endif (LLVM_ENABLE_CXX11)
endif( MSVC )
macro(append_common_sanitizer_flags)

View File

@ -18,8 +18,6 @@ set(LLVM_TARGETS_WITH_JIT @LLVM_TARGETS_WITH_JIT@)
set(TARGET_TRIPLE "@TARGET_TRIPLE@")
set(LLVM_TOOLS_BINARY_DIR @LLVM_TOOLS_BINARY_DIR@)
set(LLVM_ENABLE_TERMINFO @LLVM_ENABLE_TERMINFO@)
set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@)

View File

@ -4,7 +4,7 @@
macro(tablegen project ofn)
file(GLOB local_tds "*.td")
file(GLOB_RECURSE global_tds "${LLVM_MAIN_SRC_DIR}/include/llvm/*.td")
file(GLOB_RECURSE global_tds "${LLVM_MAIN_INCLUDE_DIR}/llvm/*.td")
if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
@ -45,7 +45,7 @@ macro(tablegen project ofn)
PROPERTIES GENERATED 1)
endmacro(tablegen)
function(add_public_tablegen_target target)
macro(add_public_tablegen_target target)
# Creates a target for publicly exporting tablegen dependencies.
if( TABLEGEN_OUTPUT )
add_custom_target(${target}
@ -54,8 +54,9 @@ function(add_public_tablegen_target target)
add_dependencies(${target} ${LLVM_COMMON_DEPENDS})
endif ()
set_target_properties(${target} PROPERTIES FOLDER "Tablegenning")
list(APPEND LLVM_COMMON_DEPENDS ${target} intrinsics_gen)
endif( TABLEGEN_OUTPUT )
endfunction()
endmacro()
if(CMAKE_CROSSCOMPILING)
set(CX_NATIVE_TG_DIR "${CMAKE_BINARY_DIR}/native")
@ -78,23 +79,11 @@ if(CMAKE_CROSSCOMPILING)
endif()
macro(add_tablegen target project)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR})
set(${target}_OLD_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS})
set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} TableGen)
add_llvm_utility(${target} ${ARGN})
set(LLVM_LINK_COMPONENTS ${${target}_OLD_LLVM_LINK_COMPONENTS})
# For Xcode builds, symlink bin/<target> to bin/<Config>/<target> so that
# a separately-configured Clang project can still find llvm-tblgen.
if (XCODE)
add_custom_target(${target}-top ALL
${CMAKE_COMMAND} -E create_symlink
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}${CMAKE_EXECUTABLE_SUFFIX}
DEPENDS ${target})
endif ()
set(${project}_TABLEGEN "${target}" CACHE
STRING "Native TableGen executable. Saves building one when cross-compiling.")

View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.60 for LLVM 3.4.
# Generated by GNU Autoconf 2.60 for LLVM 3.5svn.
#
# Report bugs to <http://llvm.org/bugs/>.
#
@ -9,7 +9,7 @@
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
#
# Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign.
# Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
@ -561,8 +561,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='LLVM'
PACKAGE_TARNAME='llvm'
PACKAGE_VERSION='3.4'
PACKAGE_STRING='LLVM 3.4'
PACKAGE_VERSION='3.5svn'
PACKAGE_STRING='LLVM 3.5svn'
PACKAGE_BUGREPORT='http://llvm.org/bugs/'
ac_unique_file="lib/IR/Module.cpp"
@ -1330,7 +1330,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures LLVM 3.4 to adapt to many kinds of systems.
\`configure' configures LLVM 3.5svn to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1396,7 +1396,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of LLVM 3.4:";;
short | recursive ) echo "Configuration of LLVM 3.5svn:";;
esac
cat <<\_ACEOF
@ -1564,7 +1564,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
LLVM configure 3.4
LLVM configure 3.5svn
generated by GNU Autoconf 2.60
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@ -1572,7 +1572,7 @@ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign.
Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
_ACEOF
exit
fi
@ -1580,7 +1580,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by LLVM $as_me 3.4, which was
It was created by LLVM $as_me 3.5svn, which was
generated by GNU Autoconf 2.60. Invocation command line was
$ $0 $@
@ -1940,11 +1940,11 @@ _ACEOF
cat >>confdefs.h <<\_ACEOF
#define LLVM_VERSION_MINOR 4
#define LLVM_VERSION_MINOR 5
_ACEOF
LLVM_COPYRIGHT="Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign."
LLVM_COPYRIGHT="Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign."
@ -22745,7 +22745,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by LLVM $as_me 3.4, which was
This file was extended by LLVM $as_me 3.5svn, which was
generated by GNU Autoconf 2.60. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -22798,7 +22798,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
LLVM config.status 3.4
LLVM config.status 3.5svn
configured by $0, generated by GNU Autoconf 2.60,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@ -1504,6 +1504,19 @@ public:
return BitWidth - (*this - 1).countLeadingZeros();
}
/// \returns the nearest log base 2 of this APInt. Ties round up.
unsigned nearestLogBase2() const {
// This is implemented by taking the normal log 2 of a number and adding 1
// to it if MSB - 1 is set.
// We follow the model from logBase2 that logBase2(0) == UINT32_MAX. This
// works since if we have 0, MSB will be 0. Then we subtract one yielding
// UINT32_MAX. Finally extractBit of MSB - 1 will be UINT32_MAX implying
// that we get BitWidth - 1.
unsigned lg = logBase2();
return lg + unsigned((*this)[std::min(lg - 1, BitWidth - 1)]);
}
/// \returns the log base 2 of this APInt if its an exact power of two, -1
/// otherwise
int32_t exactLogBase2() const {

View File

@ -185,6 +185,8 @@ namespace llvm {
public:
typedef T *iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
/// Construct an empty MutableArrayRef.
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
@ -219,6 +221,9 @@ namespace llvm {
iterator begin() const { return data(); }
iterator end() const { return data() + this->size(); }
reverse_iterator rbegin() const { return reverse_iterator(end()); }
reverse_iterator rend() const { return reverse_iterator(begin()); }
/// front - Get the first element.
T &front() const {
assert(!this->empty());

View File

@ -267,7 +267,8 @@ public:
Bits[I / BITWORD_SIZE] = ~0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
Bits[I / BITWORD_SIZE] |= PostfixMask;
if (I < E)
Bits[I / BITWORD_SIZE] |= PostfixMask;
return *this;
}
@ -305,7 +306,8 @@ public:
Bits[I / BITWORD_SIZE] = 0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
Bits[I / BITWORD_SIZE] &= ~PostfixMask;
if (I < E)
Bits[I / BITWORD_SIZE] &= ~PostfixMask;
return *this;
}

View File

@ -6,16 +6,18 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected
// components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm.
//
// The SCC iterator has the important property that if a node in SCC S1 has an
// edge to a node in SCC S2, then it visits S1 *after* S2.
//
// To visit S1 *before* S2, use the scc_iterator on the Inverse graph.
// (NOTE: This requires some simple wrappers and is not supported yet.)
//
/// \file
///
/// This builds on the llvm/ADT/GraphTraits.h file to find the strongly
/// connected components (SCCs) of a graph in O(N+E) time using Tarjan's DFS
/// algorithm.
///
/// The SCC iterator has the important property that if a node in SCC S1 has an
/// edge to a node in SCC S2, then it visits S1 *after* S2.
///
/// To visit S1 *before* S2, use the scc_iterator on the Inverse graph. (NOTE:
/// This requires some simple wrappers and is not supported yet.)
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_SCCITERATOR_H
@ -27,18 +29,19 @@
namespace llvm {
//===----------------------------------------------------------------------===//
/// \brief Enumerate the SCCs of a directed graph in reverse topological order
/// of the SCC DAG.
///
/// scc_iterator - Enumerate the SCCs of a directed graph, in
/// reverse topological order of the SCC DAG.
///
template<class GraphT, class GT = GraphTraits<GraphT> >
/// This is implemented using Tarjan's DFS algorithm using an internal stack to
/// build up a vector of nodes in a particular SCC. Note that it is a forward
/// iterator and thus you cannot backtrack or re-visit nodes.
template <class GraphT, class GT = GraphTraits<GraphT> >
class scc_iterator
: public std::iterator<std::forward_iterator_tag,
std::vector<typename GT::NodeType>, ptrdiff_t> {
typedef typename GT::NodeType NodeType;
: public std::iterator<std::forward_iterator_tag,
std::vector<typename GT::NodeType>, ptrdiff_t> {
typedef typename GT::NodeType NodeType;
typedef typename GT::ChildIteratorType ChildItTy;
typedef std::vector<NodeType*> SccTy;
typedef std::vector<NodeType *> SccTy;
typedef std::iterator<std::forward_iterator_tag,
std::vector<typename GT::NodeType>, ptrdiff_t> super;
typedef typename super::reference reference;
@ -50,30 +53,32 @@ class scc_iterator
unsigned visitNum;
DenseMap<NodeType *, unsigned> nodeVisitNumbers;
// SCCNodeStack - Stack holding nodes of the SCC.
// Stack holding nodes of the SCC.
std::vector<NodeType *> SCCNodeStack;
// CurrentSCC - The current SCC, retrieved using operator*().
// The current SCC, retrieved using operator*().
SccTy CurrentSCC;
// VisitStack - Used to maintain the ordering. Top = current block
// First element is basic block pointer, second is the 'next child' to visit
// Used to maintain the ordering. The top is the current block, the first
// element is basic block pointer, second is the 'next child' to visit.
std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
// MinVisitNumStack - Stack holding the "min" values for each node in the DFS.
// This is used to track the minimum uplink values for all children of
// the corresponding node on the VisitStack.
// Stack holding the "min" values for each node in the DFS. This is used to
// track the minimum uplink values for all children of the corresponding node
// on the VisitStack.
std::vector<unsigned> MinVisitNumStack;
// A single "visit" within the non-recursive DFS traversal.
void DFSVisitOne(NodeType *N) {
++visitNum; // Global counter for the visit order
++visitNum;
nodeVisitNumbers[N] = visitNum;
SCCNodeStack.push_back(N);
MinVisitNumStack.push_back(visitNum);
VisitStack.push_back(std::make_pair(N, GT::child_begin(N)));
//dbgs() << "TarjanSCC: Node " << N <<
// " : visitNum = " << visitNum << "\n";
#if 0 // Enable if needed when debugging.
dbgs() << "TarjanSCC: Node " << N <<
" : visitNum = " << visitNum << "\n";
#endif
}
// The stack-based DFS traversal; defined below.
@ -97,10 +102,11 @@ class scc_iterator
// Compute the next SCC using the DFS traversal.
void GetNextSCC() {
assert(VisitStack.size() == MinVisitNumStack.size());
CurrentSCC.clear(); // Prepare to compute the next SCC
CurrentSCC.clear(); // Prepare to compute the next SCC
while (!VisitStack.empty()) {
DFSVisitChildren();
assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first));
assert(VisitStack.back().second ==
GT::child_end(VisitStack.back().first));
NodeType *visitingN = VisitStack.back().first;
unsigned minVisitNum = MinVisitNumStack.back();
VisitStack.pop_back();
@ -108,9 +114,11 @@ class scc_iterator
if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum)
MinVisitNumStack.back() = minVisitNum;
//dbgs() << "TarjanSCC: Popped node " << visitingN <<
// " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
// nodeVisitNumbers[visitingN] << "\n";
#if 0 // Enable if needed when debugging.
dbgs() << "TarjanSCC: Popped node " << visitingN <<
" : minVisitNum = " << minVisitNum << "; Node visit num = " <<
nodeVisitNumbers[visitingN] << "\n";
#endif
if (minVisitNum != nodeVisitNumbers[visitingN])
continue;
@ -132,36 +140,38 @@ class scc_iterator
DFSVisitOne(entryN);
GetNextSCC();
}
inline scc_iterator() { /* End is when DFS stack is empty */ }
// End is when the DFS stack is empty.
inline scc_iterator() {}
public:
typedef scc_iterator<GraphT, GT> _Self;
static inline scc_iterator begin(const GraphT &G) {
return scc_iterator(GT::getEntryNode(G));
}
static inline scc_iterator end(const GraphT &) { return scc_iterator(); }
// Provide static "constructors"...
static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));}
static inline _Self end (const GraphT &) { return _Self(); }
// Direct loop termination test: I.isAtEnd() is more efficient than I == end()
/// \brief Direct loop termination test which is more efficient than
/// comparison with \c end().
inline bool isAtEnd() const {
assert(!CurrentSCC.empty() || VisitStack.empty());
return CurrentSCC.empty();
}
inline bool operator==(const _Self& x) const {
inline bool operator==(const scc_iterator &x) const {
return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
}
inline bool operator!=(const _Self& x) const { return !operator==(x); }
inline bool operator!=(const scc_iterator &x) const { return !operator==(x); }
// Iterator traversal: forward iteration only
inline _Self& operator++() { // Preincrement
inline scc_iterator &operator++() {
GetNextSCC();
return *this;
}
inline _Self operator++(int) { // Postincrement
_Self tmp = *this; ++*this; return tmp;
inline scc_iterator operator++(int) {
scc_iterator tmp = *this;
++*this;
return tmp;
}
// Retrieve a reference to the current SCC
inline const SccTy &operator*() const {
assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
return CurrentSCC;
@ -171,21 +181,24 @@ public:
return CurrentSCC;
}
// hasLoop() -- Test if the current SCC has a loop. If it has more than one
// node, this is trivially true. If not, it may still contain a loop if the
// node has an edge back to itself.
/// \brief Test if the current SCC has a loop.
///
/// If the SCC has more than one node, this is trivially true. If not, it may
/// still contain a loop if the node has an edge back to itself.
bool hasLoop() const {
assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
if (CurrentSCC.size() > 1) return true;
if (CurrentSCC.size() > 1)
return true;
NodeType *N = CurrentSCC.front();
for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI)
for (ChildItTy CI = GT::child_begin(N), CE = GT::child_end(N); CI != CE;
++CI)
if (*CI == N)
return true;
return false;
}
/// ReplaceNode - This informs the scc_iterator that the specified Old node
/// has been deleted, and New is to be used in its place.
/// This informs the \c scc_iterator that the specified \c Old node
/// has been deleted, and \c New is to be used in its place.
void ReplaceNode(NodeType *Old, NodeType *New) {
assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?");
nodeVisitNumbers[New] = nodeVisitNumbers[Old];
@ -193,25 +206,23 @@ public:
}
};
// Global constructor for the SCC iterator.
template <class T>
scc_iterator<T> scc_begin(const T &G) {
/// \brief Construct the begin iterator for a deduced graph type T.
template <class T> scc_iterator<T> scc_begin(const T &G) {
return scc_iterator<T>::begin(G);
}
template <class T>
scc_iterator<T> scc_end(const T &G) {
/// \brief Construct the end iterator for a deduced graph type T.
template <class T> scc_iterator<T> scc_end(const T &G) {
return scc_iterator<T>::end(G);
}
template <class T>
scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) {
/// \brief Construct the begin iterator for a deduced graph type T's Inverse<T>.
template <class T> scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) {
return scc_iterator<Inverse<T> >::begin(G);
}
template <class T>
scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) {
/// \brief Construct the end iterator for a deduced graph type T's Inverse<T>.
template <class T> scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) {
return scc_iterator<Inverse<T> >::end(G);
}

View File

@ -60,8 +60,12 @@ protected:
unsigned NumElements;
unsigned NumTombstones;
// Helper to copy construct a SmallPtrSet.
SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl& that);
// Helpers to copy and move construct a SmallPtrSet.
SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that);
#if LLVM_HAS_RVALUE_REFERENCES
SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize,
SmallPtrSetImpl &&that);
#endif
explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) :
SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
@ -135,6 +139,9 @@ protected:
void swap(SmallPtrSetImpl &RHS);
void CopyFrom(const SmallPtrSetImpl &RHS);
#if LLVM_HAS_RVALUE_REFERENCES
void MoveFrom(unsigned SmallSize, SmallPtrSetImpl &&RHS);
#endif
};
/// SmallPtrSetIteratorImpl - This is the common base class shared between all
@ -242,6 +249,10 @@ class SmallPtrSet : public SmallPtrSetImpl {
public:
SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(SmallStorage, that) {}
#if LLVM_HAS_RVALUE_REFERENCES
SmallPtrSet(SmallPtrSet &&that)
: SmallPtrSetImpl(SmallStorage, SmallSizePowTwo, std::move(that)) {}
#endif
template<typename It>
SmallPtrSet(It I, It E) : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {
@ -260,9 +271,9 @@ public:
return erase_imp(PtrTraits::getAsVoidPointer(Ptr));
}
/// count - Return true if the specified pointer is in the set.
bool count(PtrType Ptr) const {
return count_imp(PtrTraits::getAsVoidPointer(Ptr));
/// count - Return 1 if the specified pointer is in the set, 0 otherwise.
unsigned count(PtrType Ptr) const {
return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0;
}
template <typename IterT>
@ -280,14 +291,22 @@ public:
return iterator(CurArray+CurArraySize, CurArray+CurArraySize);
}
// Allow assignment from any smallptrset with the same element type even if it
// doesn't have the same smallsize.
const SmallPtrSet<PtrType, SmallSize>&
SmallPtrSet<PtrType, SmallSize> &
operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
CopyFrom(RHS);
if (&RHS != this)
CopyFrom(RHS);
return *this;
}
#if LLVM_HAS_RVALUE_REFERENCES
SmallPtrSet<PtrType, SmallSize>&
operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) {
if (&RHS != this)
MoveFrom(SmallSizePowTwo, std::move(RHS));
return *this;
}
#endif
/// swap - Swaps the elements of two sets.
void swap(SmallPtrSet<PtrType, SmallSize> &RHS) {
SmallPtrSetImpl::swap(RHS);

View File

@ -39,16 +39,19 @@ class SmallSet {
public:
SmallSet() {}
bool empty() const { return Vector.empty() && Set.empty(); }
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
return Vector.empty() && Set.empty();
}
unsigned size() const {
return isSmall() ? Vector.size() : Set.size();
}
/// count - Return true if the element is in the set.
bool count(const T &V) const {
/// count - Return 1 if the element is in the set, 0 otherwise.
unsigned count(const T &V) const {
if (isSmall()) {
// Since the collection is small, just do a linear search.
return vfind(V) != Vector.end();
return vfind(V) == Vector.end() ? 0 : 1;
} else {
return Set.count(V);
}

View File

@ -382,7 +382,7 @@ class SparseBitVector {
AtEnd = true;
return;
}
// Set up for next non zero word in bitmap.
// Set up for next non-zero word in bitmap.
BitNumber = Iter->index() * ElementSize;
NextSetBitNumber = Iter->find_first();
BitNumber += NextSetBitNumber;

View File

@ -227,10 +227,11 @@ public:
return const_cast<SparseSet*>(this)->findIndex(KeyIndexOf(Key));
}
/// count - Returns true if this set contains an element identified by Key.
/// count - Returns 1 if this set contains an element identified by Key,
/// 0 otherwise.
///
bool count(const KeyT &Key) const {
return find(Key) != end();
unsigned count(const KeyT &Key) const {
return find(Key) == end() ? 0 : 1;
}
/// insert - Attempts to insert a new element.

View File

@ -26,19 +26,6 @@ namespace llvm {
template<typename ValueTy>
class StringMapEntry;
/// StringMapEntryInitializer - This datatype can be partially specialized for
/// various datatypes in a stringmap to allow them to be initialized when an
/// entry is default constructed for the map.
template<typename ValueTy>
class StringMapEntryInitializer {
public:
template <typename InitTy>
static void Initialize(StringMapEntry<ValueTy> &T, InitTy InitVal) {
T.second = InitVal;
}
};
/// StringMapEntryBase - Shared base class of StringMapEntry instances.
class StringMapEntryBase {
unsigned StrLen;
@ -161,15 +148,12 @@ public:
static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
// Default construct the value.
new (NewItem) StringMapEntry(KeyLength);
new (NewItem) StringMapEntry(KeyLength, InitVal);
// Copy the string information.
char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
memcpy(StrBuffer, KeyStart, KeyLength);
StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
// Initialize the value if the client wants to.
StringMapEntryInitializer<ValueTy>::Initialize(*NewItem, InitVal);
return NewItem;
}
@ -313,6 +297,7 @@ public:
return GetOrCreateValue(Key).getValue();
}
/// count - Return 1 if the element is in the map, 0 otherwise.
size_type count(StringRef Key) const {
return find(Key) == end() ? 0 : 1;
}

View File

@ -121,6 +121,7 @@ public:
GNUEABIHF,
GNUX32,
EABI,
EABIHF,
MachO,
Android,
ELF
@ -341,17 +342,17 @@ public:
/// \brief Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
return !isOSDarwin() && !isOSWindows();
return !isOSBinFormatMachO() && !isOSBinFormatCOFF();
}
/// \brief Tests whether the OS uses the COFF binary format.
bool isOSBinFormatCOFF() const {
return isOSWindows();
return getEnvironment() != Triple::ELF &&
getEnvironment() != Triple::MachO && isOSWindows();
}
/// \brief Tests whether the environment is MachO.
// FIXME: Should this be an OSBinFormat predicate?
bool isEnvironmentMachO() const {
bool isOSBinFormatMachO() const {
return getEnvironment() == Triple::MachO || isOSDarwin();
}

View File

@ -57,6 +57,10 @@ namespace llvm {
/// with different address spaces: the instruction is replaced by a pair
/// ptrtoint+inttoptr.
Value *UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy);
/// Check the debug info version number, if it is out-dated, drop the debug
/// info. Return true if module is modified.
bool UpgradeDebugInfo(Module &M);
} // End llvm namespace
#endif

View File

@ -415,10 +415,13 @@ namespace llvm {
StringRef UniqueIdentifier = StringRef());
/// createSubroutineType - Create subroutine type.
/// @param File File in which this subroutine is defined.
/// @param ParameterTypes An array of subroutine parameter types. This
/// includes return type at 0th index.
DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes);
/// @param File File in which this subroutine is defined.
/// @param ParameterTypes An array of subroutine parameter types. This
/// includes return type at 0th index.
/// @param Flags E.g.: LValueReference.
/// These flags are used to emit dwarf attributes.
DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes,
unsigned Flags = 0);
/// createArtificialType - Create a new DIType with "artificial" flag set.
DIType createArtificialType(DIType Ty);
@ -506,7 +509,7 @@ namespace llvm {
/// @param Ty Variable Type
/// @param AlwaysPreserve Boolean. Set to true if debug info for this
/// variable should be preserved in optimized build.
/// @param Flags Flags, e.g. artificial variable.
/// @param Flags Flags, e.g. artificial variable.
/// @param ArgNo If this variable is an argument then this argument's
/// number. 1 indicates 1st argument.
DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope,
@ -546,7 +549,7 @@ namespace llvm {
/// @param isDefinition True if this is a function definition.
/// @param ScopeLine Set to the beginning of the scope this starts
/// @param Flags e.g. is this function prototyped or not.
/// This flags are used to emit dwarf attributes.
/// These flags are used to emit dwarf attributes.
/// @param isOptimized True if optimization is ON.
/// @param Fn llvm::Function pointer.
/// @param TParam Function template parameters.

View File

@ -64,20 +64,22 @@ class DIDescriptor {
public:
enum {
FlagPrivate = 1 << 0,
FlagProtected = 1 << 1,
FlagFwdDecl = 1 << 2,
FlagAppleBlock = 1 << 3,
FlagBlockByrefStruct = 1 << 4,
FlagVirtual = 1 << 5,
FlagArtificial = 1 << 6,
FlagExplicit = 1 << 7,
FlagPrototyped = 1 << 8,
FlagPrivate = 1 << 0,
FlagProtected = 1 << 1,
FlagFwdDecl = 1 << 2,
FlagAppleBlock = 1 << 3,
FlagBlockByrefStruct = 1 << 4,
FlagVirtual = 1 << 5,
FlagArtificial = 1 << 6,
FlagExplicit = 1 << 7,
FlagPrototyped = 1 << 8,
FlagObjcClassComplete = 1 << 9,
FlagObjectPointer = 1 << 10,
FlagVector = 1 << 11,
FlagStaticMember = 1 << 12,
FlagIndirectVariable = 1 << 13
FlagObjectPointer = 1 << 10,
FlagVector = 1 << 11,
FlagStaticMember = 1 << 12,
FlagIndirectVariable = 1 << 13,
FlagLValueReference = 1 << 14,
FlagRValueReference = 1 << 15
};
protected:
@ -313,6 +315,12 @@ public:
}
bool isVector() const { return (getFlags() & FlagVector) != 0; }
bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
bool isLValueReference() const {
return (getFlags() & FlagLValueReference) != 0;
}
bool isRValueReference() const {
return (getFlags() & FlagRValueReference) != 0;
}
bool isValid() const { return DbgNode && isType(); }
/// replaceAllUsesWith - Replace all uses of debug info referenced by
@ -377,7 +385,6 @@ public:
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
void addMember(DIDescriptor D);
unsigned getRunTimeLang() const { return getUnsignedField(11); }
DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
void setContainingType(DICompositeType ContainingType);
@ -470,6 +477,19 @@ public:
return (getUnsignedField(13) & FlagPrototyped) != 0;
}
/// Return true if this subprogram is a C++11 reference-qualified
/// non-static member function (void foo() &).
unsigned isLValueReference() const {
return (getUnsignedField(13) & FlagLValueReference) != 0;
}
/// Return true if this subprogram is a C++11
/// rvalue-reference-qualified non-static member function
/// (void foo() &&).
unsigned isRValueReference() const {
return (getUnsignedField(13) & FlagRValueReference) != 0;
}
unsigned isOptimized() const;
/// Verify - Verify that a subprogram descriptor is well formed.
@ -753,6 +773,15 @@ DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
/// Construct DITypeIdentifierMap by going through retained types of each CU.
DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
/// Strip debug info in the module if it exists.
/// To do this, we remove all calls to the debugger intrinsics and any named
/// metadata for debugging. We also remove debug locations for instructions.
/// Return true if module is modified.
bool StripDebugInfo(Module &M);
/// Return Debug Info Metadata Version by checking module flags.
unsigned getDebugMetadataVersionFromModule(const Module &M);
/// DebugInfoFinder tries to list all debug info MDNodes used in a module. To
/// list debug info MDNodes used by an instruction, DebugInfoFinder uses
/// processDeclare, processValue and processLocation to handle DbgDeclareInst,

View File

@ -59,7 +59,7 @@ public:
/// containing function.
bool hasByValAttr() const;
/// \brief If this is a byval argument, return its alignment.
/// \brief If this is a byval or inalloca argument, return its alignment.
unsigned getParamAlignment() const;
/// \brief Return true if this argument has the nest attribute on it in its
@ -86,6 +86,9 @@ public:
/// on it in its containing function.
bool onlyReadsMemory() const;
/// \brief Return true if this argument has the inalloca attribute on it in
/// its containing function.
bool hasInAllocaAttr() const;
/// \brief Add a Attribute to an argument.
void addAttr(AttributeSet AS);

View File

@ -71,6 +71,7 @@ public:
Builtin, ///< Callee is recognized as a builtin, despite
///< nobuiltin attribute on its declaration.
ByVal, ///< Pass structure by value
InAlloca, ///< Pass structure in an alloca
Cold, ///< Marks function as being in a cold path.
InlineHint, ///< Source said inlining was desirable
InReg, ///< Force argument to be passed in register

View File

@ -3,5 +3,5 @@ set(LLVM_TARGET_DEFINITIONS Intrinsics.td)
tablegen(LLVM Intrinsics.gen -gen-intrinsic)
add_custom_target(intrinsics_gen ALL
DEPENDS ${llvm_builded_incs_dir}/IR/Intrinsics.gen)
DEPENDS ${LLVM_INCLUDE_DIR}/llvm/IR/Intrinsics.gen)
set_target_properties(intrinsics_gen PROPERTIES FOLDER "Tablegenning")

View File

@ -943,12 +943,20 @@ public:
Type *Ty ///< The type to trunc or bitcast C to
);
/// @brief Create a BitCast or a PtrToInt cast constant expression
/// @brief Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant
/// expression.
static Constant *getPointerCast(
Constant *C, ///< The pointer value to be casted (operand 0)
Type *Ty ///< The type to which cast should be made
);
/// @brief Create a BitCast or AddrSpaceCast for a pointer type depending on
/// the address space.
static Constant *getPointerBitCastOrAddrSpaceCast(
Constant *C, ///< The constant to addrspacecast or bitcast
Type *Ty ///< The type to bitcast or addrspacecast C to
);
/// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts
static Constant *getIntegerCast(
Constant *C, ///< The integer constant to be casted

View File

@ -34,6 +34,7 @@ class Type;
class IntegerType;
class StructType;
class StructLayout;
class Triple;
class GlobalVariable;
class LLVMContext;
template<typename T>
@ -45,8 +46,7 @@ enum AlignTypeEnum {
INTEGER_ALIGN = 'i', ///< Integer type alignment
VECTOR_ALIGN = 'v', ///< Vector type alignment
FLOAT_ALIGN = 'f', ///< Floating point type alignment
AGGREGATE_ALIGN = 'a', ///< Aggregate alignment
STACK_ALIGN = 's' ///< Stack objects alignment
AGGREGATE_ALIGN = 'a' ///< Aggregate alignment
};
/// Layout alignment element.
@ -78,12 +78,12 @@ struct LayoutAlignElem {
struct PointerAlignElem {
unsigned ABIAlign; ///< ABI alignment for this type/bitw
unsigned PrefAlign; ///< Pref. alignment for this type/bitw
uint32_t TypeBitWidth; ///< Type bit width
uint32_t TypeByteWidth; ///< Type byte width
uint32_t AddressSpace; ///< Address space for the pointer type
/// Initializer
static PointerAlignElem get(uint32_t addr_space, unsigned abi_align,
unsigned pref_align, uint32_t bit_width);
static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign,
unsigned PrefAlign, uint32_t TypeByteWidth);
/// Equality predicate
bool operator==(const PointerAlignElem &rhs) const;
};
@ -100,6 +100,15 @@ private:
bool LittleEndian; ///< Defaults to false
unsigned StackNaturalAlign; ///< Stack natural alignment
enum ManglingModeT {
MM_None,
MM_ELF,
MM_MachO,
MM_COFF,
MM_Mips
};
ManglingModeT ManglingMode;
SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers.
/// Alignments - Where the primitive type alignment data is stored.
@ -129,8 +138,8 @@ private:
bool ABIAlign, Type *Ty) const;
//! Set/initialize pointer alignments
void setPointerAlignment(uint32_t addr_space, unsigned abi_align,
unsigned pref_align, uint32_t bit_width);
void setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
unsigned PrefAlign, uint32_t TypeByteWidth);
//! Internal helper method that returns requested alignment for type.
unsigned getAlignment(Type *Ty, bool abi_or_pref) const;
@ -175,6 +184,7 @@ public:
ImmutablePass(ID),
LittleEndian(DL.isLittleEndian()),
StackNaturalAlign(DL.StackNaturalAlign),
ManglingMode(DL.ManglingMode),
LegalIntWidths(DL.LegalIntWidths),
Alignments(DL.Alignments),
Pointers(DL.Pointers),
@ -223,6 +233,48 @@ public:
return (StackNaturalAlign != 0) && (Align > StackNaturalAlign);
}
bool hasMicrosoftFastStdCallMangling() const {
return ManglingMode == MM_COFF;
}
bool hasLinkerPrivateGlobalPrefix() const {
return ManglingMode == MM_MachO;
}
const char *getLinkerPrivateGlobalPrefix() const {
if (ManglingMode == MM_MachO)
return "l";
return getPrivateGlobalPrefix();
}
char getGlobalPrefix() const {
switch (ManglingMode) {
case MM_None:
case MM_ELF:
case MM_Mips:
return '\0';
case MM_MachO:
case MM_COFF:
return '_';
}
}
const char *getPrivateGlobalPrefix() const {
switch (ManglingMode) {
case MM_None:
return "";
case MM_ELF:
return ".L";
case MM_Mips:
return "$";
case MM_MachO:
case MM_COFF:
return "L";
}
}
static const char *getManglingComponent(const Triple &T);
/// fitsInLegalInteger - This function returns true if the specified type fits
/// in a native integer type supported by the CPU. For example, if the CPU
/// only supports i32 as a native integer type, then i27 fits in a legal
@ -263,7 +315,7 @@ public:
if (val == Pointers.end()) {
val = Pointers.find(0);
}
return val->second.TypeBitWidth;
return val->second.TypeByteWidth;
}
/// Layout pointer size, in bits
/// FIXME: The defaults need to be removed once all of
@ -344,10 +396,6 @@ public:
/// an integer type of the specified bitwidth.
unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const;
/// getCallFrameTypeAlignment - Return the minimum ABI-required alignment
/// for the specified type when it is part of a call frame.
unsigned getCallFrameTypeAlignment(Type *Ty) const;
/// getPrefTypeAlignment - Return the preferred stack/global alignment for
/// the specified type. This is always at least as good as the ABI alignment.
unsigned getPrefTypeAlignment(Type *Ty) const;

View File

@ -249,7 +249,7 @@ public:
bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; }
/// isSized - Return true if this is a sized type.
bool isSized() const;
bool isSized(SmallPtrSet<const Type*, 4> *Visited = 0) const;
/// hasName - Return true if this is a named struct that has a non-empty name.
bool hasName() const { return SymbolTableEntry != 0; }

View File

@ -0,0 +1,165 @@
//===- llvm/Support/DiagnosticInfo.h - Diagnostic Declaration ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the different classes involved in low level diagnostics.
//
// Diagnostics reporting is still done as part of the LLVMContext.
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_DIAGNOSTICINFO_H
#define LLVM_SUPPORT_DIAGNOSTICINFO_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Casting.h"
namespace llvm {
// Forward declarations.
class DiagnosticPrinter;
class Function;
class Instruction;
class Twine;
class Value;
/// \brief Defines the different supported severity of a diagnostic.
enum DiagnosticSeverity {
DS_Error,
DS_Warning,
DS_Note
};
/// \brief Defines the different supported kind of a diagnostic.
/// This enum should be extended with a new ID for each added concrete subclass.
enum DiagnosticKind {
DK_InlineAsm,
DK_StackSize,
DK_FirstPluginKind
};
/// \brief Get the next available kind ID for a plugin diagnostic.
/// Each time this function is called, it returns a different number.
/// Therefore, a plugin that wants to "identify" its own classes
/// with a dynamic identifier, just have to use this method to get a new ID
/// and assign it to each of its classes.
/// The returned ID will be greater than or equal to DK_FirstPluginKind.
/// Thus, the plugin identifiers will not conflict with the
/// DiagnosticKind values.
int getNextAvailablePluginDiagnosticKind();
/// \brief This is the base abstract class for diagnostic reporting in
/// the backend.
/// The print method must be overloaded by the subclasses to print a
/// user-friendly message in the client of the backend (let us call it a
/// frontend).
class DiagnosticInfo {
private:
/// Kind defines the kind of report this is about.
const /* DiagnosticKind */ int Kind;
/// Severity gives the severity of the diagnostic.
const DiagnosticSeverity Severity;
public:
DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
: Kind(Kind), Severity(Severity) {}
virtual ~DiagnosticInfo() {}
/* DiagnosticKind */ int getKind() const { return Kind; }
DiagnosticSeverity getSeverity() const { return Severity; }
/// Print using the given \p DP a user-friendly message.
/// This is the default message that will be printed to the user.
/// It is used when the frontend does not directly take advantage
/// of the information contained in fields of the subclasses.
/// The printed message must not end with '.' nor start with a severity
/// keyword.
virtual void print(DiagnosticPrinter &DP) const = 0;
};
/// Diagnostic information for inline asm reporting.
/// This is basically a message and an optional location.
class DiagnosticInfoInlineAsm : public DiagnosticInfo {
private:
/// Optional line information. 0 if not set.
unsigned LocCookie;
/// Message to be reported.
const Twine &MsgStr;
/// Optional origin of the problem.
const Instruction *Instr;
public:
/// \p MsgStr is the message to be reported to the frontend.
/// This class does not copy \p MsgStr, therefore the reference must be valid
/// for the whole life time of the Diagnostic.
DiagnosticInfoInlineAsm(const Twine &MsgStr,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
Instr(NULL) {}
/// \p LocCookie if non-zero gives the line number for this report.
/// \p MsgStr gives the message.
/// This class does not copy \p MsgStr, therefore the reference must be valid
/// for the whole life time of the Diagnostic.
DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
MsgStr(MsgStr), Instr(NULL) {}
/// \p Instr gives the original instruction that triggered the diagnostic.
/// \p MsgStr gives the message.
/// This class does not copy \p MsgStr, therefore the reference must be valid
/// for the whole life time of the Diagnostic.
/// Same for \p I.
DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
DiagnosticSeverity Severity = DS_Error);
unsigned getLocCookie() const { return LocCookie; }
const Twine &getMsgStr() const { return MsgStr; }
const Instruction *getInstruction() const { return Instr; }
/// \see DiagnosticInfo::print.
virtual void print(DiagnosticPrinter &DP) const;
/// Hand rolled RTTI.
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_InlineAsm;
}
};
/// Diagnostic information for stack size reporting.
/// This is basically a function and a size.
class DiagnosticInfoStackSize : public DiagnosticInfo {
private:
/// The function that is concerned by this stack size diagnostic.
const Function &Fn;
/// The computed stack size.
unsigned StackSize;
public:
/// \p The function that is concerned by this stack size diagnostic.
/// \p The computed stack size.
DiagnosticInfoStackSize(const Function &Fn, unsigned StackSize,
DiagnosticSeverity Severity = DS_Warning)
: DiagnosticInfo(DK_StackSize, Severity), Fn(Fn), StackSize(StackSize) {}
const Function &getFunction() const { return Fn; }
unsigned getStackSize() const { return StackSize; }
/// \see DiagnosticInfo::print.
virtual void print(DiagnosticPrinter &DP) const;
/// Hand rolled RTTI.
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_StackSize;
}
};
} // End namespace llvm
#endif

View File

@ -0,0 +1,84 @@
//===- llvm/Support/DiagnosticPrinter.h - Diagnostic Printer ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the main interface for printer backend diagnostic.
//
// Clients of the backend diagnostics should overload this interface based
// on their needs.
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_DIAGNOSTICPRINTER_H
#define LLVM_SUPPORT_DIAGNOSTICPRINTER_H
#include <string>
namespace llvm {
// Forward declarations.
class raw_ostream;
class StringRef;
class Twine;
class Value;
/// \brief Interface for custom diagnostic printing.
class DiagnosticPrinter {
public:
virtual ~DiagnosticPrinter() {}
// Simple types.
virtual DiagnosticPrinter &operator<<(char C) = 0;
virtual DiagnosticPrinter &operator<<(unsigned char C) = 0;
virtual DiagnosticPrinter &operator<<(signed char C) = 0;
virtual DiagnosticPrinter &operator<<(StringRef Str) = 0;
virtual DiagnosticPrinter &operator<<(const char *Str) = 0;
virtual DiagnosticPrinter &operator<<(const std::string &Str) = 0;
virtual DiagnosticPrinter &operator<<(unsigned long N) = 0;
virtual DiagnosticPrinter &operator<<(long N) = 0;
virtual DiagnosticPrinter &operator<<(unsigned long long N) = 0;
virtual DiagnosticPrinter &operator<<(long long N) = 0;
virtual DiagnosticPrinter &operator<<(const void *P) = 0;
virtual DiagnosticPrinter &operator<<(unsigned int N) = 0;
virtual DiagnosticPrinter &operator<<(int N) = 0;
virtual DiagnosticPrinter &operator<<(double N) = 0;
virtual DiagnosticPrinter &operator<<(const Twine &Str) = 0;
// IR related types.
virtual DiagnosticPrinter &operator<<(const Value &V) = 0;
};
/// \brief Basic diagnostic printer that uses an underlying raw_ostream.
class DiagnosticPrinterRawOStream : public DiagnosticPrinter {
protected:
raw_ostream &Stream;
public:
DiagnosticPrinterRawOStream(raw_ostream &Stream) : Stream(Stream) {};
// Simple types.
virtual DiagnosticPrinter &operator<<(char C);
virtual DiagnosticPrinter &operator<<(unsigned char C);
virtual DiagnosticPrinter &operator<<(signed char C);
virtual DiagnosticPrinter &operator<<(StringRef Str);
virtual DiagnosticPrinter &operator<<(const char *Str);
virtual DiagnosticPrinter &operator<<(const std::string &Str);
virtual DiagnosticPrinter &operator<<(unsigned long N);
virtual DiagnosticPrinter &operator<<(long N);
virtual DiagnosticPrinter &operator<<(unsigned long long N);
virtual DiagnosticPrinter &operator<<(long long N);
virtual DiagnosticPrinter &operator<<(const void *P);
virtual DiagnosticPrinter &operator<<(unsigned int N);
virtual DiagnosticPrinter &operator<<(int N);
virtual DiagnosticPrinter &operator<<(double N);
virtual DiagnosticPrinter &operator<<(const Twine &Str);
// IR related types.
virtual DiagnosticPrinter &operator<<(const Value &V);
};
} // End namespace llvm
#endif

View File

@ -832,11 +832,15 @@ public:
}
Value *CreateBinOp(Instruction::BinaryOps Opc,
Value *LHS, Value *RHS, const Twine &Name = "") {
Value *LHS, Value *RHS, const Twine &Name = "",
MDNode *FPMathTag = 0) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateBinOp(Opc, LC, RC), Name);
return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
llvm::Instruction *BinOp = BinaryOperator::Create(Opc, LHS, RHS);
if (isa<FPMathOperator>(BinOp))
BinOp = AddFPMathAttributes(BinOp, FPMathTag, FMF);
return Insert(BinOp, Name);
}
Value *CreateNeg(Value *V, const Twine &Name = "",
@ -915,8 +919,9 @@ public:
return SI;
}
FenceInst *CreateFence(AtomicOrdering Ordering,
SynchronizationScope SynchScope = CrossThread) {
return Insert(new FenceInst(Context, Ordering, SynchScope));
SynchronizationScope SynchScope = CrossThread,
const Twine &Name = "") {
return Insert(new FenceInst(Context, Ordering, SynchScope), Name);
}
AtomicCmpXchgInst *CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New,
AtomicOrdering Ordering,

View File

@ -458,13 +458,13 @@ def int_invariant_end : Intrinsic<[],
//===------------------------ Stackmap Intrinsics -------------------------===//
//
def int_experimental_stackmap : Intrinsic<[],
[llvm_i32_ty, llvm_i32_ty, llvm_vararg_ty]>;
[llvm_i64_ty, llvm_i32_ty, llvm_vararg_ty]>;
def int_experimental_patchpoint_void : Intrinsic<[],
[llvm_i32_ty, llvm_i32_ty,
[llvm_i64_ty, llvm_i32_ty,
llvm_ptr_ty, llvm_i32_ty,
llvm_vararg_ty]>;
def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty],
[llvm_i32_ty, llvm_i32_ty,
[llvm_i64_ty, llvm_i32_ty,
llvm_ptr_ty, llvm_i32_ty,
llvm_vararg_ty]>;

View File

@ -36,27 +36,11 @@ def int_aarch64_neon_xtn :
// Vector floating-point convert
def int_aarch64_neon_frintn : Neon_1Arg_Intrinsic;
def int_aarch64_neon_fsqrt : Neon_1Arg_Intrinsic;
def int_aarch64_neon_fcvtxn :
def int_aarch64_neon_vcvtxn :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtns :
def int_aarch64_neon_vcvtzs :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtnu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtps :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtpu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtms :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtmu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtas :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtau :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtzs :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtzu :
def int_aarch64_neon_vcvtzu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Vector maxNum (Floating Point)
@ -107,9 +91,6 @@ def int_aarch64_neon_vuqrshrn : Neon_N2V_Narrow_Intrinsic;
class Neon_Across_Intrinsic
: Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
class Neon_2Arg_Across_Float_Intrinsic
: Intrinsic<[llvm_anyvector_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_aarch64_neon_saddlv : Neon_Across_Intrinsic;
def int_aarch64_neon_uaddlv : Neon_Across_Intrinsic;
def int_aarch64_neon_smaxv : Neon_Across_Intrinsic;
@ -117,10 +98,14 @@ def int_aarch64_neon_umaxv : Neon_Across_Intrinsic;
def int_aarch64_neon_sminv : Neon_Across_Intrinsic;
def int_aarch64_neon_uminv : Neon_Across_Intrinsic;
def int_aarch64_neon_vaddv : Neon_Across_Intrinsic;
def int_aarch64_neon_vmaxv : Neon_Across_Intrinsic;
def int_aarch64_neon_vminv : Neon_Across_Intrinsic;
def int_aarch64_neon_vmaxnmv : Neon_Across_Intrinsic;
def int_aarch64_neon_vminnmv : Neon_Across_Intrinsic;
def int_aarch64_neon_vmaxv :
Intrinsic<[llvm_float_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vminv :
Intrinsic<[llvm_float_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vmaxnmv :
Intrinsic<[llvm_float_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vminnmv :
Intrinsic<[llvm_float_ty], [llvm_v4f32_ty], [IntrNoMem]>;
// Vector Table Lookup.
def int_aarch64_neon_vtbl1 :
@ -233,74 +218,118 @@ def int_aarch64_neon_vqrshlu : Neon_2Arg_Intrinsic;
def int_aarch64_neon_vpadd :
Intrinsic<[llvm_v1i64_ty], [llvm_v2i64_ty],[IntrNoMem]>;
def int_aarch64_neon_vpfadd :
Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vpfaddq :
Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Reduce Pairwise Floating Point Max/Min.
def int_aarch64_neon_vpmax :
Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vpmaxq :
Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_vpmin :
Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vpminq :
Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Reduce Pairwise Floating Point Maxnm/Minnm.
def int_aarch64_neon_vpfmaxnm :
Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vpfmaxnmq :
Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_vpfminnm :
Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vpfminnmq :
Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Signed Integer Convert To Floating-point
def int_aarch64_neon_vcvtf32_s32 :
Intrinsic<[llvm_float_ty], [llvm_v1i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtf64_s64 :
Intrinsic<[llvm_double_ty], [llvm_v1i64_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtint2fps :
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Unsigned Integer Convert To Floating-point
def int_aarch64_neon_vcvtf32_u32 :
Intrinsic<[llvm_float_ty], [llvm_v1i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtf64_u64 :
Intrinsic<[llvm_double_ty], [llvm_v1i64_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtint2fpu :
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Floating-point Convert
def int_aarch64_neon_fcvtxn :
Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtns :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtnu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtps :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtpu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtms :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtmu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtas :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtau :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtzs :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_aarch64_neon_fcvtzu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
// Scalar Floating-point Reciprocal Estimate.
def int_aarch64_neon_vrecpe :
Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
// Scalar Floating-point Reciprocal Exponent
def int_aarch64_neon_vrecpx : Neon_1Arg_Intrinsic;
def int_aarch64_neon_vrecpx :
Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
class Neon_Cmp_Intrinsic
: Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, llvm_anyvector_ty],
[IntrNoMem]>;
// Scalar Floating-point Reciprocal Square Root Estimate
def int_aarch64_neon_vrsqrte :
Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
// Scalar Floating-point Reciprocal Step
def int_aarch64_neon_vrecps :
Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem]>;
// Scalar Floating-point Reciprocal Square Root Step
def int_aarch64_neon_vrsqrts :
Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem]>;
// Compare with vector operands.
class Neon_Cmp_Intrinsic :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, llvm_anyvector_ty],
[IntrNoMem]>;
// Floating-point compare with scalar operands.
class Neon_Float_Cmp_Intrinsic :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty, llvm_anyfloat_ty],
[IntrNoMem]>;
// Scalar Compare Equal
def int_aarch64_neon_vceq : Neon_Cmp_Intrinsic;
def int_aarch64_neon_fceq : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Greater-Than or Equal
def int_aarch64_neon_vcge : Neon_Cmp_Intrinsic;
def int_aarch64_neon_vchs : Neon_Cmp_Intrinsic;
def int_aarch64_neon_fcge : Neon_Float_Cmp_Intrinsic;
def int_aarch64_neon_fchs : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Less-Than or Equal
def int_aarch64_neon_vclez : Neon_Cmp_Intrinsic;
def int_aarch64_neon_fclez : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Less-Than
def int_aarch64_neon_vcltz : Neon_Cmp_Intrinsic;
def int_aarch64_neon_fcltz : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Greater-Than
def int_aarch64_neon_vcgt : Neon_Cmp_Intrinsic;
def int_aarch64_neon_vchi : Neon_Cmp_Intrinsic;
def int_aarch64_neon_fcgt : Neon_Float_Cmp_Intrinsic;
def int_aarch64_neon_fchi : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Bitwise Test Bits
def int_aarch64_neon_vtstd : Neon_Cmp_Intrinsic;
// Scalar Floating-point Absolute Compare Greater Than Or Equal
def int_aarch64_neon_vcage : Neon_Cmp_Intrinsic;
def int_aarch64_neon_fcage : Neon_Float_Cmp_Intrinsic;
// Scalar Floating-point Absolute Compare Greater Than
def int_aarch64_neon_vcagt : Neon_Cmp_Intrinsic;
def int_aarch64_neon_fcagt : Neon_Float_Cmp_Intrinsic;
// Scalar Signed Saturating Accumulated of Unsigned Value
def int_aarch64_neon_vuqadd : Neon_2Arg_Intrinsic;
@ -313,7 +342,9 @@ def int_aarch64_neon_vabs :
Intrinsic<[llvm_v1i64_ty], [llvm_v1i64_ty], [IntrNoMem]>;
// Scalar Absolute Difference
def int_aarch64_neon_vabd : Neon_2Arg_Intrinsic;
def int_aarch64_neon_vabd :
Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem]>;
// Scalar Negate Value
def int_aarch64_neon_vneg :
@ -325,6 +356,9 @@ def int_aarch64_neon_vqdmlal : Neon_3Arg_Long_Intrinsic;
// Signed Saturating Doubling Multiply-Subtract Long
def int_aarch64_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic;
def int_aarch64_neon_vmull_p64 :
Intrinsic<[llvm_v16i8_ty], [llvm_v1i64_ty, llvm_v1i64_ty], [IntrNoMem]>;
class Neon_2Arg_ShiftImm_Intrinsic
: Intrinsic<[llvm_v1i64_ty], [llvm_v1i64_ty, llvm_i32_ty], [IntrNoMem]>;
@ -355,28 +389,20 @@ def int_aarch64_neon_vqshlu_n : Neon_N2V_Intrinsic;
def int_aarch64_neon_vqshlus_n : Neon_N2V_Intrinsic;
// Scalar Signed Fixed-point Convert To Floating-Point (Immediate)
def int_aarch64_neon_vcvtf32_n_s32 :
Intrinsic<[llvm_float_ty], [llvm_v1i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtf64_n_s64 :
Intrinsic<[llvm_double_ty], [llvm_v1i64_ty, llvm_i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtfxs2fp_n :
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty, llvm_i32_ty], [IntrNoMem]>;
// Scalar Unsigned Fixed-point Convert To Floating-Point (Immediate)
def int_aarch64_neon_vcvtf32_n_u32 :
Intrinsic<[llvm_float_ty], [llvm_v1i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtf64_n_u64 :
Intrinsic<[llvm_double_ty], [llvm_v1i64_ty, llvm_i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtfxu2fp_n :
Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty, llvm_i32_ty], [IntrNoMem]>;
// Scalar Floating-point Convert To Signed Fixed-point (Immediate)
def int_aarch64_neon_vcvts_n_s32_f32 :
Intrinsic<[llvm_v1i32_ty], [llvm_v1f32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtd_n_s64_f64 :
Intrinsic<[llvm_v1i64_ty], [llvm_v1f64_ty, llvm_i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtfp2fxs_n :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>;
// Scalar Floating-point Convert To Unsigned Fixed-point (Immediate)
def int_aarch64_neon_vcvts_n_u32_f32 :
Intrinsic<[llvm_v1i32_ty], [llvm_v1f32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtd_n_u64_f64 :
Intrinsic<[llvm_v1i64_ty], [llvm_v1f64_ty, llvm_i32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvtfp2fxu_n :
Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>;
class Neon_SHA_Intrinsic
: Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v1i32_ty, llvm_v4i32_ty],

View File

@ -1544,22 +1544,26 @@ def int_mips_shf_w : GCCBuiltin<"__builtin_msa_shf_w">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sld_b : GCCBuiltin<"__builtin_msa_sld_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sld_h : GCCBuiltin<"__builtin_msa_sld_h">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sld_w : GCCBuiltin<"__builtin_msa_sld_w">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sld_d : GCCBuiltin<"__builtin_msa_sld_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sldi_b : GCCBuiltin<"__builtin_msa_sldi_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_mips_sldi_h : GCCBuiltin<"__builtin_msa_sldi_h">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_mips_sldi_w : GCCBuiltin<"__builtin_msa_sldi_w">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_mips_sldi_d : GCCBuiltin<"__builtin_msa_sldi_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_mips_sll_b : GCCBuiltin<"__builtin_msa_sll_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;

View File

@ -536,6 +536,8 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[], [], []>;
def int_x86_sse2_mfence : GCCBuiltin<"__builtin_ia32_mfence">,
Intrinsic<[], [], []>;
def int_x86_sse2_pause : GCCBuiltin<"__builtin_ia32_pause">,
Intrinsic<[], [], []>;
}
//===----------------------------------------------------------------------===//
@ -2641,37 +2643,30 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Mask instructions
// 16-bit mask
def int_x86_kadd_v16i1 : GCCBuiltin<"__builtin_ia32_kaddw">,
Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
def int_x86_avx512_kand_w : GCCBuiltin<"__builtin_ia32_kandhi">,
Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_kand_v16i1 : GCCBuiltin<"__builtin_ia32_kandw">,
Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
def int_x86_avx512_kandn_w : GCCBuiltin<"__builtin_ia32_kandnhi">,
Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_kandn_v16i1 : GCCBuiltin<"__builtin_ia32_kandnw">,
Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
def int_x86_avx512_knot_w : GCCBuiltin<"__builtin_ia32_knothi">,
Intrinsic<[llvm_i16_ty], [llvm_i16_ty], [IntrNoMem]>;
def int_x86_avx512_kor_w : GCCBuiltin<"__builtin_ia32_korhi">,
Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_knot_v16i1 : GCCBuiltin<"__builtin_ia32_knotw">,
Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty], [IntrNoMem]>;
def int_x86_kor_v16i1 : GCCBuiltin<"__builtin_ia32_korw">,
Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
def int_x86_avx512_kxor_w : GCCBuiltin<"__builtin_ia32_kxorhi">,
Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_kxor_v16i1 : GCCBuiltin<"__builtin_ia32_kxorw">,
Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
def int_x86_avx512_kxnor_w : GCCBuiltin<"__builtin_ia32_kxnorhi">,
Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_kxnor_v16i1 : GCCBuiltin<"__builtin_ia32_kxnorw">,
Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
def int_x86_avx512_kunpck_bw : GCCBuiltin<"__builtin_ia32_kunpckhi">,
Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_mask2int_v16i1 : GCCBuiltin<"__builtin_ia32_mask2intw">,
Intrinsic<[llvm_i32_ty], [llvm_v16i1_ty], [IntrNoMem]>;
def int_x86_int2mask_v16i1 : GCCBuiltin<"__builtin_ia32_int2maskw">,
Intrinsic<[llvm_v16i1_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_x86_kunpck_v16i1 : GCCBuiltin<"__builtin_ia32_kunpckbw">,
Intrinsic<[llvm_v16i1_ty], [llvm_v8i1_ty, llvm_v8i1_ty],
[IntrNoMem]>;
def int_x86_avx512_kortestz : GCCBuiltin<"__builtin_ia32_kortestz">,
def int_x86_avx512_kortestz_w : GCCBuiltin<"__builtin_ia32_kortestzhi">,
Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_avx512_kortestc : GCCBuiltin<"__builtin_ia32_kortestc">,
def int_x86_avx512_kortestc_w : GCCBuiltin<"__builtin_ia32_kortestchi">,
Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
}
@ -2717,10 +2712,42 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Vector convert
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_cvt_ps2dq_512 : GCCBuiltin<"__builtin_ia32_cvtps2dq512">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty], [IntrNoMem]>;
def int_x86_avx512_cvtdq2_ps_512 : GCCBuiltin<"__builtin_ia32_cvtdq2ps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvttps2dq_512: GCCBuiltin<"__builtin_ia32_cvttps2dq512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvttps2udq_512: GCCBuiltin<"__builtin_ia32_cvttps2udq512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvttpd2dq_512: GCCBuiltin<"__builtin_ia32_cvttpd2dq512_mask">,
Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvttpd2udq_512: GCCBuiltin<"__builtin_ia32_cvttpd2udq512_mask">,
Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_rndscale_ps_512: GCCBuiltin<"__builtin_ia32_rndscaleps_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty,
llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_rndscale_pd_512: GCCBuiltin<"__builtin_ia32_rndscalepd_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvtps2dq_512: GCCBuiltin<"__builtin_ia32_cvtps2dq512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvtpd2dq_512: GCCBuiltin<"__builtin_ia32_cvtpd2dq512_mask">,
Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvtps2udq_512: GCCBuiltin<"__builtin_ia32_cvtps2udq512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvtpd2udq_512: GCCBuiltin<"__builtin_ia32_cvtpd2udq512_mask">,
Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvtdq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtdq2ps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty,
llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cvtdq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtdq2pd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_v8f64_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
}
// Vector load with broadcast
@ -2825,13 +2852,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
def int_x86_avx512_rndscale_ps_512 : GCCBuiltin<"__builtin_ia32_rndscaleps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty,
llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_rndscale_pd_512 : GCCBuiltin<"__builtin_ia32_rndscalepd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty,
llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty], [IntrNoMem]>;
def int_x86_avx512_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512">,
@ -3045,49 +3065,34 @@ let TargetPrefix = "x86" in {
// AVX-512 conflict detection
let TargetPrefix = "x86" in {
def int_x86_avx512_conflict_d_512 : GCCBuiltin<"__builtin_ia32_conflictd512">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty],
[]>;
def int_x86_avx512_conflict_d_mask_512 :
GCCBuiltin<"__builtin_ia32_mask_conflictd512">,
def int_x86_avx512_mask_conflict_d_512 :
GCCBuiltin<"__builtin_ia32_vpconflictsi_512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
llvm_v16i1_ty, llvm_v16i32_ty],
llvm_v16i32_ty, llvm_i16_ty],
[]>;
def int_x86_avx512_conflict_d_maskz_512:
GCCBuiltin<"__builtin_ia32_maskz_conflictd512">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i1_ty, llvm_v16i32_ty],
[]>;
def int_x86_avx512_conflict_q_512 : GCCBuiltin<"__builtin_ia32_conflictq512">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty],
[]>;
def int_x86_avx512_conflict_q_mask_512 :
GCCBuiltin<"__builtin_ia32_mask_conflictq512">,
def int_x86_avx512_mask_conflict_q_512 :
GCCBuiltin<"__builtin_ia32_vpconflictdi_512_mask">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
llvm_v8i1_ty, llvm_v8i64_ty],
[]>;
def int_x86_avx512_conflict_q_maskz_512:
GCCBuiltin<"__builtin_ia32_maskz_conflictq512">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i1_ty, llvm_v8i64_ty],
llvm_v8i64_ty, llvm_i8_ty],
[]>;
}
// Vector blend
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mskblend_ps_512 : GCCBuiltin<"__builtin_ia32_mskblendps512">,
def int_x86_avx512_mask_blend_ps_512 : GCCBuiltin<"__builtin_ia32_mask_blendps512">,
Intrinsic<[llvm_v16f32_ty],
[llvm_v16i1_ty, llvm_v16f32_ty, llvm_v16f32_ty],
[IntrNoMem]>;
def int_x86_avx512_mskblend_pd_512 : GCCBuiltin<"__builtin_ia32_mskblendpd512">,
def int_x86_avx512_mask_blend_pd_512 : GCCBuiltin<"__builtin_ia32_mask_blendpd512">,
Intrinsic<[llvm_v8f64_ty],
[llvm_v8i1_ty, llvm_v8f64_ty, llvm_v8f64_ty],
[IntrNoMem]>;
def int_x86_avx512_mskblend_d_512 : GCCBuiltin<"__builtin_ia32_mskblendd512">,
def int_x86_avx512_mask_blend_d_512 : GCCBuiltin<"__builtin_ia32_mask_blendd512">,
Intrinsic<[llvm_v16i32_ty],
[llvm_v16i1_ty, llvm_v16i32_ty, llvm_v16i32_ty],
[IntrNoMem]>;
def int_x86_avx512_mskblend_q_512 : GCCBuiltin<"__builtin_ia32_mskblendq512">,
def int_x86_avx512_mask_blend_q_512 : GCCBuiltin<"__builtin_ia32_mask_blendq512">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8i64_ty],
[IntrNoMem]>;
@ -3095,12 +3100,27 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Misc.
let TargetPrefix = "x86" in {
def int_x86_avx512_cmpeq_pi_512 : GCCBuiltin<"__builtin_ia32_cmpeqpi512">,
Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty],
def int_x86_avx512_mask_cmp_ps_512 : GCCBuiltin<"__builtin_ia32_cmpps512_mask">,
Intrinsic<[llvm_i16_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty,
llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_cmp_pd_512 : GCCBuiltin<"__builtin_ia32_cmppd512_mask">,
Intrinsic<[llvm_i8_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_mask_pcmpeq_d_512 : GCCBuiltin<"__builtin_ia32_pcmpeqd512_mask">,
Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_avx512_mask_pcmpeq_q_512 : GCCBuiltin<"__builtin_ia32_pcmpeqq512_mask">,
Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty],
[IntrNoMem]>;
def int_x86_avx512_mask_pand_d_512 : GCCBuiltin<"__builtin_ia32_pandd512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
llvm_v16i32_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_x86_avx512_mask_pand_q_512 : GCCBuiltin<"__builtin_ia32_pandq512_mask">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
llvm_v8i64_ty, llvm_i8_ty],
[IntrNoMem]>;
def int_x86_avx512_and_pi : GCCBuiltin<"__builtin_ia32_andpi512">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty],
[IntrNoMem]>;
}
//===----------------------------------------------------------------------===//

View File

@ -27,6 +27,7 @@ class Twine;
class Instruction;
class Module;
class SMDiagnostic;
class DiagnosticInfo;
template <typename T> class SmallVectorImpl;
/// This is an important class for using LLVM in a threaded context. It
@ -64,6 +65,11 @@ public:
typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
unsigned LocCookie);
/// Defines the type of a diagnostic handler.
/// \see LLVMContext::setDiagnosticHandler.
/// \see LLVMContext::diagnose.
typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context);
/// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
/// when problems with inline asm are detected by the backend. The first
/// argument is a function pointer and the second is a context pointer that
@ -82,6 +88,33 @@ public:
/// setInlineAsmDiagnosticHandler.
void *getInlineAsmDiagnosticContext() const;
/// setDiagnosticHandler - This method sets a handler that is invoked
/// when the backend needs to report anything to the user. The first
/// argument is a function pointer and the second is a context pointer that
/// gets passed into the DiagHandler.
///
/// LLVMContext doesn't take ownership or interpret either of these
/// pointers.
void setDiagnosticHandler(DiagnosticHandlerTy DiagHandler,
void *DiagContext = 0);
/// getDiagnosticHandler - Return the diagnostic handler set by
/// setDiagnosticHandler.
DiagnosticHandlerTy getDiagnosticHandler() const;
/// getDiagnosticContext - Return the diagnostic context set by
/// setDiagnosticContext.
void *getDiagnosticContext() const;
/// diagnose - Report a message to the currently installed diagnostic handler.
/// This function returns, in particular in the case of error reporting
/// (DI.Severity == RS_Error), so the caller should leave the compilation
/// process in a self-consistent state, even though the generated code
/// need not be correct.
/// The diagnostic message will be implicitly prefixed with a severity
/// keyword according to \p DI.getSeverity(), i.e., "error: "
/// for RS_Error, "warning: " for RS_Warning, and "note: " for RS_Note.
void diagnose(const DiagnosticInfo &DI);
/// emitError - Emit an error message to the currently installed error handler
/// with optional location information. This function returns, so code should

View File

@ -101,15 +101,15 @@ namespace llvm {
// enums for debugging strings
enum PassDebuggingString {
EXECUTION_MSG, // "Executing Pass '"
MODIFICATION_MSG, // "' Made Modification '"
FREEING_MSG, // " Freeing Pass '"
ON_BASICBLOCK_MSG, // "' on BasicBlock '" + PassName + "'...\n"
EXECUTION_MSG, // "Executing Pass '" + PassName
MODIFICATION_MSG, // "Made Modification '" + PassName
FREEING_MSG, // " Freeing Pass '" + PassName
ON_BASICBLOCK_MSG, // "' on BasicBlock '" + InstructionName + "'...\n"
ON_FUNCTION_MSG, // "' on Function '" + FunctionName + "'...\n"
ON_MODULE_MSG, // "' on Module '" + ModuleName + "'...\n"
ON_REGION_MSG, // " 'on Region ...\n'"
ON_LOOP_MSG, // " 'on Loop ...\n'"
ON_CG_MSG // "' on Call Graph ...\n'"
ON_REGION_MSG, // "' on Region '" + Msg + "'...\n'"
ON_LOOP_MSG, // "' on Loop '" + Msg + "'...\n'"
ON_CG_MSG // "' on Call Graph Nodes '" + Msg + "'...\n'"
};
/// PassManagerPrettyStackEntry - This is used to print informative information

View File

@ -28,6 +28,10 @@ template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
DEBUG_METADATA_VERSION = 1 // Current debug info version number.
};
//===----------------------------------------------------------------------===//
/// MDString - a single uniqued string.
/// These are used to efficiently contain a byte sequence for metadata.

View File

@ -143,10 +143,10 @@ public:
typedef NamedMDListType::const_iterator const_named_metadata_iterator;
/// An enumeration for describing the endianess of the target machine.
enum Endianness { AnyEndianness, LittleEndian, BigEndian };
enum Endianness { LittleEndian, BigEndian };
/// An enumeration for describing the size of a pointer on the target machine.
enum PointerSize { AnyPointerSize, Pointer32, Pointer64 };
enum PointerSize { Pointer32, Pointer64 };
/// This enumeration defines the supported behaviors of module flags.
enum ModFlagBehavior {

View File

@ -36,6 +36,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/polymorphic_ptr.h"
#include "llvm/Support/type_traits.h"
#include "llvm/IR/Function.h"
@ -48,317 +49,595 @@ namespace llvm {
class Module;
class Function;
/// \brief An abstract set of preserved analyses following a transformation pass
/// run.
///
/// When a transformation pass is run, it can return a set of analyses whose
/// results were preserved by that transformation. The default set is "none",
/// and preserving analyses must be done explicitly.
///
/// There is also an explicit all state which can be used (for example) when
/// the IR is not mutated at all.
class PreservedAnalyses {
public:
/// \brief Convenience factory function for the empty preserved set.
static PreservedAnalyses none() { return PreservedAnalyses(); }
/// \brief Construct a special preserved set that preserves all passes.
static PreservedAnalyses all() {
PreservedAnalyses PA;
PA.PreservedPassIDs.insert((void *)AllPassesID);
return PA;
}
PreservedAnalyses &operator=(PreservedAnalyses Arg) {
swap(Arg);
return *this;
}
void swap(PreservedAnalyses &Arg) {
PreservedPassIDs.swap(Arg.PreservedPassIDs);
}
/// \brief Mark a particular pass as preserved, adding it to the set.
template <typename PassT> void preserve() {
if (!areAllPreserved())
PreservedPassIDs.insert(PassT::ID());
}
/// \brief Intersect this set with another in place.
///
/// This is a mutating operation on this preserved set, removing all
/// preserved passes which are not also preserved in the argument.
void intersect(const PreservedAnalyses &Arg) {
if (Arg.areAllPreserved())
return;
if (areAllPreserved()) {
PreservedPassIDs = Arg.PreservedPassIDs;
return;
}
for (SmallPtrSet<void *, 2>::const_iterator I = PreservedPassIDs.begin(),
E = PreservedPassIDs.end();
I != E; ++I)
if (!Arg.PreservedPassIDs.count(*I))
PreservedPassIDs.erase(*I);
}
#if LLVM_HAS_RVALUE_REFERENCES
/// \brief Intersect this set with a temporary other set in place.
///
/// This is a mutating operation on this preserved set, removing all
/// preserved passes which are not also preserved in the argument.
void intersect(PreservedAnalyses &&Arg) {
if (Arg.areAllPreserved())
return;
if (areAllPreserved()) {
PreservedPassIDs = std::move(Arg.PreservedPassIDs);
return;
}
for (SmallPtrSet<void *, 2>::const_iterator I = PreservedPassIDs.begin(),
E = PreservedPassIDs.end();
I != E; ++I)
if (!Arg.PreservedPassIDs.count(*I))
PreservedPassIDs.erase(*I);
}
#endif
/// \brief Query whether a pass is marked as preserved by this set.
template <typename PassT> bool preserved() const {
return preserved(PassT::ID());
}
/// \brief Query whether an abstract pass ID is marked as preserved by this
/// set.
bool preserved(void *PassID) const {
return PreservedPassIDs.count((void *)AllPassesID) ||
PreservedPassIDs.count(PassID);
}
private:
// Note that this must not be -1 or -2 as those are already used by the
// SmallPtrSet.
static const uintptr_t AllPassesID = (intptr_t)-3;
bool areAllPreserved() const { return PreservedPassIDs.count((void *)AllPassesID); }
SmallPtrSet<void *, 2> PreservedPassIDs;
};
inline void swap(PreservedAnalyses &LHS, PreservedAnalyses &RHS) {
LHS.swap(RHS);
}
/// \brief Implementation details of the pass manager interfaces.
namespace detail {
/// \brief Template for the abstract base class used to dispatch
/// polymorphically over pass objects.
template <typename T> struct PassConcept {
template <typename IRUnitT, typename AnalysisManagerT> struct PassConcept {
// Boiler plate necessary for the container of derived classes.
virtual ~PassConcept() {}
virtual PassConcept *clone() = 0;
/// \brief The polymorphic API which runs the pass over a given IR entity.
virtual bool run(T Arg) = 0;
///
/// Note that actual pass object can omit the analysis manager argument if
/// desired. Also that the analysis manager may be null if there is no
/// analysis manager in the pass pipeline.
virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) = 0;
};
/// \brief SFINAE metafunction for computing whether \c PassT has a run method
/// accepting an \c AnalysisManagerT.
template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
typename ResultT>
class PassRunAcceptsAnalysisManager {
typedef char SmallType;
struct BigType { char a, b; };
template <typename T, ResultT (T::*)(IRUnitT, AnalysisManagerT *)>
struct Checker;
template <typename T> static SmallType f(Checker<T, &T::run> *);
template <typename T> static BigType f(...);
public:
enum { Value = sizeof(f<PassT>(0)) == sizeof(SmallType) };
};
/// \brief A template wrapper used to implement the polymorphic API.
///
/// Can be instantiated for any object which provides a \c run method
/// accepting a \c T. It requires the pass to be a copyable
/// object.
template <typename T, typename PassT> struct PassModel : PassConcept<T> {
/// Can be instantiated for any object which provides a \c run method accepting
/// an \c IRUnitT. It requires the pass to be a copyable object. When the
/// \c run method also accepts an \c AnalysisManagerT*, we pass it along.
template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
IRUnitT, AnalysisManagerT, PassT, PreservedAnalyses>::Value>
struct PassModel;
/// \brief Specialization of \c PassModel for passes that accept an analyis
/// manager.
template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
struct PassModel<IRUnitT, AnalysisManagerT, PassT,
true> : PassConcept<IRUnitT, AnalysisManagerT> {
PassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
virtual PassModel *clone() { return new PassModel(Pass); }
virtual bool run(T Arg) { return Pass.run(Arg); }
virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) {
return Pass.run(IR, AM);
}
PassT Pass;
};
/// \brief Specialization of \c PassModel for passes that accept an analyis
/// manager.
template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
struct PassModel<IRUnitT, AnalysisManagerT, PassT,
false> : PassConcept<IRUnitT, AnalysisManagerT> {
PassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
virtual PassModel *clone() { return new PassModel(Pass); }
virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) {
return Pass.run(IR);
}
PassT Pass;
};
/// \brief Abstract concept of an analysis result.
///
/// This concept is parameterized over the IR unit that this result pertains
/// to.
template <typename IRUnitT> struct AnalysisResultConcept {
virtual ~AnalysisResultConcept() {}
virtual AnalysisResultConcept *clone() = 0;
/// \brief Method to try and mark a result as invalid.
///
/// When the outer analysis manager detects a change in some underlying
/// unit of the IR, it will call this method on all of the results cached.
///
/// This method also receives a set of preserved analyses which can be used
/// to avoid invalidation because the pass which changed the underlying IR
/// took care to update or preserve the analysis result in some way.
///
/// \returns true if the result is indeed invalid (the default).
virtual bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) = 0;
};
/// \brief SFINAE metafunction for computing whether \c ResultT provides an
/// \c invalidate member function.
template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
typedef char SmallType;
struct BigType { char a, b; };
template <typename T, bool (T::*)(IRUnitT, const PreservedAnalyses &)>
struct Checker;
template <typename T> static SmallType f(Checker<T, &T::invalidate> *);
template <typename T> static BigType f(...);
public:
enum { Value = sizeof(f<ResultT>(0)) == sizeof(SmallType) };
};
/// \brief Wrapper to model the analysis result concept.
///
/// By default, this will implement the invalidate method with a trivial
/// implementation so that the actual analysis result doesn't need to provide
/// an invalidation handler. It is only selected when the invalidation handler
/// is not part of the ResultT's interface.
template <typename IRUnitT, typename PassT, typename ResultT,
bool HasInvalidateHandler =
ResultHasInvalidateMethod<IRUnitT, ResultT>::Value>
struct AnalysisResultModel;
/// \brief Specialization of \c AnalysisResultModel which provides the default
/// invalidate functionality.
template <typename IRUnitT, typename PassT, typename ResultT>
struct AnalysisResultModel<IRUnitT, PassT, ResultT,
false> : AnalysisResultConcept<IRUnitT> {
AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {}
virtual AnalysisResultModel *clone() {
return new AnalysisResultModel(Result);
}
/// \brief The model bases invalidation solely on being in the preserved set.
//
// FIXME: We should actually use two different concepts for analysis results
// rather than two different models, and avoid the indirect function call for
// ones that use the trivial behavior.
virtual bool invalidate(IRUnitT, const PreservedAnalyses &PA) {
return !PA.preserved(PassT::ID());
}
ResultT Result;
};
/// \brief Specialization of \c AnalysisResultModel which delegates invalidate
/// handling to \c ResultT.
template <typename IRUnitT, typename PassT, typename ResultT>
struct AnalysisResultModel<IRUnitT, PassT, ResultT,
true> : AnalysisResultConcept<IRUnitT> {
AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {}
virtual AnalysisResultModel *clone() {
return new AnalysisResultModel(Result);
}
/// \brief The model delegates to the \c ResultT method.
virtual bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) {
return Result.invalidate(IR, PA);
}
ResultT Result;
};
/// \brief Abstract concept of an analysis pass.
///
/// This concept is parameterized over the IR unit that it can run over and
/// produce an analysis result.
template <typename IRUnitT, typename AnalysisManagerT>
struct AnalysisPassConcept {
virtual ~AnalysisPassConcept() {}
virtual AnalysisPassConcept *clone() = 0;
/// \brief Method to run this analysis over a unit of IR.
/// \returns The analysis result object to be queried by users, the caller
/// takes ownership.
virtual AnalysisResultConcept<IRUnitT> *run(IRUnitT IR,
AnalysisManagerT *AM) = 0;
};
/// \brief Wrapper to model the analysis pass concept.
///
/// Can wrap any type which implements a suitable \c run method. The method
/// must accept the IRUnitT as an argument and produce an object which can be
/// wrapped in a \c AnalysisResultModel.
template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
IRUnitT, AnalysisManagerT, PassT,
typename PassT::Result>::Value> struct AnalysisPassModel;
/// \brief Specialization of \c AnalysisPassModel which passes an
/// \c AnalysisManager to PassT's run method.
template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT,
true> : AnalysisPassConcept<IRUnitT,
AnalysisManagerT> {
AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); }
// FIXME: Replace PassT::Result with type traits when we use C++11.
typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
ResultModelT;
/// \brief The model delegates to the \c PassT::run method.
///
/// The return is wrapped in an \c AnalysisResultModel.
virtual ResultModelT *run(IRUnitT IR, AnalysisManagerT *AM) {
return new ResultModelT(Pass.run(IR, AM));
}
PassT Pass;
};
/// \brief Specialization of \c AnalysisPassModel which does not pass an
/// \c AnalysisManager to PassT's run method.
template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT,
false> : AnalysisPassConcept<IRUnitT,
AnalysisManagerT> {
AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); }
// FIXME: Replace PassT::Result with type traits when we use C++11.
typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
ResultModelT;
/// \brief The model delegates to the \c PassT::run method.
///
/// The return is wrapped in an \c AnalysisResultModel.
virtual ResultModelT *run(IRUnitT IR, AnalysisManagerT *) {
return new ResultModelT(Pass.run(IR));
}
PassT Pass;
};
}
class AnalysisManager;
class ModuleAnalysisManager;
class ModulePassManager {
public:
ModulePassManager(Module *M, AnalysisManager *AM = 0) : M(M), AM(AM) {}
explicit ModulePassManager() {}
/// \brief Run all of the module passes in this module pass manager over
/// a module.
///
/// This method should only be called for a single module as there is the
/// expectation that the lifetime of a pass is bounded to that of a module.
PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM = 0);
template <typename ModulePassT> void addPass(ModulePassT Pass) {
Passes.push_back(new ModulePassModel<ModulePassT>(llvm_move(Pass)));
}
void run();
private:
// Pull in the concept type and model template specialized for modules.
typedef detail::PassConcept<Module *> ModulePassConcept;
typedef detail::PassConcept<Module *, ModuleAnalysisManager> ModulePassConcept;
template <typename PassT>
struct ModulePassModel : detail::PassModel<Module *, PassT> {
ModulePassModel(PassT Pass) : detail::PassModel<Module *, PassT>(Pass) {}
struct ModulePassModel
: detail::PassModel<Module *, ModuleAnalysisManager, PassT> {
ModulePassModel(PassT Pass)
: detail::PassModel<Module *, ModuleAnalysisManager, PassT>(Pass) {}
};
Module *M;
AnalysisManager *AM;
std::vector<polymorphic_ptr<ModulePassConcept> > Passes;
};
class FunctionAnalysisManager;
class FunctionPassManager {
public:
FunctionPassManager(AnalysisManager *AM = 0) : AM(AM) {}
explicit FunctionPassManager() {}
template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
Passes.push_back(new FunctionPassModel<FunctionPassT>(llvm_move(Pass)));
}
bool run(Module *M);
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = 0);
private:
// Pull in the concept type and model template specialized for functions.
typedef detail::PassConcept<Function *> FunctionPassConcept;
typedef detail::PassConcept<Function *, FunctionAnalysisManager>
FunctionPassConcept;
template <typename PassT>
struct FunctionPassModel : detail::PassModel<Function *, PassT> {
struct FunctionPassModel
: detail::PassModel<Function *, FunctionAnalysisManager, PassT> {
FunctionPassModel(PassT Pass)
: detail::PassModel<Function *, PassT>(Pass) {}
: detail::PassModel<Function *, FunctionAnalysisManager, PassT>(Pass) {}
};
AnalysisManager *AM;
std::vector<polymorphic_ptr<FunctionPassConcept> > Passes;
};
namespace detail {
/// \brief An analysis manager to coordinate and cache analyses run over
/// a module.
/// \brief A CRTP base used to implement analysis managers.
///
/// The analysis manager is typically used by passes in a pass pipeline
/// (consisting potentially of several individual pass managers) over a module
/// of IR. It provides registration of available analyses, declaring
/// requirements on support for specific analyses, running of an specific
/// analysis over a specific unit of IR to compute an analysis result, and
/// caching of the analysis results to reuse them across multiple passes.
/// This class template serves as the boiler plate of an analysis manager. Any
/// analysis manager can be implemented on top of this base class. Any
/// implementation will be required to provide specific hooks:
///
/// It is the responsibility of callers to use the invalidation API to
/// invalidate analysis results when the IR they correspond to changes. The
/// \c ModulePassManager and \c FunctionPassManager do this automatically.
class AnalysisManager {
/// - getResultImpl
/// - getCachedResultImpl
/// - invalidateImpl
///
/// The details of the call pattern are within.
template <typename DerivedT, typename IRUnitT>
class AnalysisManagerBase {
DerivedT *derived_this() { return static_cast<DerivedT *>(this); }
const DerivedT *derived_this() const { return static_cast<const DerivedT *>(this); }
protected:
typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
typedef detail::AnalysisPassConcept<IRUnitT, DerivedT> PassConceptT;
// FIXME: Provide template aliases for the models when we're using C++11 in
// a mode supporting them.
public:
AnalysisManager(Module *M) : M(M) {}
/// \brief Get the result of an analysis pass for this module.
///
/// If there is not a valid cached result in the manager already, this will
/// re-run the analysis to produce a valid result.
///
/// The module passed in must be the same module as the analysis manager was
/// constructed around.
template <typename PassT>
const typename PassT::Result &getResult(Module *M) {
assert(ModuleAnalysisPasses.count(PassT::ID()) &&
template <typename PassT> const typename PassT::Result &getResult(IRUnitT IR) {
assert(AnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being queried");
const AnalysisResultConcept<Module> &ResultConcept =
getResultImpl(PassT::ID(), M);
typedef AnalysisResultModel<Module, typename PassT::Result> ResultModelT;
const ResultConceptT &ResultConcept =
derived_this()->getResultImpl(PassT::ID(), IR);
typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
ResultModelT;
return static_cast<const ResultModelT &>(ResultConcept).Result;
}
/// \brief Get the result of an analysis pass for a function.
/// \brief Get the cached result of an analysis pass for this module.
///
/// If there is not a valid cached result in the manager already, this will
/// re-run the analysis to produce a valid result.
/// This method never runs the analysis.
///
/// \returns null if there is no cached result.
template <typename PassT>
const typename PassT::Result &getResult(Function *F) {
assert(FunctionAnalysisPasses.count(PassT::ID()) &&
const typename PassT::Result *getCachedResult(IRUnitT IR) const {
assert(AnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being queried");
const AnalysisResultConcept<Function> &ResultConcept =
getResultImpl(PassT::ID(), F);
typedef AnalysisResultModel<Function, typename PassT::Result> ResultModelT;
return static_cast<const ResultModelT &>(ResultConcept).Result;
const ResultConceptT *ResultConcept =
derived_this()->getCachedResultImpl(PassT::ID(), IR);
if (!ResultConcept)
return 0;
typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
ResultModelT;
return &static_cast<const ResultModelT *>(ResultConcept)->Result;
}
/// \brief Register an analysis pass with the manager.
///
/// This provides an initialized and set-up analysis pass to the
/// analysis
/// manager. Whomever is setting up analysis passes must use this to
/// populate
/// This provides an initialized and set-up analysis pass to the analysis
/// manager. Whomever is setting up analysis passes must use this to populate
/// the manager with all of the analysis passes available.
template <typename PassT> void registerAnalysisPass(PassT Pass) {
registerAnalysisPassImpl<PassT>(llvm_move(Pass));
template <typename PassT> void registerPass(PassT Pass) {
assert(!AnalysisPasses.count(PassT::ID()) &&
"Registered the same analysis pass twice!");
typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
AnalysisPasses[PassT::ID()] = new PassModelT(llvm_move(Pass));
}
/// \brief Invalidate a specific analysis pass for an IR module.
///
/// Note that the analysis result can disregard invalidation.
template <typename PassT> void invalidate(Module *M) {
invalidateImpl(PassT::ID(), M);
assert(AnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being invalidated");
derived_this()->invalidateImpl(PassT::ID(), M);
}
/// \brief Invalidate a specific analysis pass for an IR function.
/// \brief Invalidate analyses cached for an IR unit.
///
/// Note that the analysis result can disregard invalidation.
template <typename PassT> void invalidate(Function *F) {
invalidateImpl(PassT::ID(), F);
/// Walk through all of the analyses pertaining to this unit of IR and
/// invalidate them unless they are preserved by the PreservedAnalyses set.
void invalidate(IRUnitT IR, const PreservedAnalyses &PA) {
derived_this()->invalidateImpl(IR, PA);
}
/// \brief Invalidate analyses cached for an IR Module.
///
/// Note that specific analysis results can disregard invalidation by
/// overriding their invalidate method.
///
/// The module must be the module this analysis manager was constructed
/// around.
void invalidateAll(Module *M);
protected:
/// \brief Lookup a registered analysis pass.
PassConceptT &lookupPass(void *PassID) {
typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(PassID);
assert(PI != AnalysisPasses.end() &&
"Analysis passes must be registered prior to being queried!");
return *PI->second;
}
/// \brief Invalidate analyses cached for an IR Function.
///
/// Note that specific analysis results can disregard invalidation by
/// overriding the invalidate method.
void invalidateAll(Function *F);
/// \brief Lookup a registered analysis pass.
const PassConceptT &lookupPass(void *PassID) const {
typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(PassID);
assert(PI != AnalysisPasses.end() &&
"Analysis passes must be registered prior to being queried!");
return *PI->second;
}
private:
/// \brief Abstract concept of an analysis result.
///
/// This concept is parameterized over the IR unit that this result pertains
/// to.
template <typename IRUnitT> struct AnalysisResultConcept {
virtual ~AnalysisResultConcept() {}
virtual AnalysisResultConcept *clone() = 0;
/// \brief Map type from module analysis pass ID to pass concept pointer.
typedef DenseMap<void *, polymorphic_ptr<PassConceptT> > AnalysisPassMapT;
/// \brief Method to try and mark a result as invalid.
///
/// When the outer \c AnalysisManager detects a change in some underlying
/// unit of the IR, it will call this method on all of the results cached.
///
/// \returns true if the result should indeed be invalidated (the default).
virtual bool invalidate(IRUnitT *IR) = 0;
};
/// \brief Collection of module analysis passes, indexed by ID.
AnalysisPassMapT AnalysisPasses;
};
/// \brief Wrapper to model the analysis result concept.
///
/// Can wrap any type which implements a suitable invalidate member and model
/// the AnalysisResultConcept for the AnalysisManager.
template <typename IRUnitT, typename ResultT>
struct AnalysisResultModel : AnalysisResultConcept<IRUnitT> {
AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {}
virtual AnalysisResultModel *clone() {
return new AnalysisResultModel(Result);
}
}
/// \brief The model delegates to the \c ResultT method.
virtual bool invalidate(IRUnitT *IR) { return Result.invalidate(IR); }
ResultT Result;
};
/// \brief Abstract concept of an analysis pass.
///
/// This concept is parameterized over the IR unit that it can run over and
/// produce an analysis result.
template <typename IRUnitT> struct AnalysisPassConcept {
virtual ~AnalysisPassConcept() {}
virtual AnalysisPassConcept *clone() = 0;
/// \brief Method to run this analysis over a unit of IR.
/// \returns The analysis result object to be queried by users, the caller
/// takes ownership.
virtual AnalysisResultConcept<IRUnitT> *run(IRUnitT *IR) = 0;
};
/// \brief Wrapper to model the analysis pass concept.
///
/// Can wrap any type which implements a suitable \c run method. The method
/// must accept the IRUnitT as an argument and produce an object which can be
/// wrapped in a \c AnalysisResultModel.
template <typename PassT>
struct AnalysisPassModel : AnalysisPassConcept<typename PassT::IRUnitT> {
AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); }
// FIXME: Replace PassT::IRUnitT with type traits when we use C++11.
typedef typename PassT::IRUnitT IRUnitT;
// FIXME: Replace PassT::Result with type traits when we use C++11.
typedef AnalysisResultModel<IRUnitT, typename PassT::Result> ResultModelT;
/// \brief The model delegates to the \c PassT::run method.
///
/// The return is wrapped in an \c AnalysisResultModel.
virtual ResultModelT *run(IRUnitT *IR) {
return new ResultModelT(Pass.run(IR));
}
PassT Pass;
};
/// \brief A module analysis pass manager with lazy running and caching of
/// results.
class ModuleAnalysisManager
: public detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> {
friend class detail::AnalysisManagerBase<ModuleAnalysisManager, Module *>;
typedef detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> BaseT;
typedef BaseT::ResultConceptT ResultConceptT;
typedef BaseT::PassConceptT PassConceptT;
public:
// Public methods provided by the base class.
private:
/// \brief Get a module pass result, running the pass if necessary.
const AnalysisResultConcept<Module> &getResultImpl(void *PassID, Module *M);
const ResultConceptT &getResultImpl(void *PassID, Module *M);
/// \brief Get a function pass result, running the pass if necessary.
const AnalysisResultConcept<Function> &getResultImpl(void *PassID,
Function *F);
/// \brief Get a cached module pass result or return null.
const ResultConceptT *getCachedResultImpl(void *PassID, Module *M) const;
/// \brief Invalidate a module pass result.
void invalidateImpl(void *PassID, Module *M);
/// \brief Invalidate a function pass result.
void invalidateImpl(void *PassID, Function *F);
/// \brief Module pass specific implementation of registration.
template <typename PassT>
typename enable_if<is_same<typename PassT::IRUnitT, Module> >::type
registerAnalysisPassImpl(PassT Pass) {
assert(!ModuleAnalysisPasses.count(PassT::ID()) &&
"Registered the same analysis pass twice!");
ModuleAnalysisPasses[PassT::ID()] =
new AnalysisPassModel<PassT>(llvm_move(Pass));
}
/// \brief Function pass specific implementation of registration.
template <typename PassT>
typename enable_if<is_same<typename PassT::IRUnitT, Function> >::type
registerAnalysisPassImpl(PassT Pass) {
assert(!FunctionAnalysisPasses.count(PassT::ID()) &&
"Registered the same analysis pass twice!");
FunctionAnalysisPasses[PassT::ID()] =
new AnalysisPassModel<PassT>(llvm_move(Pass));
}
/// \brief Map type from module analysis pass ID to pass concept pointer.
typedef DenseMap<void *, polymorphic_ptr<AnalysisPassConcept<Module> > >
ModuleAnalysisPassMapT;
/// \brief Collection of module analysis passes, indexed by ID.
ModuleAnalysisPassMapT ModuleAnalysisPasses;
/// \brief Invalidate results across a module.
void invalidateImpl(Module *M, const PreservedAnalyses &PA);
/// \brief Map type from module analysis pass ID to pass result concept pointer.
typedef DenseMap<void *, polymorphic_ptr<AnalysisResultConcept<Module> > >
ModuleAnalysisResultMapT;
typedef DenseMap<void *,
polymorphic_ptr<detail::AnalysisResultConcept<Module *> > >
ModuleAnalysisResultMapT;
/// \brief Cache of computed module analysis results for this module.
ModuleAnalysisResultMapT ModuleAnalysisResults;
};
/// \brief A function analysis manager to coordinate and cache analyses run over
/// a module.
class FunctionAnalysisManager
: public detail::AnalysisManagerBase<FunctionAnalysisManager, Function *> {
friend class detail::AnalysisManagerBase<FunctionAnalysisManager, Function *>;
typedef detail::AnalysisManagerBase<FunctionAnalysisManager, Function *> BaseT;
typedef BaseT::ResultConceptT ResultConceptT;
typedef BaseT::PassConceptT PassConceptT;
/// \brief Map type from function analysis pass ID to pass concept pointer.
typedef DenseMap<void *, polymorphic_ptr<AnalysisPassConcept<Function> > >
FunctionAnalysisPassMapT;
public:
// Most public APIs are inherited from the CRTP base class.
/// \brief Collection of function analysis passes, indexed by ID.
FunctionAnalysisPassMapT FunctionAnalysisPasses;
/// \brief Returns true if the analysis manager has an empty results cache.
bool empty() const;
/// \brief Clear the function analysis result cache.
///
/// This routine allows cleaning up when the set of functions itself has
/// potentially changed, and thus we can't even look up a a result and
/// invalidate it directly. Notably, this does *not* call invalidate
/// functions as there is nothing to be done for them.
void clear();
private:
/// \brief Get a function pass result, running the pass if necessary.
const ResultConceptT &getResultImpl(void *PassID, Function *F);
/// \brief Get a cached function pass result or return null.
const ResultConceptT *getCachedResultImpl(void *PassID, Function *F) const;
/// \brief Invalidate a function pass result.
void invalidateImpl(void *PassID, Function *F);
/// \brief Invalidate the results for a function..
void invalidateImpl(Function *F, const PreservedAnalyses &PA);
/// \brief List of function analysis pass IDs and associated concept pointers.
///
/// Requires iterators to be valid across appending new entries and arbitrary
/// erases. Provides both the pass ID and concept pointer such that it is
/// half of a bijection and provides storage for the actual result concept.
typedef std::list<
std::pair<void *, polymorphic_ptr<AnalysisResultConcept<Function> > > >
FunctionAnalysisResultListT;
typedef std::list<std::pair<
void *, polymorphic_ptr<detail::AnalysisResultConcept<Function *> > > >
FunctionAnalysisResultListT;
/// \brief Map type from function pointer to our custom list type.
typedef DenseMap<Function *, FunctionAnalysisResultListT> FunctionAnalysisResultListMapT;
typedef DenseMap<Function *, FunctionAnalysisResultListT>
FunctionAnalysisResultListMapT;
/// \brief Map from function to a list of function analysis results.
///
@ -370,14 +649,172 @@ private:
/// iterator into a particular result list.
typedef DenseMap<std::pair<void *, Function *>,
FunctionAnalysisResultListT::iterator>
FunctionAnalysisResultMapT;
FunctionAnalysisResultMapT;
/// \brief Map from an analysis ID and function to a particular cached
/// analysis result.
FunctionAnalysisResultMapT FunctionAnalysisResults;
/// \brief Module handle for the \c AnalysisManager.
Module *M;
};
/// \brief A module analysis which acts as a proxy for a function analysis
/// manager.
///
/// This primarily proxies invalidation information from the module analysis
/// manager and module pass manager to a function analysis manager. You should
/// never use a function analysis manager from within (transitively) a module
/// pass manager unless your parent module pass has received a proxy result
/// object for it.
class FunctionAnalysisManagerModuleProxy {
public:
class Result;
static void *ID() { return (void *)&PassID; }
FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM) : FAM(FAM) {}
/// \brief Run the analysis pass and create our proxy result object.
///
/// This doesn't do any interesting work, it is primarily used to insert our
/// proxy result object into the module analysis cache so that we can proxy
/// invalidation to the function analysis manager.
///
/// In debug builds, it will also assert that the analysis manager is empty
/// as no queries should arrive at the function analysis manager prior to
/// this analysis being requested.
Result run(Module *M);
private:
static char PassID;
FunctionAnalysisManager &FAM;
};
/// \brief The result proxy object for the
/// \c FunctionAnalysisManagerModuleProxy.
///
/// See its documentation for more information.
class FunctionAnalysisManagerModuleProxy::Result {
public:
Result(FunctionAnalysisManager &FAM) : FAM(FAM) {}
~Result();
/// \brief Accessor for the \c FunctionAnalysisManager.
FunctionAnalysisManager &getManager() const { return FAM; }
/// \brief Handler for invalidation of the module.
///
/// If this analysis itself is preserved, then we assume that the set of \c
/// Function objects in the \c Module hasn't changed and thus we don't need
/// to invalidate *all* cached data associated with a \c Function* in the \c
/// FunctionAnalysisManager.
///
/// Regardless of whether this analysis is marked as preserved, all of the
/// analyses in the \c FunctionAnalysisManager are potentially invalidated
/// based on the set of preserved analyses.
bool invalidate(Module *M, const PreservedAnalyses &PA);
private:
FunctionAnalysisManager &FAM;
};
/// \brief A function analysis which acts as a proxy for a module analysis
/// manager.
///
/// This primarily provides an accessor to a parent module analysis manager to
/// function passes. Only the const interface of the module analysis manager is
/// provided to indicate that once inside of a function analysis pass you
/// cannot request a module analysis to actually run. Instead, the user must
/// rely on the \c getCachedResult API.
///
/// This proxy *doesn't* manage the invalidation in any way. That is handled by
/// the recursive return path of each layer of the pass manager and the
/// returned PreservedAnalysis set.
class ModuleAnalysisManagerFunctionProxy {
public:
/// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
class Result {
public:
Result(const ModuleAnalysisManager &MAM) : MAM(MAM) {}
const ModuleAnalysisManager &getManager() const { return MAM; }
/// \brief Handle invalidation by ignoring it, this pass is immutable.
bool invalidate(Function *) { return false; }
private:
const ModuleAnalysisManager &MAM;
};
static void *ID() { return (void *)&PassID; }
ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
: MAM(MAM) {}
/// \brief Run the analysis pass and create our proxy result object.
/// Nothing to see here, it just forwards the \c MAM reference into the
/// result.
Result run(Function *) { return Result(MAM); }
private:
static char PassID;
const ModuleAnalysisManager &MAM;
};
/// \brief Trivial adaptor that maps from a module to its functions.
///
/// Designed to allow composition of a FunctionPass(Manager) and
/// a ModulePassManager. Note that if this pass is constructed with a pointer
/// to a \c ModuleAnalysisManager it will run the
/// \c FunctionAnalysisManagerModuleProxy analysis prior to running the function
/// pass over the module to enable a \c FunctionAnalysisManager to be used
/// within this run safely.
template <typename FunctionPassT>
class ModuleToFunctionPassAdaptor {
public:
explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)
: Pass(llvm_move(Pass)) {}
/// \brief Runs the function pass across every function in the module.
PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
FunctionAnalysisManager *FAM = 0;
if (AM)
// Setup the function analysis manager from its proxy.
FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
PreservedAnalyses PA = PreservedAnalyses::all();
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
PreservedAnalyses PassPA = Pass.run(I, FAM);
// We know that the function pass couldn't have invalidated any other
// function's analyses (that's the contract of a function pass), so
// directly handle the function analysis manager's invalidation here.
if (FAM)
FAM->invalidate(I, PassPA);
// Then intersect the preserved set so that invalidation of module
// analyses will eventually occur when the module pass completes.
PA.intersect(llvm_move(PassPA));
}
// By definition we preserve the proxy. This precludes *any* invalidation
// of function analyses by the proxy, but that's OK because we've taken
// care to invalidate analyses in the function analysis manager
// incrementally above.
PA.preserve<FunctionAnalysisManagerModuleProxy>();
return PA;
}
private:
FunctionPassT Pass;
};
/// \brief A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename FunctionPassT>
ModuleToFunctionPassAdaptor<FunctionPassT>
createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
return ModuleToFunctionPassAdaptor<FunctionPassT>(llvm_move(Pass));
}
}

View File

@ -16,6 +16,7 @@
#define LLVM_IR_TYPE_H
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/DataTypes.h"
@ -70,11 +71,7 @@ public:
StructTyID, ///< 12: Structures
ArrayTyID, ///< 13: Arrays
PointerTyID, ///< 14: Pointers
VectorTyID, ///< 15: SIMD 'packed' format, or other vector type
NumTypeIDs, // Must remain as last defined ID
LastPrimitiveTyID = X86_MMXTyID,
FirstDerivedTyID = IntegerTyID
VectorTyID ///< 15: SIMD 'packed' format, or other vector type
};
private:
@ -239,12 +236,6 @@ public:
/// elements or all its elements are empty.
bool isEmptyTy() const;
/// Here are some useful little methods to query what type derived types are
/// Note that all other types can just compare to see if this == Type::xxxTy;
///
bool isPrimitiveType() const { return getTypeID() <= LastPrimitiveTyID; }
bool isDerivedType() const { return getTypeID() >= FirstDerivedTyID; }
/// isFirstClassType - Return true if the type is "first class", meaning it
/// is a valid type for a Value.
///
@ -257,9 +248,8 @@ public:
/// and array types.
///
bool isSingleValueType() const {
return (getTypeID() != VoidTyID && isPrimitiveType()) ||
getTypeID() == IntegerTyID || getTypeID() == PointerTyID ||
getTypeID() == VectorTyID;
return isFloatingPointTy() || isX86_MMXTy() || isIntegerTy() ||
isPointerTy() || isVectorTy();
}
/// isAggregateType - Return true if the type is an aggregate type. This
@ -275,7 +265,7 @@ public:
/// get the actual size for a particular target, it is reasonable to use the
/// DataLayout subsystem to do this.
///
bool isSized() const {
bool isSized(SmallPtrSet<const Type*, 4> *Visited = 0) const {
// If it's a primitive, it is always sized.
if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
getTypeID() == PointerTyID ||
@ -287,7 +277,7 @@ public:
getTypeID() != VectorTyID)
return false;
// Otherwise we have to try harder to decide.
return isSizedDerivedType();
return isSizedDerivedType(Visited);
}
/// getPrimitiveSizeInBits - Return the basic size of this type if it is a
@ -300,12 +290,12 @@ public:
/// instance of the type is stored to memory. The DataLayout class provides
/// additional query functions to provide this information.
///
unsigned getPrimitiveSizeInBits() const;
unsigned getPrimitiveSizeInBits() const LLVM_READONLY;
/// getScalarSizeInBits - If this is a vector type, return the
/// getPrimitiveSizeInBits value for the element type. Otherwise return the
/// getPrimitiveSizeInBits value for this type.
unsigned getScalarSizeInBits();
unsigned getScalarSizeInBits() const LLVM_READONLY;
/// getFPMantissaWidth - Return the width of the mantissa of this type. This
/// is only valid on floating point types. If the FP type does not
@ -314,8 +304,8 @@ public:
/// getScalarType - If this is a vector type, return the element type,
/// otherwise return 'this'.
const Type *getScalarType() const;
Type *getScalarType();
const Type *getScalarType() const LLVM_READONLY;
Type *getScalarType() LLVM_READONLY;
//===--------------------------------------------------------------------===//
// Type Iteration support.
@ -429,7 +419,7 @@ private:
/// isSizedDerivedType - Derived types like structures and arrays are sized
/// iff all of the members of the type are sized as well. Since asking for
/// their size is relatively uncommon, move this operation out of line.
bool isSizedDerivedType() const;
bool isSizedDerivedType(SmallPtrSet<const Type*, 4> *Visited = 0) const;
};
// Printing of types.

View File

@ -73,7 +73,7 @@ void initializeArgPromotionPass(PassRegistry&);
void initializeSampleProfileLoaderPass(PassRegistry&);
void initializeBarrierNoopPass(PassRegistry&);
void initializeBasicAliasAnalysisPass(PassRegistry&);
void initializeCallGraphPass(PassRegistry&);
void initializeCallGraphWrapperPassPass(PassRegistry &);
void initializeBasicTTIPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyInfoPass(PassRegistry&);
@ -120,6 +120,7 @@ void initializeAddressSanitizerModulePass(PassRegistry&);
void initializeMemorySanitizerPass(PassRegistry&);
void initializeThreadSanitizerPass(PassRegistry&);
void initializeDataFlowSanitizerPass(PassRegistry&);
void initializeScalarizerPass(PassRegistry&);
void initializeEarlyCSEPass(PassRegistry&);
void initializeExpandISelPseudosPass(PassRegistry&);
void initializeFindUsedTypesPass(PassRegistry&);
@ -209,6 +210,7 @@ void initializePostDomPrinterPass(PassRegistry&);
void initializePostDomViewerPass(PassRegistry&);
void initializePostDominatorTreePass(PassRegistry&);
void initializePostRASchedulerPass(PassRegistry&);
void initializePostMachineSchedulerPass(PassRegistry&);
void initializePreVerifierPass(PassRegistry&);
void initializePrintFunctionPassPass(PassRegistry&);
void initializePrintModulePassPass(PassRegistry&);
@ -265,6 +267,7 @@ void initializeLoopVectorizePass(PassRegistry&);
void initializeSLPVectorizerPass(PassRegistry&);
void initializeBBVectorizePass(PassRegistry&);
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
void initializeStackMapLivenessPass(PassRegistry&);
}
#endif

View File

@ -154,6 +154,7 @@ namespace {
(void) llvm::createSLPVectorizerPass();
(void) llvm::createBBVectorizePass();
(void) llvm::createPartiallyInlineLibCallsPass();
(void) llvm::createScalarizerPass();
(void)new llvm::IntervalPartition();
(void)new llvm::FindUsedTypes();

View File

@ -82,7 +82,7 @@ namespace llvm {
/// LinkerRequiresNonEmptyDwarfLines - True if the linker has a bug and
/// requires that the debug_line section be of a minimum size. In practice
/// such a linker requires a non empty line sequence if a file is present.
/// such a linker requires a non-empty line sequence if a file is present.
bool LinkerRequiresNonEmptyDwarfLines; // Default to false.
/// MaxInstLength - This is the maximum possible length of an instruction,
@ -115,19 +115,10 @@ namespace llvm {
/// LabelSuffix - This is appended to emitted labels.
const char *DebugLabelSuffix; // Defaults to ":"
/// GlobalPrefix - If this is set to a non-empty string, it is prepended
/// onto all global symbols. This is often used for "_" or ".".
const char *GlobalPrefix; // Defaults to ""
/// PrivateGlobalPrefix - This prefix is used for globals like constant
/// pool entries that are completely private to the .s file and should not
/// have names in the .o file. This is often "." or "L".
const char *PrivateGlobalPrefix; // Defaults to "."
/// LinkerPrivateGlobalPrefix - This prefix is used for symbols that should
/// be passed through the assembler but be removed by the linker. This
/// is "l" on Darwin, currently used for some ObjC metadata.
const char *LinkerPrivateGlobalPrefix; // Defaults to ""
/// This prefix is used for globals like constant pool entries that are
/// completely private to the .s file and should not have names in the .o
/// file.
const char *PrivateGlobalPrefix; // Defaults to "L"
/// InlineAsmStart/End - If these are nonempty, they contain a directive to
/// emit before and after an inline assembly statement.
@ -198,11 +189,6 @@ namespace llvm {
/// which doesn't support the '.bss' directive only.
bool UsesELFSectionDirectiveForBSS; // Defaults to false.
/// HasMicrosoftFastStdCallMangling - True if this target uses microsoft
/// style mangling for functions with X86_StdCall/X86_FastCall calling
/// convention.
bool HasMicrosoftFastStdCallMangling; // Defaults to false.
bool NeedsDwarfSectionOffsetDirective;
//===--- Alignment Information ----------------------------------------===//
@ -266,13 +252,16 @@ namespace llvm {
/// global as being a weak undefined symbol.
const char *WeakRefDirective; // Defaults to NULL.
/// WeakDefDirective - This directive, if non-null, is used to declare a
/// global as being a weak defined symbol.
const char *WeakDefDirective; // Defaults to NULL.
/// True if we have a directive to declare a global as being a weak
/// defined symbol.
bool HasWeakDefDirective; // Defaults to false.
/// LinkOnceDirective - This directive, if non-null is used to declare a
/// global as being a weak defined symbol. This is used on cygwin/mingw.
const char *LinkOnceDirective; // Defaults to NULL.
/// True if we have a directive to declare a global as being a weak
/// defined symbol that can be hidden (unexported).
bool HasWeakDefCanBeHiddenDirective; // Defaults to false.
/// True if we have a .linkonce directive. This is used on cygwin/mingw.
bool HasLinkOnceDirective; // Defaults to false.
/// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to
/// declare a symbol as having hidden visibility.
@ -307,6 +296,10 @@ namespace llvm {
/// instead of symbolic register names in .cfi_* directives.
bool DwarfRegNumForCFI; // Defaults to false;
/// UseParensForSymbolVariant - True if target uses parens to indicate the
/// symbol variant instead of @. For example, foo(plt) instead of foo@plt.
bool UseParensForSymbolVariant; // Defaults to false;
//===--- Prologue State ----------------------------------------------===//
std::vector<MCCFIInstruction> InitialFrameState;
@ -384,10 +377,6 @@ namespace llvm {
return UsesELFSectionDirectiveForBSS;
}
bool hasMicrosoftFastStdCallMangling() const {
return HasMicrosoftFastStdCallMangling;
}
bool needsDwarfSectionOffsetDirective() const {
return NeedsDwarfSectionOffsetDirective;
}
@ -427,16 +416,9 @@ namespace llvm {
const char *getDebugLabelSuffix() const {
return DebugLabelSuffix;
}
const char *getGlobalPrefix() const {
return GlobalPrefix;
}
const char *getPrivateGlobalPrefix() const {
return PrivateGlobalPrefix;
}
const char *getLinkerPrivateGlobalPrefix() const {
return LinkerPrivateGlobalPrefix;
}
const char *getInlineAsmStart() const {
return InlineAsmStart;
}
@ -497,8 +479,11 @@ namespace llvm {
bool hasIdentDirective() const { return HasIdentDirective; }
bool hasNoDeadStrip() const { return HasNoDeadStrip; }
const char *getWeakRefDirective() const { return WeakRefDirective; }
const char *getWeakDefDirective() const { return WeakDefDirective; }
const char *getLinkOnceDirective() const { return LinkOnceDirective; }
bool hasWeakDefDirective() const { return HasWeakDefDirective; }
bool hasWeakDefCanBeHiddenDirective() const {
return HasWeakDefCanBeHiddenDirective;
}
bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;}
MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
@ -531,6 +516,9 @@ namespace llvm {
bool useDwarfRegNumForCFI() const {
return DwarfRegNumForCFI;
}
bool useParensForSymbolVariant() const {
return UseParensForSymbolVariant;
}
void addInitialFrameState(const MCCFIInstruction &Inst) {
InitialFrameState.push_back(Inst);

View File

@ -278,6 +278,7 @@ namespace llvm {
/// This can be overridden by clients which want to control the reported
/// compilation directory and have it be something other than the current
/// working directory.
/// Returns an empty string if the current directory cannot be determined.
StringRef getCompilationDir() const { return CompilationDir; }
/// \brief Set the compilation directory for DW_AT_comp_dir

View File

@ -21,10 +21,12 @@
namespace llvm {
enum {
ELF_STT_Shift = 0, // Shift value for STT_* flags.
ELF_STB_Shift = 4, // Shift value for STB_* flags.
ELF_STV_Shift = 8, // Shift value for STV_* flags.
ELF_Other_Shift = 10 // Shift value for other flags.
ELF_STT_Shift = 0, // Shift value for STT_* flags.
ELF_STB_Shift = 4, // Shift value for STB_* flags.
ELF_STV_Shift = 8, // Shift value for STV_* flags.
ELF_STO_Shift = 10, // Shift value for STO_* flags.
ELF_Other_Shift = 16 // Shift value for llvm local flags,
// not part of the final object file
};
enum ELFSymbolFlags {

View File

@ -15,6 +15,7 @@
#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCAsmInfo;
class MCAsmLayout;
class MCAssembler;
class MCContext;
@ -159,14 +160,8 @@ public:
VK_DTPOFF,
VK_TLVP, // Mach-O thread local variable relocation
VK_SECREL,
// FIXME: We'd really like to use the generic Kinds listed above for these.
VK_ARM_NONE,
VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT
VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF
VK_ARM_GOT,
VK_ARM_GOTOFF,
VK_ARM_TPOFF,
VK_ARM_GOTTPOFF,
VK_ARM_TARGET1,
VK_ARM_TARGET2,
VK_ARM_PREL31,
@ -258,9 +253,14 @@ private:
/// The symbol reference modifier.
const VariantKind Kind;
explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind)
: MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {
/// MCAsmInfo that is used to print symbol variants correctly.
const MCAsmInfo *MAI;
explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind,
const MCAsmInfo *_MAI)
: MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind), MAI(_MAI) {
assert(Symbol);
assert(MAI);
}
public:
@ -281,6 +281,7 @@ public:
/// @{
const MCSymbol &getSymbol() const { return *Symbol; }
const MCAsmInfo &getMCAsmInfo() const { return *MAI; }
VariantKind getKind() const { return Kind; }

View File

@ -262,6 +262,8 @@ public:
const MCSection *getDwarfInfoDWOSection() const {
return DwarfInfoDWOSection;
}
const MCSection *getDwarfTypesSection(uint64_t Hash) const;
const MCSection *getDwarfTypesDWOSection(uint64_t Hash) const;
const MCSection *getDwarfAbbrevDWOSection() const {
return DwarfAbbrevDWOSection;
}
@ -353,8 +355,12 @@ public:
return EHFrameSection;
}
private:
enum Environment { IsMachO, IsELF, IsCOFF };
Environment getObjectFileType() const {
return Env;
}
private:
Environment Env;
Reloc::Model RelocM;
CodeModel::Model CMModel;

View File

@ -30,6 +30,7 @@ class AsmLexer : public MCAsmLexer {
const char *CurPtr;
const MemoryBuffer *CurBuf;
bool isAtStartOfLine;
bool AllowAtInIdentifier; // Cached here to avoid repeated MAI query.
void operator=(const AsmLexer&) LLVM_DELETED_FUNCTION;
AsmLexer(const AsmLexer&) LLVM_DELETED_FUNCTION;

View File

@ -36,7 +36,8 @@ struct MCProcResourceDesc {
// some indeterminate cycle after dispatch (e.g. for instructions that may
// issue out-of-order). Unbuffered resources (BufferSize == 0) always consume
// their resource some fixed number of cycles after dispatch (e.g. for
// instruction interlocking that may stall the pipeline).
// instruction interlocking that may stall the pipeline). If BufferSize==1,
// the latency between producer and consumer is modeled as a stall.
int BufferSize;
bool operator==(const MCProcResourceDesc &Other) const {
@ -149,7 +150,7 @@ public:
// but we balance those stalls against other heuristics.
//
// "> 1" means the processor is out-of-order. This is a machine independent
// estimate of highly machine specific characteristics such are the register
// estimate of highly machine specific characteristics such as the register
// renaming pool and reorder buffer.
unsigned MicroOpBufferSize;
static const unsigned DefaultMicroOpBufferSize = 0;

View File

@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
@ -60,8 +61,13 @@ public:
StringRef getSectionName() const { return SectionName; }
virtual std::string getLabelBeginName() const {
return SectionName.str() + "_begin"; }
if (Group)
return (SectionName.str() + '_' + Group->getName() + "_begin").str();
return SectionName.str() + "_begin";
}
virtual std::string getLabelEndName() const {
if (Group)
return (SectionName.str() + '_' + Group->getName() + "_end").str();
return SectionName.str() + "_end";
}
unsigned getType() const { return Type; }

View File

@ -93,7 +93,9 @@ public:
virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0;
virtual void emitTextAttribute(unsigned Attribute, StringRef String) = 0;
virtual void emitFPU(unsigned FPU) = 0;
virtual void emitArch(unsigned Arch) = 0;
virtual void finishAttributeSection() = 0;
virtual void emitInst(uint32_t Inst, char Suffix = '\0') = 0;
};
/// MCStreamer - Streaming machine code generation interface. This interface
@ -334,6 +336,8 @@ public:
/// @param Symbol - The symbol to emit. A given symbol should only be
/// emitted as a label once, and symbols emitted as a label should never be
/// used in an assignment.
// FIXME: These emission are non-const because we mutate the symbol to
// add the section we're emitting it to later.
virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitDebugLabel(MCSymbol *Symbol);
@ -407,9 +411,14 @@ public:
/// EndCOFFSymbolDef - Marks the end of the symbol definition.
virtual void EndCOFFSymbolDef() = 0;
/// EmitCOFFSectionIndex - Emits a COFF section index.
///
/// @param Symbol - Symbol the section number relocation should point to.
virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
/// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
///
/// @param Symbol - Symbol the section relative realocation should point to.
/// @param Symbol - Symbol the section relative relocation should point to.
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
/// EmitELFSize - Emit an ELF .size directive.

View File

@ -141,7 +141,7 @@ namespace llvm {
}
// AliasedSymbol() - If this is an alias (a = b), return the symbol
// we ultimately point to. For a non alias, this just returns the symbol
// we ultimately point to. For a non-alias, this just returns the symbol
// itself.
const MCSymbol &AliasedSymbol() const;

View File

@ -182,6 +182,11 @@ public:
return 0;
}
/// Allow a target to perform any actions after the parse completes
/// successfully. For example, to write out constant pools for ldr pseudo on
/// ARM.
virtual void finishParse() {};
virtual void onLabelParsed(MCSymbol *Symbol) { };
};

View File

@ -25,7 +25,6 @@ class BranchProbability;
class BlockFrequency {
uint64_t Frequency;
static const int64_t ENTRY_FREQ = 1 << 14;
/// \brief Scale the given BlockFrequency by N/D. Return the remainder from
/// the division by D. Upon overflow, the routine will saturate and
@ -35,9 +34,6 @@ class BlockFrequency {
public:
BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
/// \brief Returns the frequency of the entry block of the function.
static uint64_t getEntryFrequency() { return ENTRY_FREQ; }
/// \brief Returns the maximum possible frequency, the saturation value.
static uint64_t getMaxFrequency() { return -1ULL; }
@ -59,6 +55,9 @@ public:
BlockFrequency &operator+=(const BlockFrequency &Freq);
const BlockFrequency operator+(const BlockFrequency &Freq) const;
/// \brief Shift block frequency to the right by count digits saturating to 1.
BlockFrequency &operator>>=(const unsigned count);
/// \brief Scale the given BlockFrequency by N/D. Return the remainder from
/// the division by D. Upon overflow, the routine will saturate.
uint32_t scale(const BranchProbability &Prob);
@ -78,12 +77,8 @@ public:
bool operator>=(const BlockFrequency &RHS) const {
return Frequency >= RHS.Frequency;
}
void print(raw_ostream &OS) const;
};
raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq);
}
#endif

View File

@ -34,7 +34,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
USE_iterator It;
inline void advancePastNonTerminators() {
// Loop to ignore non terminator uses (for example BlockAddresses).
// Loop to ignore non-terminator uses (for example BlockAddresses).
while (!It.atEnd() && !isa<TerminatorInst>(*It))
++It;
}

View File

@ -611,6 +611,13 @@ namespace COFF {
}
};
enum CodeViewLineTableIdentifiers {
DEBUG_SECTION_MAGIC = 0x4,
DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
DEBUG_STRING_TABLE_SUBSECTION = 0xF3,
DEBUG_INDEX_SUBSECTION = 0xF4
};
} // End namespace COFF.
} // End namespace llvm.

View File

@ -257,6 +257,22 @@ public:
return paramHasAttr(ArgNo + 1, Attribute::ByVal);
}
/// @brief Determine whether this argument is passed in an alloca.
bool isInAllocaArgument(unsigned ArgNo) const {
return paramHasAttr(ArgNo + 1, Attribute::InAlloca);
}
/// @brief Determine whether this argument is passed by value or in an alloca.
bool isByValOrInAllocaArgument(unsigned ArgNo) const {
return paramHasAttr(ArgNo + 1, Attribute::ByVal) ||
paramHasAttr(ArgNo + 1, Attribute::InAlloca);
}
/// @brief Determine if there are any inalloca arguments.
bool hasInAllocaArgument() const {
return getAttributes().hasAttrSomewhere(Attribute::InAlloca);
}
bool doesNotAccessMemory(unsigned ArgNo) const {
return paramHasAttr(ArgNo + 1, Attribute::ReadNone);
}

View File

@ -21,6 +21,10 @@
# define __has_feature(x) 0
#endif
#ifndef __has_extension
# define __has_extension(x) 0
#endif
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
@ -40,12 +44,23 @@
# endif
#endif
/// \macro LLVM_MSC_PREREQ
/// \brief Is the compiler MSVC of at least the specified version?
/// The common \param version values to check for are:
/// * 1600: Microsoft Visual Studio 2010 / 10.0
/// * 1700: Microsoft Visual Studio 2012 / 11.0
/// * 1800: Microsoft Visual Studio 2013 / 12.0
#ifdef _MSC_VER
#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
#else
#define LLVM_MSC_PREREQ(version) 0
#endif
/// \brief Does the compiler support r-value references?
/// This implies that <utility> provides the one-argument std::move; it
/// does not imply the existence of any other C++ library features.
#if (__has_feature(cxx_rvalue_references) \
|| defined(__GXX_EXPERIMENTAL_CXX0X__) \
|| (defined(_MSC_VER) && _MSC_VER >= 1600))
#if __has_feature(cxx_rvalue_references) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1600)
#define LLVM_HAS_RVALUE_REFERENCES 1
#else
#define LLVM_HAS_RVALUE_REFERENCES 0
@ -72,8 +87,7 @@
/// * {true,false}_type
/// * is_constructible
/// * etc...
#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
|| (defined(_MSC_VER) && _MSC_VER >= 1700)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
#define LLVM_HAS_CXX11_TYPETRAITS 1
#else
#define LLVM_HAS_CXX11_TYPETRAITS 0
@ -83,8 +97,7 @@
/// \brief Does the compiler have the C++11 standard library.
///
/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS
#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
|| (defined(_MSC_VER) && _MSC_VER >= 1700)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
#define LLVM_HAS_CXX11_STDLIB 1
#else
#define LLVM_HAS_CXX11_STDLIB 0
@ -94,7 +107,7 @@
/// \brief Does this compiler support variadic templates.
///
/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward.
#if __has_feature(cxx_variadic_templates)
#if __has_feature(cxx_variadic_templates) || LLVM_MSC_PREREQ(1800)
# define LLVM_HAS_VARIADIC_TEMPLATES 1
#else
# define LLVM_HAS_VARIADIC_TEMPLATES 0
@ -129,9 +142,8 @@
/// public:
/// ...
/// };
#if (__has_feature(cxx_deleted_functions) \
|| defined(__GXX_EXPERIMENTAL_CXX0X__))
// No version of MSVC currently supports this.
#if __has_feature(cxx_deleted_functions) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
#define LLVM_DELETED_FUNCTION = delete
#else
#define LLVM_DELETED_FUNCTION
@ -139,8 +151,8 @@
/// LLVM_FINAL - Expands to 'final' if the compiler supports it.
/// Use to mark classes or virtual methods as final.
#if __has_feature(cxx_override_control) \
|| (defined(_MSC_VER) && _MSC_VER >= 1700)
#if __has_feature(cxx_override_control) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
#define LLVM_FINAL final
#else
#define LLVM_FINAL
@ -148,8 +160,8 @@
/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it.
/// Use to mark virtual methods as overriding a base class method.
#if __has_feature(cxx_override_control) \
|| (defined(_MSC_VER) && _MSC_VER >= 1700)
#if __has_feature(cxx_override_control) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
#define LLVM_OVERRIDE override
#else
#define LLVM_OVERRIDE
@ -374,8 +386,8 @@
/// \macro LLVM_EXPLICIT
/// \brief Expands to explicit on compilers which support explicit conversion
/// operators. Otherwise expands to nothing.
#if (__has_feature(cxx_explicit_conversions) \
|| defined(__GXX_EXPERIMENTAL_CXX0X__))
#if __has_feature(cxx_explicit_conversions) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
#define LLVM_EXPLICIT explicit
#else
#define LLVM_EXPLICIT
@ -383,10 +395,13 @@
/// \macro LLVM_STATIC_ASSERT
/// \brief Expands to C/C++'s static_assert on compilers which support it.
#if __has_feature(cxx_static_assert)
#if __has_feature(cxx_static_assert) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1600)
# define LLVM_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
#elif __has_feature(c_static_assert)
# define LLVM_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
#elif __has_extension(c_static_assert)
# define LLVM_STATIC_ASSERT(expr, msg) LLVM_EXTENSION _Static_assert(expr, msg)
#else
# define LLVM_STATIC_ASSERT(expr, msg)
#endif
@ -395,17 +410,25 @@
/// \brief Expands to colon followed by the given integral type on compilers
/// which support C++11 strong enums. This can be used to make enums unsigned
/// with MSVC.
#if __has_feature(cxx_strong_enums)
# define LLVM_ENUM_INT_TYPE(intty) : intty
#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Added in MSVC 2010.
#if __has_feature(cxx_strong_enums) || LLVM_MSC_PREREQ(1600)
# define LLVM_ENUM_INT_TYPE(intty) : intty
#else
# define LLVM_ENUM_INT_TYPE(intty)
#endif
/// \brief Does the compiler support C++11 semantics for strongly typed forward
/// declared enums?
#if __has_feature(cxx_strong_enums) || LLVM_MSC_PREREQ(1700)
#define LLVM_HAS_STRONG_ENUMS 1
#else
#define LLVM_HAS_STRONG_ENUMS 0
#endif
/// \brief Does the compiler support generalized initializers (using braced
/// lists and std::initializer_list).
#if __has_feature(cxx_generalized_initializers)
/// lists and std::initializer_list). While clang may claim it supports general
/// initializers, if we're using MSVC's headers, we might not have a usable
/// std::initializer list type from the STL. Disable this for now.
#if __has_feature(cxx_generalized_initializers) && !defined(_MSC_VER)
#define LLVM_HAS_INITIALIZER_LISTS 1
#else
#define LLVM_HAS_INITIALIZER_LISTS 0

View File

@ -41,7 +41,7 @@ namespace dwarf {
//===----------------------------------------------------------------------===//
// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
// reference manual http://dwarf.freestandards.org.
// reference manual http://www.dwarfstd.org/.
//
// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
@ -129,6 +129,12 @@ enum Tag LLVM_ENUM_INT_TYPE(uint16_t) {
DW_TAG_type_unit = 0x41,
DW_TAG_rvalue_reference_type = 0x42,
DW_TAG_template_alias = 0x43,
// New in DWARF 5:
DW_TAG_coarray_type = 0x44,
DW_TAG_generic_subrange = 0x45,
DW_TAG_dynamic_type = 0x46,
DW_TAG_MIPS_loop = 0x4081,
DW_TAG_format_label = 0x4101,
DW_TAG_function_template = 0x4102,
@ -264,6 +270,18 @@ enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
DW_AT_enum_class = 0x6d,
DW_AT_linkage_name = 0x6e,
// New in DWARF 5:
DW_AT_string_length_bit_size = 0x6f,
DW_AT_string_length_byte_size = 0x70,
DW_AT_rank = 0x71,
DW_AT_str_offsets_base = 0x72,
DW_AT_addr_base = 0x73,
DW_AT_ranges_base = 0x74,
DW_AT_dwo_id = 0x75,
DW_AT_dwo_name = 0x76,
DW_AT_reference = 0x77,
DW_AT_rvalue_reference = 0x78,
DW_AT_lo_user = 0x2000,
DW_AT_hi_user = 0x3fff,
@ -605,7 +623,16 @@ enum SourceLanguage {
DW_LANG_ObjC_plus_plus = 0x0011,
DW_LANG_UPC = 0x0012,
DW_LANG_D = 0x0013,
// New in DWARF 5:
DW_LANG_Python = 0x0014,
DW_LANG_OpenCL = 0x0015,
DW_LANG_Go = 0x0016,
DW_LANG_Modula3 = 0x0017,
DW_LANG_Haskell = 0x0018,
DW_LANG_C_plus_plus_03 = 0x0019,
DW_LANG_C_plus_plus_11 = 0x001a,
DW_LANG_OCaml = 0x001b,
DW_LANG_lo_user = 0x8000,
DW_LANG_Mips_Assembler = 0x8001,
DW_LANG_hi_user = 0xffff

View File

@ -890,6 +890,8 @@ enum {
R_MICROMIPS_GOT_DISP = 145,
R_MICROMIPS_GOT_PAGE = 146,
R_MICROMIPS_GOT_OFST = 147,
R_MICROMIPS_TLS_GD = 162,
R_MICROMIPS_TLS_LDM = 163,
R_MICROMIPS_TLS_DTPREL_HI16 = 164,
R_MICROMIPS_TLS_DTPREL_LO16 = 165,
R_MICROMIPS_TLS_TPREL_HI16 = 169,

View File

@ -545,6 +545,11 @@ inline error_code file_size(const Twine &Path, uint64_t &Result) {
return error_code::success();
}
/// @brief Set the file modification and access time.
///
/// @returns errc::success if the file times were successfully set, otherwise a
/// platform specific error_code or errc::not_supported on platforms
/// where the functionality isn't available.
error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
/// @brief Is status available?

View File

@ -1,4 +1,4 @@
//===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===//
//===- GCOV.h - LLVM coverage tool ----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This header provides the interface to read and write coverage files that
// This header provides the interface to read and write coverage files that
// use 'gcov' format.
//
//===----------------------------------------------------------------------===//
@ -16,6 +16,7 @@
#define LLVM_SUPPORT_GCOV_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
@ -28,36 +29,68 @@ class GCOVBlock;
class FileInfo;
namespace GCOV {
enum GCOVFormat {
InvalidGCOV,
GCNO_402,
GCNO_404,
GCDA_402,
GCDA_404
enum GCOVVersion {
V402,
V404
};
} // end GCOV namespace
/// GCOVOptions - A struct for passing gcov options between functions.
struct GCOVOptions {
GCOVOptions(bool A, bool B, bool C, bool F, bool U) :
AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F), UncondBranch(U)
{}
bool AllBlocks;
bool BranchInfo;
bool BranchCount;
bool FuncCoverage;
bool UncondBranch;
};
/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
/// read operations.
class GCOVBuffer {
public:
GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
/// readGCOVFormat - Read GCOV signature at the beginning of buffer.
GCOV::GCOVFormat readGCOVFormat() {
StringRef Magic = Buffer->getBuffer().slice(0, 12);
Cursor = 12;
if (Magic == "oncg*404MVLL")
return GCOV::GCNO_404;
else if (Magic == "oncg*204MVLL")
return GCOV::GCNO_402;
else if (Magic == "adcg*404MVLL")
return GCOV::GCDA_404;
else if (Magic == "adcg*204MVLL")
return GCOV::GCDA_402;
Cursor = 0;
return GCOV::InvalidGCOV;
/// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
bool readGCNOFormat() {
StringRef File = Buffer->getBuffer().slice(0, 4);
if (File != "oncg") {
errs() << "Unexpected file type: " << File << ".\n";
return false;
}
Cursor = 4;
return true;
}
/// readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
bool readGCDAFormat() {
StringRef File = Buffer->getBuffer().slice(0, 4);
if (File != "adcg") {
errs() << "Unexpected file type: " << File << ".\n";
return false;
}
Cursor = 4;
return true;
}
/// readGCOVVersion - Read GCOV version.
bool readGCOVVersion(GCOV::GCOVVersion &Version) {
StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (VersionStr == "*204") {
Cursor += 4;
Version = GCOV::V402;
return true;
}
if (VersionStr == "*404") {
Cursor += 4;
Version = GCOV::V404;
return true;
}
errs() << "Unexpected version: " << VersionStr << ".\n";
return false;
}
/// readFunctionTag - If cursor points to a function tag then increment the
@ -193,67 +226,183 @@ private:
/// (.gcno and .gcda).
class GCOVFile {
public:
GCOVFile() : Functions(), RunCount(0), ProgramCount(0) {}
GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
ProgramCount(0) {}
~GCOVFile();
bool read(GCOVBuffer &Buffer);
void dump();
bool readGCNO(GCOVBuffer &Buffer);
bool readGCDA(GCOVBuffer &Buffer);
uint32_t getChecksum() const { return Checksum; }
void dump() const;
void collectLineCounts(FileInfo &FI);
private:
bool GCNOInitialized;
GCOV::GCOVVersion Version;
uint32_t Checksum;
SmallVector<GCOVFunction *, 16> Functions;
uint32_t RunCount;
uint32_t ProgramCount;
};
/// GCOVEdge - Collects edge information.
struct GCOVEdge {
GCOVEdge(GCOVBlock *S, GCOVBlock *D): Src(S), Dst(D), Count(0) {}
GCOVBlock *Src;
GCOVBlock *Dst;
uint64_t Count;
};
/// GCOVFunction - Collects function information.
class GCOVFunction {
public:
GCOVFunction() : Ident(0), LineNumber(0) {}
typedef SmallVectorImpl<GCOVBlock *>::const_iterator BlockIterator;
GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {}
~GCOVFunction();
bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
StringRef getName() const { return Name; }
StringRef getFilename() const { return Filename; }
void dump();
size_t getNumBlocks() const { return Blocks.size(); }
uint64_t getEntryCount() const;
uint64_t getExitCount() const;
BlockIterator block_begin() const { return Blocks.begin(); }
BlockIterator block_end() const { return Blocks.end(); }
void dump() const;
void collectLineCounts(FileInfo &FI);
private:
GCOVFile &Parent;
uint32_t Ident;
uint32_t Checksum;
uint32_t LineNumber;
StringRef Name;
StringRef Filename;
SmallVector<GCOVBlock *, 16> Blocks;
SmallVector<GCOVEdge *, 16> Edges;
};
/// GCOVBlock - Collects block information.
class GCOVBlock {
struct EdgeWeight {
EdgeWeight(GCOVBlock *D): Dst(D), Count(0) {}
GCOVBlock *Dst;
uint64_t Count;
};
struct SortDstEdgesFunctor {
bool operator()(const GCOVEdge *E1, const GCOVEdge *E2) {
return E1->Dst->Number < E2->Dst->Number;
}
};
public:
GCOVBlock(GCOVFunction &P, uint32_t N) :
Parent(P), Number(N), Counter(0), Edges(), Lines() {}
typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator;
GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0),
DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {}
~GCOVBlock();
void addEdge(uint32_t N) { Edges.push_back(N); }
const GCOVFunction &getParent() const { return Parent; }
void addLine(uint32_t N) { Lines.push_back(N); }
void addCount(uint64_t N) { Counter += N; }
size_t getNumEdges() { return Edges.size(); }
void dump();
uint32_t getLastLine() const { return Lines.back(); }
void addCount(size_t DstEdgeNo, uint64_t N);
uint64_t getCount() const { return Counter; }
void addSrcEdge(GCOVEdge *Edge) {
assert(Edge->Dst == this); // up to caller to ensure edge is valid
SrcEdges.push_back(Edge);
}
void addDstEdge(GCOVEdge *Edge) {
assert(Edge->Src == this); // up to caller to ensure edge is valid
// Check if adding this edge causes list to become unsorted.
if (DstEdges.size() && DstEdges.back()->Dst->Number > Edge->Dst->Number)
DstEdgesAreSorted = false;
DstEdges.push_back(Edge);
}
size_t getNumSrcEdges() const { return SrcEdges.size(); }
size_t getNumDstEdges() const { return DstEdges.size(); }
void sortDstEdges();
EdgeIterator src_begin() const { return SrcEdges.begin(); }
EdgeIterator src_end() const { return SrcEdges.end(); }
EdgeIterator dst_begin() const { return DstEdges.begin(); }
EdgeIterator dst_end() const { return DstEdges.end(); }
void dump() const;
void collectLineCounts(FileInfo &FI);
private:
GCOVFunction &Parent;
uint32_t Number;
uint64_t Counter;
SmallVector<uint32_t, 16> Edges;
bool DstEdgesAreSorted;
SmallVector<GCOVEdge *, 16> SrcEdges;
SmallVector<GCOVEdge *, 16> DstEdges;
SmallVector<uint32_t, 16> Lines;
};
typedef DenseMap<uint32_t, uint64_t> LineCounts;
class FileInfo {
// It is unlikely--but possible--for multiple functions to be on the same line.
// Therefore this typedef allows LineData.Functions to store multiple functions
// per instance. This is rare, however, so optimize for the common case.
typedef SmallVector<const GCOVFunction *, 1> FunctionVector;
typedef DenseMap<uint32_t, FunctionVector> FunctionLines;
typedef SmallVector<const GCOVBlock *, 4> BlockVector;
typedef DenseMap<uint32_t, BlockVector> BlockLines;
struct LineData {
BlockLines Blocks;
FunctionLines Functions;
};
struct GCOVCoverage {
GCOVCoverage(StringRef Name) :
Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
BranchesTaken(0) {}
StringRef Name;
uint32_t LogicalLines;
uint32_t LinesExec;
uint32_t Branches;
uint32_t BranchesExec;
uint32_t BranchesTaken;
};
public:
void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) {
LineInfo[Filename][Line-1] += Count;
FileInfo(const GCOVOptions &Options) :
Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
LineInfo[Filename].Blocks[Line-1].push_back(Block);
}
void addFunctionLine(StringRef Filename, uint32_t Line,
const GCOVFunction *Function) {
LineInfo[Filename].Functions[Line-1].push_back(Function);
}
void setRunCount(uint32_t Runs) { RunCount = Runs; }
void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile);
void print(StringRef GCNOFile, StringRef GCDAFile);
private:
StringMap<LineCounts> LineInfo;
void printFunctionSummary(raw_fd_ostream &OS,
const FunctionVector &Funcs) const;
void printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
uint32_t LineIndex, uint32_t &BlockNo) const;
void printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
GCOVCoverage &Coverage, uint32_t &EdgeNo);
void printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo,
uint64_t Count) const;
void printCoverage(const GCOVCoverage &Coverage) const;
void printFuncCoverage() const;
void printFileCoverage() const;
const GCOVOptions &Options;
StringMap<LineData> LineInfo;
uint32_t RunCount;
uint32_t ProgramCount;
SmallVector<GCOVCoverage, 4> FileCoverages;
MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverages;
};
}

View File

@ -55,7 +55,7 @@ namespace sys {
/// target which matches the host.
///
/// \return - The host CPU name, or empty if the CPU could not be determined.
std::string getHostCPUName();
StringRef getHostCPUName();
/// getHostCPUFeatures - Get the LLVM names for the host CPU features.
/// The particular format of the names are target dependent, and suitable for

View File

@ -0,0 +1,73 @@
//===- LineIterator.h - Iterator to read a text buffer's lines --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringRef.h"
#include <iterator>
namespace llvm {
class MemoryBuffer;
/// \brief A forward iterator which reads non-blank text lines from a buffer.
///
/// This class provides a forward iterator interface for reading one line at
/// a time from a buffer. When default constructed the iterator will be the
/// "end" iterator.
///
/// The iterator also is aware of what line number it is currently processing
/// and can strip comment lines given the comment-starting character.
///
/// Note that this iterator requires the buffer to be nul terminated.
class line_iterator
: public std::iterator<std::forward_iterator_tag, StringRef, ptrdiff_t> {
const MemoryBuffer *Buffer;
char CommentMarker;
unsigned LineNumber;
StringRef CurrentLine;
public:
/// \brief Default construct an "end" iterator.
line_iterator() : Buffer(0) {}
/// \brief Construct a new iterator around some memory buffer.
explicit line_iterator(const MemoryBuffer &Buffer, char CommentMarker = '\0');
/// \brief Return true if we've reached EOF or are an "end" iterator.
bool is_at_eof() const { return !Buffer; }
/// \brief Return true if we're an "end" iterator or have reached EOF.
bool is_at_end() const { return is_at_eof(); }
/// \brief Return the current line number. May return any number at EOF.
int64_t line_number() const { return LineNumber; }
/// \brief Advance to the next (non-empty, non-comment) line.
line_iterator &operator++() {
advance();
return *this;
}
/// \brief Get the current line as a \c StringRef.
StringRef operator*() const { return CurrentLine; }
friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) {
return LHS.Buffer == RHS.Buffer &&
LHS.CurrentLine.begin() == RHS.CurrentLine.begin();
}
friend bool operator!=(const line_iterator &LHS, const line_iterator &RHS) {
return !(LHS == RHS);
}
private:
/// \brief Advance the iterator to the next line.
void advance();
};
}

View File

@ -52,13 +52,16 @@ struct ProcessInfo {
ProcessInfo();
};
/// This static constructor (factory) will attempt to locate a program in
/// the operating system's file system using some pre-determined set of
/// locations to search (e.g. the PATH on Unix). Paths with slashes are
/// returned unmodified.
/// @returns A Path object initialized to the path of the program or a
/// Path object that is empty (invalid) if the program could not be found.
/// @brief Construct a Program by finding it by name.
/// This function attempts to locate a program in the operating
/// system's file system using some pre-determined set of locations to search
/// (e.g. the PATH on Unix). Paths with slashes are returned unmodified.
///
/// It does not perform hashing as a shell would but instead stats each PATH
/// entry individually so should generally be avoided. Core LLVM library
/// functions and options should instead require fully specified paths.
///
/// @returns A string containing the path of the program or an empty string if
/// the program could not be found.
std::string FindProgramByName(const std::string& name);
// These functions change the specified standard stream (stdin, stdout, or
@ -72,7 +75,9 @@ struct ProcessInfo {
/// invoked program will inherit the stdin, stdout, and stderr file
/// descriptors, the environment and other configuration settings of the
/// invoking program.
/// This function waits the program to finish.
/// This function waits for the program to finish, so should be avoided in
/// library functions that aren't expected to block. Consider using
/// ExecuteNoWait() instead.
/// @returns an integer result code indicating the status of the program.
/// A zero or positive value indicates the result code of the program.
/// -1 indicates failure to execute

View File

@ -17,6 +17,7 @@
#ifndef LLVM_SUPPORT_REGEX_H
#define LLVM_SUPPORT_REGEX_H
#include "llvm/Support/Compiler.h"
#include <string>
struct llvm_regex;
@ -45,6 +46,19 @@ namespace llvm {
/// Compiles the given regular expression \p Regex.
Regex(StringRef Regex, unsigned Flags = NoFlags);
Regex(const Regex &) LLVM_DELETED_FUNCTION;
Regex &operator=(Regex regex) {
std::swap(preg, regex.preg);
std::swap(error, regex.error);
return *this;
}
#if LLVM_HAS_RVALUE_REFERENCES
Regex(Regex &&regex) {
preg = regex.preg;
error = regex.error;
regex.preg = NULL;
}
#endif
~Regex();
/// isValid - returns the error encountered during regex compilation, or
@ -81,6 +95,9 @@ namespace llvm {
/// expression that matches Str and only Str.
static bool isLiteralERE(StringRef Str);
/// \brief Turn String into a regex by escaping its special characters.
static std::string escape(StringRef String);
private:
struct llvm_regex *preg;
int error;

View File

@ -79,7 +79,7 @@ namespace llvm {
public:
friend struct TargetRegistry;
typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
StringRef TT);
@ -154,9 +154,8 @@ namespace llvm {
/// TargetRegistry.
Target *Next;
/// TripleMatchQualityFn - The target function for rating the match quality
/// of a triple.
TripleMatchQualityFnTy TripleMatchQualityFn;
/// The target function for checking if an architecture is supported.
ArchMatchFnTy ArchMatchFn;
/// Name - The target name.
const char *Name;
@ -578,14 +577,13 @@ namespace llvm {
/// @param Name - The target name. This should be a static string.
/// @param ShortDesc - A short target description. This should be a static
/// string.
/// @param TQualityFn - The triple match quality computation function for
/// this target.
/// @param ArchMatchFn - The arch match checking function for this target.
/// @param HasJIT - Whether the target supports JIT code
/// generation.
static void RegisterTarget(Target &T,
const char *Name,
const char *ShortDesc,
Target::TripleMatchQualityFnTy TQualityFn,
Target::ArchMatchFnTy ArchMatchFn,
bool HasJIT = false);
/// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
@ -831,15 +829,11 @@ namespace llvm {
bool HasJIT = false>
struct RegisterTarget {
RegisterTarget(Target &T, const char *Name, const char *Desc) {
TargetRegistry::RegisterTarget(T, Name, Desc,
&getTripleMatchQuality,
HasJIT);
TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
}
static unsigned getTripleMatchQuality(const std::string &TT) {
if (Triple(TT).getArch() == TargetArchType)
return 20;
return 0;
static bool getArchMatch(Triple::ArchType Arch) {
return Arch == TargetArchType;
}
};

View File

@ -18,7 +18,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
@ -45,6 +44,8 @@ template<class T>
struct MappingTraits {
// Must provide:
// static void mapping(IO &io, T &fields);
// Optionally may provide:
// static StringRef validate(IO &io, T &fields);
};
@ -227,6 +228,23 @@ public:
static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
};
// Test if MappingTraits<T>::validate() is defined on type T.
template <class T>
struct has_MappingValidateTraits
{
typedef StringRef (*Signature_validate)(class IO&, T&);
template <typename U>
static char test(SameType<Signature_validate, &U::validate>*);
template <typename U>
static double test(...);
public:
static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
};
// Test if SequenceTraits<T> is defined on type T.
template <class T>
@ -310,7 +328,15 @@ struct missingTraits : public llvm::integral_constant<bool,
&& !has_SequenceTraits<T>::value
&& !has_DocumentListTraits<T>::value > {};
template<typename T>
struct validatedMappingTraits : public llvm::integral_constant<bool,
has_MappingTraits<T>::value
&& has_MappingValidateTraits<T>::value> {};
template<typename T>
struct unvalidatedMappingTraits : public llvm::integral_constant<bool,
has_MappingTraits<T>::value
&& !has_MappingValidateTraits<T>::value> {};
// Base class for Input and Output.
class IO {
public:
@ -318,7 +344,7 @@ public:
IO(void *Ctxt=NULL);
virtual ~IO();
virtual bool outputting() const = 0;
virtual bool outputting() = 0;
virtual unsigned beginSequence() = 0;
virtual bool preflightElement(unsigned, void *&) = 0;
@ -484,7 +510,27 @@ yamlize(IO &io, T &Val, bool) {
template<typename T>
typename llvm::enable_if_c<has_MappingTraits<T>::value, void>::type
typename llvm::enable_if_c<validatedMappingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
io.beginMapping();
if (io.outputting()) {
StringRef Err = MappingTraits<T>::validate(io, Val);
if (!Err.empty()) {
llvm::errs() << Err << "\n";
assert(Err.empty() && "invalid struct trying to be written as yaml");
}
}
MappingTraits<T>::mapping(io, Val);
if (!io.outputting()) {
StringRef Err = MappingTraits<T>::validate(io, Val);
if (!Err.empty())
io.setError(Err);
}
io.endMapping();
}
template<typename T>
typename llvm::enable_if_c<unvalidatedMappingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
io.beginMapping();
MappingTraits<T>::mapping(io, Val);
@ -538,6 +584,12 @@ struct ScalarTraits<StringRef> {
static void output(const StringRef &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, StringRef &);
};
template<>
struct ScalarTraits<std::string> {
static void output(const std::string &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, std::string &);
};
template<>
struct ScalarTraits<uint8_t> {
@ -697,10 +749,8 @@ public:
// Check if there was an syntax or semantic error during parsing.
llvm::error_code error();
static bool classof(const IO *io) { return !io->outputting(); }
private:
virtual bool outputting() const;
virtual bool outputting();
virtual bool mapTag(StringRef, bool);
virtual void beginMapping();
virtual void endMapping();
@ -825,9 +875,7 @@ public:
Output(llvm::raw_ostream &, void *Ctxt=NULL);
virtual ~Output();
static bool classof(const IO *io) { return io->outputting(); }
virtual bool outputting() const;
virtual bool outputting();
virtual bool mapTag(StringRef, bool);
virtual void beginMapping();
virtual void endMapping();

View File

@ -111,7 +111,6 @@ public:
bool BBVectorize;
bool SLPVectorize;
bool LoopVectorize;
bool LateVectorize;
bool RerollLoops;
private:

View File

@ -370,6 +370,12 @@ FunctionPass *createPartiallyInlineLibCallsPass();
FunctionPass *createSampleProfileLoaderPass();
FunctionPass *createSampleProfileLoaderPass(StringRef Name);
//===----------------------------------------------------------------------===//
//
// ScalarizerPass - Converts vector operations into scalar operations
//
FunctionPass *createScalarizerPass();
} // End llvm namespace
#endif

View File

@ -0,0 +1,64 @@
//===- ASanStackFrameLayout.h - ComputeASanStackFrameLayout -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header defines ComputeASanStackFrameLayout and auxilary data structs.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
#define LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
namespace llvm {
class AllocaInst;
// These magic constants should be the same as in
// in asan_internal.h from ASan runtime in compiler-rt.
static const int kAsanStackLeftRedzoneMagic = 0xf1;
static const int kAsanStackMidRedzoneMagic = 0xf2;
static const int kAsanStackRightRedzoneMagic = 0xf3;
// Input/output data struct for ComputeASanStackFrameLayout.
struct ASanStackVariableDescription {
const char *Name; // Name of the variable that will be displayed by asan
// if a stack-related bug is reported.
uint64_t Size; // Size of the variable in bytes.
size_t Alignment; // Alignment of the variable (power of 2).
AllocaInst *AI; // The actual AllocaInst.
size_t Offset; // Offset from the beginning of the frame;
// set by ComputeASanStackFrameLayout.
};
// Output data struct for ComputeASanStackFrameLayout.
struct ASanStackFrameLayout {
// Frame description, see DescribeAddressIfStack in ASan runtime.
SmallString<64> DescriptionString;
// The contents of the shadow memory for the stack frame that we need
// to set at function entry.
SmallVector<uint8_t, 64> ShadowBytes;
size_t FrameAlignment; // Alignment for the entire frame.
size_t FrameSize; // Size of the frame in bytes.
};
void ComputeASanStackFrameLayout(
// The array of stack variables. The elements may get reordered and changed.
SmallVectorImpl<ASanStackVariableDescription> &Vars,
// AddressSanitizer's shadow granularity. Usually 8, may also be 16, 32, 64.
size_t Granularity,
// The minimal size of the left-most redzone (header).
// At least 4 pointer sizes, power of 2, and >= Granularity.
// The resulting FrameSize should be multiple of MinHeaderSize.
size_t MinHeaderSize,
// The result is put here.
ASanStackFrameLayout *Layout);
} // llvm namespace
#endif // LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H

View File

@ -183,27 +183,47 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
BasicBlock *Pred);
/// SplitBlockAndInsertIfThen - Split the containing block at the
/// specified instruction - everything before and including Cmp stays
/// in the old basic block, and everything after Cmp is moved to a
/// specified instruction - everything before and including SplitBefore stays
/// in the old basic block, and everything after SplitBefore is moved to a
/// new block. The two blocks are connected by a conditional branch
/// (with value of Cmp being the condition).
/// Before:
/// Head
/// Cmp
/// SplitBefore
/// Tail
/// After:
/// Head
/// Cmp
/// if (Cmp)
/// if (Cond)
/// ThenBlock
/// SplitBefore
/// Tail
///
/// If Unreachable is true, then ThenBlock ends with
/// UnreachableInst, otherwise it branches to Tail.
/// Returns the NewBasicBlock's terminator.
TerminatorInst *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
bool Unreachable,
MDNode *BranchWeights = 0);
TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
bool Unreachable, MDNode *BranchWeights = 0);
/// SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen,
/// but also creates the ElseBlock.
/// Before:
/// Head
/// SplitBefore
/// Tail
/// After:
/// Head
/// if (Cond)
/// ThenBlock
/// else
/// ElseBlock
/// SplitBefore
/// Tail
void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
TerminatorInst **ThenTerm,
TerminatorInst **ElseTerm,
MDNode *BranchWeights = 0);
///
/// GetIfCondition - Check whether BB is the merge point of a if-region.
@ -211,7 +231,6 @@ TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
/// BB will be taken. Also, return by references the block that will be
/// entered from if the condition is true, and the block that will be
/// entered if the condition is false.
Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
BasicBlock *&IfFalse);
} // End llvm namespace

View File

@ -83,6 +83,14 @@ namespace llvm {
Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
const AttributeSet &Attrs);
/// EmitUnaryFloatFnCall - Emit a call to the binary function named 'Name'
/// (e.g. 'fmin'). This function is known to take type matching 'Op1' and
/// 'Op2' and return one value with the same type. If 'Op1/Op2' are long
/// double, 'l' is added as the suffix of name, if 'Op1/Op2' are float, we
/// add a 'f' suffix.
Value *EmitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
IRBuilder<> &B, const AttributeSet &Attrs);
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,

View File

@ -1,4 +1,4 @@
//===-- CmpInstAnalysis.h - Utils to help fold compare insts ------===//
//===-- CmpInstAnalysis.h - Utils to help fold compare insts ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//

View File

@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
// This file contains an implementation of 32bit integer division for targets
// that don't have native support. It's largely derived from compiler-rt's
// implementation of __udivsi3, but hand-tuned for targets that prefer less
// control flow.
// This file contains an implementation of 32bit and 64bit scalar integer
// division for targets that don't have native support. It's largely derived
// from compiler-rt's implementations of __udivsi3 and __udivmoddi4,
// but hand-tuned for targets that prefer less control flow.
//
//===----------------------------------------------------------------------===//
@ -26,9 +26,8 @@ namespace llvm {
/// Generate code to calculate the remainder of two integers, replacing Rem
/// with the generated code. This currently generates code using the udiv
/// expansion, but future work includes generating more specialized code,
/// e.g. when more information about the operands are known. Currently only
/// implements 32bit scalar division (due to udiv's limitation), but future
/// work is removing this limitation.
/// e.g. when more information about the operands are known. Implements both
/// 32bit and 64bit scalar division.
///
/// @brief Replace Rem with generated code.
bool expandRemainder(BinaryOperator *Rem);
@ -36,27 +35,39 @@ namespace llvm {
/// Generate code to divide two integers, replacing Div with the generated
/// code. This currently generates code similarly to compiler-rt's
/// implementations, but future work includes generating more specialized code
/// when more information about the operands are known. Currently only
/// implements 32bit scalar division, but future work is removing this
/// limitation.
/// when more information about the operands are known. Implements both
/// 32bit and 64bit scalar division.
///
/// @brief Replace Div with generated code.
bool expandDivision(BinaryOperator* Div);
/// Generate code to calculate the remainder of two integers, replacing Rem
/// with the generated code. Uses the above 32bit routine, therefore adequate
/// for targets with little or no support for less than 32 bit arithmetic.
/// with the generated code. Uses ExpandReminder with a 32bit Rem which
/// makes it useful for targets with little or no support for less than
/// 32 bit arithmetic.
///
/// @brief Replace Rem with generated code.
bool expandRemainderUpTo32Bits(BinaryOperator *Rem);
/// Generate code to calculate the remainder of two integers, replacing Rem
/// with the generated code. Uses ExpandReminder with a 64bit Rem.
///
/// @brief Replace Rem with generated code.
bool expandRemainderUpTo64Bits(BinaryOperator *Rem);
/// Generate code to divide two integers, replacing Div with the generated
/// code. Uses the above 32bit routine, therefore adequate for targets with
/// little or no support for less than 32 bit arithmetic.
/// code. Uses ExpandDivision with a 32bit Div which makes it useful for
/// targets with little or no support for less than 32 bit arithmetic.
///
/// @brief Replace Rem with generated code.
bool expandDivisionUpTo32Bits(BinaryOperator *Div);
/// Generate code to divide two integers, replacing Div with the generated
/// code. Uses ExpandDivision with a 64bit Div.
///
/// @brief Replace Rem with generated code.
bool expandDivisionUpTo64Bits(BinaryOperator *Div);
} // End llvm namespace
#endif

View File

@ -22,6 +22,7 @@
namespace llvm {
class CastInst;
class DominatorTree;
class IVUsers;
class Loop;
class LPPassManager;
@ -31,9 +32,25 @@ class ScalarEvolution;
/// Interface for visiting interesting IV users that are recognized but not
/// simplified by this utility.
class IVVisitor {
protected:
const DominatorTree *DT;
bool ShouldSplitOverflowIntrinsics;
virtual void anchor();
public:
IVVisitor(): DT(NULL), ShouldSplitOverflowIntrinsics(false) {}
virtual ~IVVisitor() {}
const DominatorTree *getDomTree() const { return DT; }
bool shouldSplitOverflowInstrinsics() const {
return ShouldSplitOverflowIntrinsics;
}
void setSplitOverflowIntrinsics() {
ShouldSplitOverflowIntrinsics = true;
assert(DT && "Splitting overflow intrinsics requires a DomTree.");
}
virtual void visitCast(CastInst *Cast) = 0;
};

View File

@ -43,7 +43,9 @@
// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H
#define LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H
#include "llvm/ADT/StringMap.h"
@ -108,3 +110,5 @@ class SpecialCaseList {
};
} // namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H

View File

@ -114,7 +114,8 @@ createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
//
// LoopVectorize - Create a loop vectorization pass.
//
Pass *createLoopVectorizePass(bool NoUnrolling = false);
Pass *createLoopVectorizePass(bool NoUnrolling = false,
bool AlwaysVectorize = true);
//===----------------------------------------------------------------------===//
//