Import LLVM 3.5svn r198450.
This commit is contained in:
parent
eaac9e3d28
commit
d149ea39d0
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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@)
|
||||
|
|
|
@ -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.")
|
||||
|
||||
|
|
|
@ -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'`\\"
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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]>;
|
||||
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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]>;
|
||||
|
|
|
@ -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]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) { };
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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 &®ex) {
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -111,7 +111,6 @@ public:
|
|||
bool BBVectorize;
|
||||
bool SLPVectorize;
|
||||
bool LoopVectorize;
|
||||
bool LateVectorize;
|
||||
bool RerollLoops;
|
||||
|
||||
private:
|
||||
|
|
|
@ -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
|
||||
|
|
64
external/bsd/llvm/dist/llvm/include/llvm/Transforms/Utils/ASanStackFrameLayout.h
vendored
Normal file
64
external/bsd/llvm/dist/llvm/include/llvm/Transforms/Utils/ASanStackFrameLayout.h
vendored
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue