Update LLVM to r90226.
This commit is contained in:
parent
bf68f1ea49
commit
e7908924d8
@ -191,6 +191,10 @@ set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib )
|
||||
add_llvm_definitions( -D__STDC_LIMIT_MACROS )
|
||||
add_llvm_definitions( -D__STDC_CONSTANT_MACROS )
|
||||
|
||||
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
|
||||
option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
|
||||
option(LLVM_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
|
||||
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
|
||||
# TODO: support other platforms and toolchains.
|
||||
option(LLVM_BUILD_32_BITS "Build 32 bits executables and libraries." OFF)
|
||||
@ -226,6 +230,27 @@ if( MSVC )
|
||||
add_llvm_definitions("/${LLVM_USE_CRT}")
|
||||
message(STATUS "Using VC++ CRT: ${LLVM_USE_CRT}")
|
||||
endif (NOT ${LLVM_USE_CRT} STREQUAL "")
|
||||
|
||||
# Enable warnings
|
||||
if (LLVM_ENABLE_WARNINGS)
|
||||
add_llvm_definitions( /W4 /Wall )
|
||||
if (LLVM_ENABLE_PEDANTIC)
|
||||
# No MSVC equivalent available
|
||||
endif (LLVM_ENABLE_PEDANTIC)
|
||||
endif (LLVM_ENABLE_WARNINGS)
|
||||
if (LLVM_ENABLE_WERROR)
|
||||
add_llvm_definitions( /WX )
|
||||
endif (LLVM_ENABLE_WERROR)
|
||||
elseif( CMAKE_COMPILER_IS_GNUCXX )
|
||||
if (LLVM_ENABLE_WARNINGS)
|
||||
add_llvm_definitions( -Wall -W -Wno-unused-parameter -Wwrite-strings )
|
||||
if (LLVM_ENABLE_PEDANTIC)
|
||||
add_llvm_definitions( -pedantic -Wno-long-long )
|
||||
endif (LLVM_ENABLE_PEDANTIC)
|
||||
endif (LLVM_ENABLE_WARNINGS)
|
||||
if (LLVM_ENABLE_WERROR)
|
||||
add_llvm_definitions( -Werror )
|
||||
endif (LLVM_ENABLE_WERROR)
|
||||
endif( MSVC )
|
||||
|
||||
include_directories( ${LLVM_BINARY_DIR}/include ${LLVM_MAIN_INCLUDE_DIR})
|
||||
@ -280,6 +305,7 @@ add_subdirectory(utils/not)
|
||||
|
||||
set(LLVM_ENUM_ASM_PRINTERS "")
|
||||
set(LLVM_ENUM_ASM_PARSERS "")
|
||||
set(LLVM_ENUM_DISASSEMBLERS "")
|
||||
foreach(t ${LLVM_TARGETS_TO_BUILD})
|
||||
message(STATUS "Targeting ${t}")
|
||||
add_subdirectory(lib/Target/${t})
|
||||
@ -294,6 +320,11 @@ foreach(t ${LLVM_TARGETS_TO_BUILD})
|
||||
set(LLVM_ENUM_ASM_PARSERS
|
||||
"${LLVM_ENUM_ASM_PARSERS}LLVM_ASM_PARSER(${t})\n")
|
||||
endif( EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Target/${t}/AsmParser/CMakeLists.txt )
|
||||
if( EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Target/${t}/Disassembler/CMakeLists.txt )
|
||||
add_subdirectory(lib/Target/${t}/Disassembler)
|
||||
set(LLVM_ENUM_DISASSEMBLERS
|
||||
"${LLVM_ENUM_DISASSEMBLERS}LLVM_DISASSEMBLER(${t})\n")
|
||||
endif( EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Target/${t}/Disassembler/CMakeLists.txt )
|
||||
set(CURRENT_LLVM_TARGET)
|
||||
endforeach(t)
|
||||
|
||||
@ -309,6 +340,12 @@ configure_file(
|
||||
${LLVM_BINARY_DIR}/include/llvm/Config/AsmParsers.def
|
||||
)
|
||||
|
||||
# Produce llvm/Config/Disassemblers.def
|
||||
configure_file(
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/Disassemblers.def.in
|
||||
${LLVM_BINARY_DIR}/include/llvm/Config/Disassemblers.def
|
||||
)
|
||||
|
||||
add_subdirectory(lib/ExecutionEngine)
|
||||
add_subdirectory(lib/ExecutionEngine/Interpreter)
|
||||
add_subdirectory(lib/ExecutionEngine/JIT)
|
||||
@ -319,14 +356,10 @@ add_subdirectory(lib/Archive)
|
||||
add_subdirectory(projects)
|
||||
|
||||
option(LLVM_BUILD_TOOLS "Build LLVM tool programs." ON)
|
||||
if(LLVM_BUILD_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
add_subdirectory(tools)
|
||||
|
||||
option(LLVM_BUILD_EXAMPLES "Build LLVM example programs." OFF)
|
||||
if(LLVM_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif ()
|
||||
add_subdirectory(examples)
|
||||
|
||||
install(DIRECTORY include/
|
||||
DESTINATION include
|
||||
|
6
Makefile
6
Makefile
@ -155,9 +155,11 @@ install-libs: install
|
||||
FilesToConfig := \
|
||||
include/llvm/Config/config.h \
|
||||
include/llvm/Config/Targets.def \
|
||||
include/llvm/Config/AsmPrinters.def \
|
||||
include/llvm/Config/AsmPrinters.def \
|
||||
include/llvm/Config/AsmParsers.def \
|
||||
include/llvm/Config/Disassemblers.def \
|
||||
include/llvm/System/DataTypes.h \
|
||||
tools/llvmc/plugins/Base/Base.td
|
||||
tools/llvmc/plugins/Base/Base.td
|
||||
FilesToConfigPATH := $(addprefix $(LLVM_OBJ_ROOT)/,$(FilesToConfig))
|
||||
|
||||
all-local:: $(FilesToConfigPATH)
|
||||
|
@ -1565,6 +1565,11 @@ $(ObjDir)/%GenDAGISel.inc.tmp : %.td $(ObjDir)/.dir
|
||||
$(Echo) "Building $(<F) DAG instruction selector implementation with tblgen"
|
||||
$(Verb) $(TableGen) -gen-dag-isel -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(TARGET:%=$(ObjDir)/%GenDisassemblerTables.inc.tmp): \
|
||||
$(ObjDir)/%GenDisassemblerTables.inc.tmp : %.td $(ObjDir)/.dir
|
||||
$(Echo) "Building $(<F) disassembly tables with tblgen"
|
||||
$(Verb) $(TableGen) -gen-disassembler -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(TARGET:%=$(ObjDir)/%GenFastISel.inc.tmp): \
|
||||
$(ObjDir)/%GenFastISel.inc.tmp : %.td $(ObjDir)/.dir
|
||||
$(Echo) "Building $(<F) \"fast\" instruction selector implementation with tblgen"
|
||||
|
@ -533,11 +533,12 @@ for a_target in $TARGETS_TO_BUILD; do
|
||||
fi
|
||||
done
|
||||
|
||||
# Build the LLVM_TARGET and LLVM_ASM_PRINTER macro uses for
|
||||
# Targets.def, AsmPrinters.def, and AsmParsers.def.
|
||||
# Build the LLVM_TARGET and LLVM_... macros for Targets.def and the individual
|
||||
# target feature def files.
|
||||
LLVM_ENUM_TARGETS=""
|
||||
LLVM_ENUM_ASM_PRINTERS=""
|
||||
LLVM_ENUM_ASM_PARSERS=""
|
||||
LLVM_ENUM_DISASSEMBLERS=""
|
||||
for target_to_build in $TARGETS_TO_BUILD; do
|
||||
LLVM_ENUM_TARGETS="LLVM_TARGET($target_to_build) $LLVM_ENUM_TARGETS"
|
||||
if test -f ${srcdir}/lib/Target/${target_to_build}/AsmPrinter/Makefile ; then
|
||||
@ -546,10 +547,14 @@ for target_to_build in $TARGETS_TO_BUILD; do
|
||||
if test -f ${srcdir}/lib/Target/${target_to_build}/AsmParser/Makefile ; then
|
||||
LLVM_ENUM_ASM_PARSERS="LLVM_ASM_PARSER($target_to_build) $LLVM_ENUM_ASM_PARSERS";
|
||||
fi
|
||||
if test -f ${srcdir}/lib/Target/${target_to_build}/Disassembler/Makefile ; then
|
||||
LLVM_ENUM_DISASSEMBLERS="LLVM_DISASSEMBLER($target_to_build) $LLVM_ENUM_DISASSEMBLERS";
|
||||
fi
|
||||
done
|
||||
AC_SUBST(LLVM_ENUM_TARGETS)
|
||||
AC_SUBST(LLVM_ENUM_ASM_PRINTERS)
|
||||
AC_SUBST(LLVM_ENUM_ASM_PARSERS)
|
||||
AC_SUBST(LLVM_ENUM_DISASSEMBLERS)
|
||||
|
||||
dnl Prevent the CBackend from using printf("%a") for floating point so older
|
||||
dnl C compilers that cannot deal with the 0x0p+0 hex floating point format
|
||||
@ -1407,6 +1412,7 @@ AC_CONFIG_HEADERS([include/llvm/Config/config.h])
|
||||
AC_CONFIG_FILES([include/llvm/Config/Targets.def])
|
||||
AC_CONFIG_FILES([include/llvm/Config/AsmPrinters.def])
|
||||
AC_CONFIG_FILES([include/llvm/Config/AsmParsers.def])
|
||||
AC_CONFIG_FILES([include/llvm/Config/Disassemblers.def])
|
||||
AC_CONFIG_HEADERS([include/llvm/System/DataTypes.h])
|
||||
|
||||
dnl Configure the makefile's configuration data
|
||||
|
@ -46,7 +46,12 @@ endmacro(add_llvm_loadable_module name)
|
||||
|
||||
macro(add_llvm_executable name)
|
||||
llvm_process_sources( ALL_FILES ${ARGN} )
|
||||
add_executable(${name} ${ALL_FILES})
|
||||
if( EXCLUDE_FROM_ALL )
|
||||
add_executable(${name} EXCLUDE_FROM_ALL ${ALL_FILES})
|
||||
else()
|
||||
add_executable(${name} ${ALL_FILES})
|
||||
endif()
|
||||
set(EXCLUDE_FROM_ALL OFF)
|
||||
if( LLVM_USED_LIBS )
|
||||
foreach(lib ${LLVM_USED_LIBS})
|
||||
target_link_libraries( ${name} ${lib} )
|
||||
@ -67,17 +72,25 @@ endmacro(add_llvm_executable name)
|
||||
|
||||
macro(add_llvm_tool name)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR})
|
||||
if( NOT LLVM_BUILD_TOOLS )
|
||||
set(EXCLUDE_FROM_ALL ON)
|
||||
endif()
|
||||
add_llvm_executable(${name} ${ARGN})
|
||||
install(TARGETS ${name}
|
||||
RUNTIME DESTINATION bin)
|
||||
if( LLVM_BUILD_TOOLS )
|
||||
install(TARGETS ${name} RUNTIME DESTINATION bin)
|
||||
endif()
|
||||
endmacro(add_llvm_tool name)
|
||||
|
||||
|
||||
macro(add_llvm_example name)
|
||||
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_EXAMPLES_BINARY_DIR})
|
||||
if( NOT LLVM_BUILD_EXAMPLES )
|
||||
set(EXCLUDE_FROM_ALL ON)
|
||||
endif()
|
||||
add_llvm_executable(${name} ${ARGN})
|
||||
install(TARGETS ${name}
|
||||
RUNTIME DESTINATION examples)
|
||||
if( LLVM_BUILD_EXAMPLES )
|
||||
install(TARGETS ${name} RUNTIME DESTINATION examples)
|
||||
endif()
|
||||
endmacro(add_llvm_example name)
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@ function(get_system_libs return_var)
|
||||
set(system_libs ${system_libs} imagehlp psapi)
|
||||
elseif( CMAKE_HOST_UNIX )
|
||||
if( HAVE_LIBDL )
|
||||
set(system_libs ${system_libs} dl)
|
||||
set(system_libs ${system_libs} ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
|
||||
set(system_libs ${system_libs} pthread)
|
||||
@ -32,7 +32,7 @@ endfunction(explicit_llvm_config)
|
||||
function(explicit_map_components_to_libraries out_libs)
|
||||
set( link_components ${ARGN} )
|
||||
foreach(c ${link_components})
|
||||
# add codegen, asmprinter, asmparser
|
||||
# add codegen, asmprinter, asmparser, disassembler
|
||||
list(FIND LLVM_TARGETS_TO_BUILD ${c} idx)
|
||||
if( NOT idx LESS 0 )
|
||||
list(FIND llvm_libs "LLVM${c}CodeGen" idx)
|
||||
@ -58,6 +58,10 @@ function(explicit_map_components_to_libraries out_libs)
|
||||
if( NOT asmidx LESS 0 )
|
||||
list(APPEND expanded_components "LLVM${c}Info")
|
||||
endif()
|
||||
list(FIND llvm_libs "LLVM${c}Disassembler" asmidx)
|
||||
if( NOT asmidx LESS 0 )
|
||||
list(APPEND expanded_components "LLVM${c}Disassembler")
|
||||
endif()
|
||||
elseif( c STREQUAL "native" )
|
||||
list(APPEND expanded_components "LLVM${LLVM_NATIVE_ARCH}CodeGen")
|
||||
elseif( c STREQUAL "nativecodegen" )
|
||||
|
@ -58,6 +58,7 @@ set(MSVC_LIB_DEPS_LLVMTransformUtils LLVMAnalysis LLVMCore LLVMSupport LLVMSyste
|
||||
set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget LLVMX86CodeGen LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86Disassembler LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86Info LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMXCore LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMXCoreInfo)
|
||||
set(MSVC_LIB_DEPS_LLVMXCoreAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget LLVMXCoreInfo)
|
||||
|
72
configure
vendored
72
configure
vendored
@ -847,6 +847,7 @@ TARGETS_TO_BUILD
|
||||
LLVM_ENUM_TARGETS
|
||||
LLVM_ENUM_ASM_PRINTERS
|
||||
LLVM_ENUM_ASM_PARSERS
|
||||
LLVM_ENUM_DISASSEMBLERS
|
||||
ENABLE_CBE_PRINTF_A
|
||||
OPTIMIZE_OPTION
|
||||
EXTRA_OPTIONS
|
||||
@ -5108,11 +5109,12 @@ _ACEOF
|
||||
fi
|
||||
done
|
||||
|
||||
# Build the LLVM_TARGET and LLVM_ASM_PRINTER macro uses for
|
||||
# Targets.def, AsmPrinters.def, and AsmParsers.def.
|
||||
# Build the LLVM_TARGET and LLVM_... macros for Targets.def and the individual
|
||||
# target feature def files.
|
||||
LLVM_ENUM_TARGETS=""
|
||||
LLVM_ENUM_ASM_PRINTERS=""
|
||||
LLVM_ENUM_ASM_PARSERS=""
|
||||
LLVM_ENUM_DISASSEMBLERS=""
|
||||
for target_to_build in $TARGETS_TO_BUILD; do
|
||||
LLVM_ENUM_TARGETS="LLVM_TARGET($target_to_build) $LLVM_ENUM_TARGETS"
|
||||
if test -f ${srcdir}/lib/Target/${target_to_build}/AsmPrinter/Makefile ; then
|
||||
@ -5121,11 +5123,15 @@ for target_to_build in $TARGETS_TO_BUILD; do
|
||||
if test -f ${srcdir}/lib/Target/${target_to_build}/AsmParser/Makefile ; then
|
||||
LLVM_ENUM_ASM_PARSERS="LLVM_ASM_PARSER($target_to_build) $LLVM_ENUM_ASM_PARSERS";
|
||||
fi
|
||||
if test -f ${srcdir}/lib/Target/${target_to_build}/Disassembler/Makefile ; then
|
||||
LLVM_ENUM_DISASSEMBLERS="LLVM_DISASSEMBLER($target_to_build) $LLVM_ENUM_DISASSEMBLERS";
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Check whether --enable-cbe-printf-a was given.
|
||||
if test "${enable_cbe_printf_a+set}" = set; then
|
||||
enableval=$enable_cbe_printf_a;
|
||||
@ -11114,7 +11120,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 11117 "configure"
|
||||
#line 11123 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -13258,7 +13264,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 13261 "configure"' > conftest.$ac_ext
|
||||
echo '#line 13267 "configure"' > conftest.$ac_ext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@ -14976,11 +14982,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:14979: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:14985: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:14983: \$? = $ac_status" >&5
|
||||
echo "$as_me:14989: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -15244,11 +15250,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15247: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15253: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15251: \$? = $ac_status" >&5
|
||||
echo "$as_me:15257: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -15348,11 +15354,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15351: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15357: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:15355: \$? = $ac_status" >&5
|
||||
echo "$as_me:15361: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -17800,7 +17806,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17803 "configure"
|
||||
#line 17809 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -17900,7 +17906,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17903 "configure"
|
||||
#line 17909 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -20268,11 +20274,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:20271: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:20277: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:20275: \$? = $ac_status" >&5
|
||||
echo "$as_me:20281: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -20372,11 +20378,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:20375: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:20381: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:20379: \$? = $ac_status" >&5
|
||||
echo "$as_me:20385: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -21942,11 +21948,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:21945: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:21951: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:21949: \$? = $ac_status" >&5
|
||||
echo "$as_me:21955: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -22046,11 +22052,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:22049: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:22055: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:22053: \$? = $ac_status" >&5
|
||||
echo "$as_me:22059: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -24281,11 +24287,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:24284: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:24290: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:24288: \$? = $ac_status" >&5
|
||||
echo "$as_me:24294: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -24549,11 +24555,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:24552: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:24558: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:24556: \$? = $ac_status" >&5
|
||||
echo "$as_me:24562: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -24653,11 +24659,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:24656: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:24662: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:24660: \$? = $ac_status" >&5
|
||||
echo "$as_me:24666: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -35375,6 +35381,8 @@ ac_config_files="$ac_config_files include/llvm/Config/AsmPrinters.def"
|
||||
|
||||
ac_config_files="$ac_config_files include/llvm/Config/AsmParsers.def"
|
||||
|
||||
ac_config_files="$ac_config_files include/llvm/Config/Disassemblers.def"
|
||||
|
||||
ac_config_headers="$ac_config_headers include/llvm/System/DataTypes.h"
|
||||
|
||||
|
||||
@ -36002,6 +36010,7 @@ do
|
||||
"include/llvm/Config/Targets.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/Targets.def" ;;
|
||||
"include/llvm/Config/AsmPrinters.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/AsmPrinters.def" ;;
|
||||
"include/llvm/Config/AsmParsers.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/AsmParsers.def" ;;
|
||||
"include/llvm/Config/Disassemblers.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/Disassemblers.def" ;;
|
||||
"include/llvm/System/DataTypes.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/System/DataTypes.h" ;;
|
||||
"Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
|
||||
"llvm.spec") CONFIG_FILES="$CONFIG_FILES llvm.spec" ;;
|
||||
@ -36175,12 +36184,12 @@ TARGETS_TO_BUILD!$TARGETS_TO_BUILD$ac_delim
|
||||
LLVM_ENUM_TARGETS!$LLVM_ENUM_TARGETS$ac_delim
|
||||
LLVM_ENUM_ASM_PRINTERS!$LLVM_ENUM_ASM_PRINTERS$ac_delim
|
||||
LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim
|
||||
LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim
|
||||
ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim
|
||||
OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim
|
||||
EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim
|
||||
BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim
|
||||
ENABLE_LLVMC_DYNAMIC!$ENABLE_LLVMC_DYNAMIC$ac_delim
|
||||
ENABLE_LLVMC_DYNAMIC_PLUGINS!$ENABLE_LLVMC_DYNAMIC_PLUGINS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
|
||||
@ -36222,6 +36231,7 @@ _ACEOF
|
||||
ac_delim='%!_!# '
|
||||
for ac_last_try in false false false false false :; do
|
||||
cat >conf$$subs.sed <<_ACEOF
|
||||
ENABLE_LLVMC_DYNAMIC_PLUGINS!$ENABLE_LLVMC_DYNAMIC_PLUGINS$ac_delim
|
||||
CXX!$CXX$ac_delim
|
||||
CXXFLAGS!$CXXFLAGS$ac_delim
|
||||
ac_ct_CXX!$ac_ct_CXX$ac_delim
|
||||
@ -36319,7 +36329,7 @@ LIBOBJS!$LIBOBJS$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 95; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 96; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
@ -36338,7 +36348,7 @@ fi
|
||||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
|
||||
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
|
||||
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
|
||||
_ACEOF
|
||||
sed '
|
||||
s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
|
||||
@ -36351,8 +36361,6 @@ N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
|
||||
' >>$CONFIG_STATUS <conf$$subs.sed
|
||||
rm -f conf$$subs.sed
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
:end
|
||||
s/|#_!!_#|//g
|
||||
CEOF$ac_eof
|
||||
_ACEOF
|
||||
|
||||
@ -36600,7 +36608,7 @@ s&@abs_builddir@&$ac_abs_builddir&;t t
|
||||
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
|
||||
s&@INSTALL@&$ac_INSTALL&;t t
|
||||
$ac_datarootdir_hack
|
||||
" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out
|
||||
" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" | sed 's/|#_!!_#|//g' >$tmp/out
|
||||
|
||||
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
|
||||
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
|
||||
|
@ -225,12 +225,7 @@ method for testing dependencies between function calls. This method takes two
|
||||
call sites (CS1 & CS2), returns NoModRef if the two calls refer to disjoint
|
||||
memory locations, Ref if CS1 reads memory written by CS2, Mod if CS1 writes to
|
||||
memory read or written by CS2, or ModRef if CS1 might read or write memory
|
||||
accessed by CS2. Note that this relation is not commutative. Clients that use
|
||||
this method should be predicated on the <tt>hasNoModRefInfoForCalls()</tt>
|
||||
method, which indicates whether or not an analysis can provide mod/ref
|
||||
information for function call pairs (most can not). If this predicate is false,
|
||||
the client shouldn't waste analysis time querying the <tt>getModRefInfo</tt>
|
||||
method many times.</p>
|
||||
accessed by CS2. Note that this relation is not commutative.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -249,21 +244,6 @@ analysis implementations and can be put to good use by various clients.
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
The <tt>getMustAliases</tt> method
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>getMustAliases</tt> method returns all values that are known to
|
||||
always must alias a pointer. This information can be provided in some cases for
|
||||
important objects like the null pointer and global values. Knowing that a
|
||||
pointer always points to a particular function allows indirect calls to be
|
||||
turned into direct calls, for example.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
The <tt>pointsToConstantMemory</tt> method
|
||||
@ -969,7 +949,7 @@ analysis directly.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-04-25 23:11:37 +0200 (Sat, 25 Apr 2009) $
|
||||
Last modified: $Date: 2009-11-22 17:01:44 +0100 (Sun, 22 Nov 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -251,10 +251,16 @@
|
||||
<i>-DLLVM_TARGETS_TO_BUILD="X86;PowerPC;Alpha"</i>.</dd>
|
||||
|
||||
<dt><b>LLVM_BUILD_TOOLS</b>:BOOL</dt>
|
||||
<dd>Build LLVM tools. Defaults to ON.</dd>
|
||||
<dd>Build LLVM tools. Defaults to ON. Targets for building each tool
|
||||
are generated in any case. You can build an tool separately by
|
||||
invoking its target. For example, you can build <i>llvm-as</i>
|
||||
with a makefile-based system executing <i>make llvm-as</i> on the
|
||||
root of your build directory.</dd>
|
||||
|
||||
<dt><b>LLVM_BUILD_EXAMPLES</b>:BOOL</dt>
|
||||
<dd>Build LLVM examples. Defaults to ON.</dd>
|
||||
<dd>Build LLVM examples. Defaults to OFF. Targets for building each
|
||||
example are generated in any case. See documentation
|
||||
for <i>LLVM_BUILD_TOOLS</i> above for more details.</dd>
|
||||
|
||||
<dt><b>LLVM_ENABLE_THREADS</b>:BOOL</dt>
|
||||
<dd>Build with threads support, if available. Defaults to ON.</dd>
|
||||
@ -268,10 +274,21 @@
|
||||
compiler supports this flag. Some systems, like Windows, do not
|
||||
need this flag. Defaults to ON.</dd>
|
||||
|
||||
<dt><b>LLVM_ENABLE_WARNINGS</b>:BOOL</dt>
|
||||
<dd>Enable all compiler warnings. Defaults to ON.</dd>
|
||||
|
||||
<dt><b>LLVM_ENABLE_PEDANTIC</b>:BOOL</dt>
|
||||
<dd>Enable pedantic mode. This disable compiler specific extensions, is
|
||||
possible. Defaults to ON.</dd>
|
||||
|
||||
<dt><b>LLVM_ENABLE_WERROR</b>:BOOL</dt>
|
||||
<dd>Stop and fail build, if a compiler warning is
|
||||
triggered. Defaults to OFF.</dd>
|
||||
|
||||
<dt><b>LLVM_BUILD_32_BITS</b>:BOOL</dt>
|
||||
<dd>Build 32-bits executables and libraries on 64-bits systems. This
|
||||
option is available only on some 64-bits unix systems. Defaults to
|
||||
OFF.</dd>
|
||||
option is available only on some 64-bits unix systems. Defaults to
|
||||
OFF.</dd>
|
||||
|
||||
<dt><b>LLVM_TARGET_ARCH</b>:STRING</dt>
|
||||
<dd>LLVM target to use for native code generation. This is required
|
||||
|
@ -224,7 +224,7 @@ The first check line matches a regex (<tt>%[a-z]+</tt>) and captures it into
|
||||
the variables "REGISTER". The second line verifies that whatever is in REGISTER
|
||||
occurs later in the file after an "andw". FileCheck variable references are
|
||||
always contained in <tt>[[ ]]</tt> pairs, are named, and their names can be
|
||||
formed with the regex "<tt>[a-zA-Z][a-zA-Z0-9]*</tt>". If a colon follows the
|
||||
formed with the regex "<tt>[a-zA-Z_][a-zA-Z0-9_]*</tt>". If a colon follows the
|
||||
name, then it is a definition of the variable, if not, it is a use.
|
||||
|
||||
FileCheck variables can be defined multiple times, and uses always get the
|
||||
|
@ -126,24 +126,31 @@ use the B<-Wo,> option.
|
||||
|
||||
=item B<-I> I<directory>
|
||||
|
||||
Add a directory to the header file search path. This option can be
|
||||
repeated.
|
||||
Add a directory to the header file search path.
|
||||
|
||||
=item B<-L> I<directory>
|
||||
|
||||
Add I<directory> to the library search path. This option can be
|
||||
repeated.
|
||||
Add I<directory> to the library search path.
|
||||
|
||||
=item B<-F> I<directory>
|
||||
|
||||
Add I<directory> to the framework search path.
|
||||
|
||||
=item B<-l>I<name>
|
||||
|
||||
Link in the library libI<name>.[bc | a | so]. This library should
|
||||
be a bitcode library.
|
||||
|
||||
=item B<-framework> I<name>
|
||||
|
||||
Link in the library libI<name>.[bc | a | so]. This library should
|
||||
be a bitcode library.
|
||||
|
||||
=item B<-emit-llvm>
|
||||
|
||||
Make the output be LLVM bitcode (with B<-c>) or assembly (with B<-S>) instead
|
||||
of native object (or assembly). If B<-emit-llvm> is given without either B<-c>
|
||||
or B<-S> it has no effect.
|
||||
Output LLVM bitcode (with B<-c>) or assembly (with B<-S>) instead of native
|
||||
object (or assembly). If B<-emit-llvm> is given without either B<-c> or B<-S>
|
||||
it has no effect.
|
||||
|
||||
=item B<-Wa>
|
||||
|
||||
@ -157,6 +164,10 @@ Pass options to linker.
|
||||
|
||||
Pass options to opt.
|
||||
|
||||
=item B<-Wllc>
|
||||
|
||||
Pass options to llc (code generator).
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
@ -291,6 +291,8 @@
|
||||
'<tt>llvm.trap</tt>' Intrinsic</a></li>
|
||||
<li><a href="#int_stackprotector">
|
||||
'<tt>llvm.stackprotector</tt>' Intrinsic</a></li>
|
||||
<li><a href="#int_objectsize">
|
||||
'<tt>llvm.objectsize</tt>' Intrinsic</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
@ -1440,11 +1442,6 @@ Classifications</a> </div>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Note that the code generator does not yet support large integer types to be
|
||||
used as function return types. The specific limit on how large a return type
|
||||
the code generator can currently handle is target-dependent; currently it's
|
||||
often 64 bits for 32-bit targets and 128 bits for 64-bit targets.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
@ -1583,11 +1580,6 @@ Classifications</a> </div>
|
||||
length array type. An implementation of 'pascal style arrays' in LLVM could
|
||||
use the type "<tt>{ i32, [0 x float]}</tt>", for example.</p>
|
||||
|
||||
<p>Note that the code generator does not yet support large aggregate types to be
|
||||
used as function return types. The specific limit on how large an aggregate
|
||||
return type the code generator can currently handle is target-dependent, and
|
||||
also dependent on the aggregate element types.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
@ -1680,11 +1672,6 @@ Classifications</a> </div>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Note that the code generator does not yet support large aggregate types to be
|
||||
used as function return types. The specific limit on how large an aggregate
|
||||
return type the code generator can currently handle is target-dependent, and
|
||||
also dependent on the aggregate element types.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
@ -1775,8 +1762,7 @@ Classifications</a> </div>
|
||||
<p>A vector type is a simple derived type that represents a vector of elements.
|
||||
Vector types are used when multiple primitive data are operated in parallel
|
||||
using a single instruction (SIMD). A vector type requires a size (number of
|
||||
elements) and an underlying primitive data type. Vectors must have a power
|
||||
of two length (1, 2, 4, 8, 16 ...). Vector types are considered
|
||||
elements) and an underlying primitive data type. Vector types are considered
|
||||
<a href="#t_firstclass">first class</a>.</p>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
@ -1803,11 +1789,6 @@ Classifications</a> </div>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Note that the code generator does not yet support large vector types to be
|
||||
used as function return types. The specific limit on how large a vector
|
||||
return type codegen can currently handle is target-dependent; currently it's
|
||||
often a few times longer than a hardware vector register.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
@ -2600,14 +2581,6 @@ Instruction</a> </div>
|
||||
ret { i32, i8 } { i32 4, i8 2 } <i>; Return a struct of values 4 and 2</i>
|
||||
</pre>
|
||||
|
||||
<p>Note that the code generator does not yet fully support large
|
||||
return values. The specific sizes that are currently supported are
|
||||
dependent on the target. For integers, on 32-bit targets the limit
|
||||
is often 64 bits, and on 64-bit targets the limit is often 128 bits.
|
||||
For aggregate types, the current limits are dependent on the element
|
||||
types; for example targets are often limited to 2 total integer
|
||||
elements and 2 total floating-point elements.</p>
|
||||
|
||||
</div>
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="i_br">'<tt>br</tt>' Instruction</a> </div>
|
||||
@ -7275,6 +7248,41 @@ LLVM</a>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="int_objectsize">'<tt>llvm.objectsize</tt>' Intrinsic</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
declare i32 @llvm.objectsize.i32( i8* <ptr>, i32 <type> )
|
||||
declare i64 @llvm.objectsize.i64( i8* <ptr>, i32 <type> )
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The <tt>llvm.objectsize</tt> intrinsic returns the constant number of bytes
|
||||
from <tt>ptr</tt> to the end of the object <tt>ptr</tt> points to if it
|
||||
can deduce this at compile time. If there are any side-effects in evaluating
|
||||
the argument or it cannot deduce which objects <tt>ptr</tt> points to at compile
|
||||
time the intrinsic returns <tt>(size_t) -1</tt> for <tt>type</tt> 0
|
||||
or 1 and <tt>(size_t) 0</tt> for <tt>type</tt> 2 or 3.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The <tt>llvm.objectsize</tt> intrinsic takes two arguments. The first
|
||||
argument is a pointer to the object <tt>ptr</tt> and an integer <tt>type</tt>.
|
||||
<tt>type</tt> is an integer ranging from 0 to 3. The lsb corresponds to
|
||||
a return value based on whole objects, the second bit whether or not we
|
||||
return the maximum or minimum remaining bytes computed.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>The <tt>llvm.objectsize</tt> intrinsic is lowered to either a constant
|
||||
representing the size of the object concerned or <tt>(size_t) -1</tt> if
|
||||
it cannot be determined at compile time.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<hr>
|
||||
<address>
|
||||
@ -7285,7 +7293,7 @@ LLVM</a>.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-11-09 20:01:53 +0100 (Mon, 09 Nov 2009) $
|
||||
Last modified: $Date: 2009-11-30 09:03:53 +0100 (Mon, 30 Nov 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -37,15 +37,10 @@
|
||||
</ul></li>
|
||||
<li><a href="#format_common_intrinsics">Debugger intrinsic functions</a>
|
||||
<ul>
|
||||
<li><a href="#format_common_stoppoint">llvm.dbg.stoppoint</a></li>
|
||||
<li><a href="#format_common_func_start">llvm.dbg.func.start</a></li>
|
||||
<li><a href="#format_common_region_start">llvm.dbg.region.start</a></li>
|
||||
<li><a href="#format_common_region_end">llvm.dbg.region.end</a></li>
|
||||
<li><a href="#format_common_declare">llvm.dbg.declare</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#format_common_stoppoints">Representing stopping points in the
|
||||
source program</a></li>
|
||||
</ol></li>
|
||||
<li><a href="#format_common_lifetime">Object lifetimes and scoping</a></li>
|
||||
<li><a href="#ccxx_frontend">C/C++ front-end specific debug information</a>
|
||||
<ol>
|
||||
<li><a href="#ccxx_compile_units">C/C++ source file information</a></li>
|
||||
@ -761,92 +756,6 @@ DW_TAG_return_variable = 258
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="format_common_stoppoint">llvm.dbg.stoppoint</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<pre>
|
||||
void %<a href="#format_common_stoppoint">llvm.dbg.stoppoint</a>( uint, uint, metadata)
|
||||
</pre>
|
||||
|
||||
<p>This intrinsic is used to provide correspondence between the source file and
|
||||
the generated code. The first argument is the line number (base 1), second
|
||||
argument is the column number (0 if unknown) and the third argument the
|
||||
source <tt>%<a href="#format_compile_units">llvm.dbg.compile_unit</a></tt>.
|
||||
Code following a call to this intrinsic will
|
||||
have been defined in close proximity of the line, column and file. This
|
||||
information holds until the next call
|
||||
to <tt>%<a href="#format_common_stoppoint">lvm.dbg.stoppoint</a></tt>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="format_common_func_start">llvm.dbg.func.start</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<pre>
|
||||
void %<a href="#format_common_func_start">llvm.dbg.func.start</a>( metadata )
|
||||
</pre>
|
||||
|
||||
<p>This intrinsic is used to link the debug information
|
||||
in <tt>%<a href="#format_subprograms">llvm.dbg.subprogram</a></tt> to the
|
||||
function. It defines the beginning of the function's declarative region
|
||||
(scope). It also implies a call to
|
||||
%<tt><a href="#format_common_stoppoint">llvm.dbg.stoppoint</a></tt> which
|
||||
defines a source line "stop point". The intrinsic should be called early in
|
||||
the function after the all the alloca instructions. It should be paired off
|
||||
with a closing
|
||||
<tt>%<a href="#format_common_region_end">llvm.dbg.region.end</a></tt>.
|
||||
The function's single argument is
|
||||
the <tt>%<a href="#format_subprograms">llvm.dbg.subprogram.type</a></tt>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="format_common_region_start">llvm.dbg.region.start</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<pre>
|
||||
void %<a href="#format_common_region_start">llvm.dbg.region.start</a>( metadata )
|
||||
</pre>
|
||||
|
||||
<p>This intrinsic is used to define the beginning of a declarative scope (ex.
|
||||
block) for local language elements. It should be paired off with a closing
|
||||
<tt>%<a href="#format_common_region_end">llvm.dbg.region.end</a></tt>. The
|
||||
function's single argument is
|
||||
the <tt>%<a href="#format_blocks">llvm.dbg.block</a></tt> which is
|
||||
starting.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="format_common_region_end">llvm.dbg.region.end</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<pre>
|
||||
void %<a href="#format_common_region_end">llvm.dbg.region.end</a>( metadata )
|
||||
</pre>
|
||||
|
||||
<p>This intrinsic is used to define the end of a declarative scope (ex. block)
|
||||
for local language elements. It should be paired off with an
|
||||
opening <tt>%<a href="#format_common_region_start">llvm.dbg.region.start</a></tt>
|
||||
or <tt>%<a href="#format_common_func_start">llvm.dbg.func.start</a></tt>.
|
||||
The function's single argument is either
|
||||
the <tt>%<a href="#format_blocks">llvm.dbg.block</a></tt> or
|
||||
the <tt>%<a href="#format_subprograms">llvm.dbg.subprogram.type</a></tt>
|
||||
which is ending.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="format_common_declare">llvm.dbg.declare</a>
|
||||
@ -865,70 +774,35 @@ DW_TAG_return_variable = 258
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="format_common_stoppoints">
|
||||
Representing stopping points in the source program
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM debugger "stop points" are a key part of the debugging representation
|
||||
that allows the LLVM to maintain simple semantics
|
||||
for <a href="#debugopt">debugging optimized code</a>. The basic idea is that
|
||||
the front-end inserts calls to
|
||||
the <a href="#format_common_stoppoint">%<tt>llvm.dbg.stoppoint</tt></a>
|
||||
intrinsic function at every point in the program where a debugger should be
|
||||
able to inspect the program (these correspond to places a debugger stops when
|
||||
you "<tt>step</tt>" through it). The front-end can choose to place these as
|
||||
fine-grained as it would like (for example, before every subexpression
|
||||
evaluated), but it is recommended to only put them after every source
|
||||
statement that includes executable code.</p>
|
||||
|
||||
<p>Using calls to this intrinsic function to demark legal points for the
|
||||
debugger to inspect the program automatically disables any optimizations that
|
||||
could potentially confuse debugging information. To
|
||||
non-debug-information-aware transformations, these calls simply look like
|
||||
calls to an external function, which they must assume to do anything
|
||||
(including reading or writing to any part of reachable memory). On the other
|
||||
hand, it does not impact many optimizations, such as code motion of
|
||||
non-trapping instructions, nor does it impact optimization of subexpressions,
|
||||
code duplication transformations, or basic-block reordering
|
||||
transformations.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="format_common_lifetime">Object lifetimes and scoping</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p>In many languages, the local variables in functions can have their lifetime
|
||||
or scope limited to a subset of a function. In the C family of languages,
|
||||
<p>In many languages, the local variables in functions can have their lifetimes
|
||||
or scopes limited to a subset of a function. In the C family of languages,
|
||||
for example, variables are only live (readable and writable) within the
|
||||
source block that they are defined in. In functional languages, values are
|
||||
only readable after they have been defined. Though this is a very obvious
|
||||
concept, it is also non-trivial to model in LLVM, because it has no notion of
|
||||
concept, it is non-trivial to model in LLVM, because it has no notion of
|
||||
scoping in this sense, and does not want to be tied to a language's scoping
|
||||
rules.</p>
|
||||
|
||||
<p>In order to handle this, the LLVM debug format uses the notion of "regions"
|
||||
of a function, delineated by calls to intrinsic functions. These intrinsic
|
||||
functions define new regions of the program and indicate when the region
|
||||
lifetime expires. Consider the following C fragment, for example:</p>
|
||||
<p>In order to handle this, the LLVM debug format uses the metadata attached to
|
||||
llvm instructions to encode line nuber and scoping information. Consider the
|
||||
following C fragment, for example:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
1. void foo() {
|
||||
2. int X = ...;
|
||||
3. int Y = ...;
|
||||
2. int X = 21;
|
||||
3. int Y = 22;
|
||||
4. {
|
||||
5. int Z = ...;
|
||||
6. ...
|
||||
5. int Z = 23;
|
||||
6. Z = X;
|
||||
7. }
|
||||
8. ...
|
||||
8. X = Y;
|
||||
9. }
|
||||
</pre>
|
||||
</div>
|
||||
@ -937,98 +811,129 @@ DW_TAG_return_variable = 258
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
void %foo() {
|
||||
define void @foo() nounwind ssp {
|
||||
entry:
|
||||
%X = alloca int
|
||||
%Y = alloca int
|
||||
%Z = alloca int
|
||||
|
||||
...
|
||||
|
||||
call void @<a href="#format_common_func_start">llvm.dbg.func.start</a>( metadata !0)
|
||||
|
||||
call void @<a href="#format_common_stoppoint">llvm.dbg.stoppoint</a>( uint 2, uint 2, metadata !1)
|
||||
|
||||
call void @<a href="#format_common_declare">llvm.dbg.declare</a>({}* %X, ...)
|
||||
call void @<a href="#format_common_declare">llvm.dbg.declare</a>({}* %Y, ...)
|
||||
|
||||
<i>;; Evaluate expression on line 2, assigning to X.</i>
|
||||
|
||||
call void @<a href="#format_common_stoppoint">llvm.dbg.stoppoint</a>( uint 3, uint 2, metadata !1)
|
||||
|
||||
<i>;; Evaluate expression on line 3, assigning to Y.</i>
|
||||
|
||||
call void @<a href="#format_common_stoppoint">llvm.region.start</a>()
|
||||
call void @<a href="#format_common_stoppoint">llvm.dbg.stoppoint</a>( uint 5, uint 4, metadata !1)
|
||||
call void @<a href="#format_common_declare">llvm.dbg.declare</a>({}* %X, ...)
|
||||
|
||||
<i>;; Evaluate expression on line 5, assigning to Z.</i>
|
||||
|
||||
call void @<a href="#format_common_stoppoint">llvm.dbg.stoppoint</a>( uint 7, uint 2, metadata !1)
|
||||
call void @<a href="#format_common_region_end">llvm.region.end</a>()
|
||||
|
||||
call void @<a href="#format_common_stoppoint">llvm.dbg.stoppoint</a>( uint 9, uint 2, metadata !1)
|
||||
|
||||
call void @<a href="#format_common_region_end">llvm.region.end</a>()
|
||||
|
||||
ret void
|
||||
%X = alloca i32, align 4 ; <i32*> [#uses=4]
|
||||
%Y = alloca i32, align 4 ; <i32*> [#uses=4]
|
||||
%Z = alloca i32, align 4 ; <i32*> [#uses=3]
|
||||
%0 = bitcast i32* %X to { }* ; <{ }*> [#uses=1]
|
||||
call void @llvm.dbg.declare({ }* %0, metadata !0), !dbg !7
|
||||
store i32 21, i32* %X, !dbg !8
|
||||
%1 = bitcast i32* %Y to { }* ; <{ }*> [#uses=1]
|
||||
call void @llvm.dbg.declare({ }* %1, metadata !9), !dbg !10
|
||||
store i32 22, i32* %Y, !dbg !11
|
||||
%2 = bitcast i32* %Z to { }* ; <{ }*> [#uses=1]
|
||||
call void @llvm.dbg.declare({ }* %2, metadata !12), !dbg !14
|
||||
store i32 23, i32* %Z, !dbg !15
|
||||
%tmp = load i32* %X, !dbg !16 ; <i32> [#uses=1]
|
||||
%tmp1 = load i32* %Y, !dbg !16 ; <i32> [#uses=1]
|
||||
%add = add nsw i32 %tmp, %tmp1, !dbg !16 ; <i32> [#uses=1]
|
||||
store i32 %add, i32* %Z, !dbg !16
|
||||
%tmp2 = load i32* %Y, !dbg !17 ; <i32> [#uses=1]
|
||||
store i32 %tmp2, i32* %X, !dbg !17
|
||||
ret void, !dbg !18
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare({ }*, metadata) nounwind readnone
|
||||
|
||||
!0 = metadata !{i32 459008, metadata !1, metadata !"X",
|
||||
metadata !3, i32 2, metadata !6}; [ DW_TAG_auto_variable ]
|
||||
!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ]
|
||||
!2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"foo", metadata !"foo",
|
||||
metadata !"foo", metadata !3, i32 1, metadata !4,
|
||||
i1 false, i1 true}; [DW_TAG_subprogram ]
|
||||
!3 = metadata !{i32 458769, i32 0, i32 12, metadata !"foo.c",
|
||||
metadata !"/private/tmp", metadata !"clang 1.1", i1 true,
|
||||
i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ]
|
||||
!4 = metadata !{i32 458773, metadata !3, metadata !"", null, i32 0, i64 0, i64 0,
|
||||
i64 0, i32 0, null, metadata !5, i32 0}; [DW_TAG_subroutine_type ]
|
||||
!5 = metadata !{null}
|
||||
!6 = metadata !{i32 458788, metadata !3, metadata !"int", metadata !3, i32 0,
|
||||
i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ]
|
||||
!7 = metadata !{i32 2, i32 7, metadata !1, null}
|
||||
!8 = metadata !{i32 2, i32 3, metadata !1, null}
|
||||
!9 = metadata !{i32 459008, metadata !1, metadata !"Y", metadata !3, i32 3,
|
||||
metadata !6}; [ DW_TAG_auto_variable ]
|
||||
!10 = metadata !{i32 3, i32 7, metadata !1, null}
|
||||
!11 = metadata !{i32 3, i32 3, metadata !1, null}
|
||||
!12 = metadata !{i32 459008, metadata !13, metadata !"Z", metadata !3, i32 5,
|
||||
metadata !6}; [ DW_TAG_auto_variable ]
|
||||
!13 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ]
|
||||
!14 = metadata !{i32 5, i32 9, metadata !13, null}
|
||||
!15 = metadata !{i32 5, i32 5, metadata !13, null}
|
||||
!16 = metadata !{i32 6, i32 5, metadata !13, null}
|
||||
!17 = metadata !{i32 8, i32 3, metadata !1, null}
|
||||
!18 = metadata !{i32 9, i32 1, metadata !2, null}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This example illustrates a few important details about the LLVM debugging
|
||||
information. In particular, it shows how the various intrinsics are applied
|
||||
together to allow a debugger to analyze the relationship between statements,
|
||||
variable definitions, and the code used to implement the function.</p>
|
||||
<p>This example illustrates a few important details about LLVM debugging
|
||||
information. In particular, it shows how the <tt>llvm.dbg.declare</tt>
|
||||
intrinsic and location information, which are attached to an instruction,
|
||||
are applied together to allow a debugger to analyze the relationship between
|
||||
statements, variable definitions, and the code used to implement the
|
||||
function.</p>
|
||||
|
||||
<p>The first
|
||||
intrinsic <tt>%<a href="#format_common_func_start">llvm.dbg.func.start</a></tt>
|
||||
provides a link with the <a href="#format_subprograms">subprogram
|
||||
descriptor</a> containing the details of this function. This call also
|
||||
defines the beginning of the function region, bounded by
|
||||
the <tt>%<a href="#format_common_region_end">llvm.region.end</a></tt> at the
|
||||
end of the function. This region is used to bracket the lifetime of
|
||||
variables declared within. For a function, this outer region defines a new
|
||||
stack frame whose lifetime ends when the region is ended.</p>
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
call void @llvm.dbg.declare({ }* %0, metadata !0), !dbg !7
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>It is possible to define inner regions for short term variables by using the
|
||||
%<a href="#format_common_stoppoint"><tt>llvm.region.start</tt></a>
|
||||
and <a href="#format_common_region_end"><tt>%llvm.region.end</tt></a> to
|
||||
bound a region. The inner region in this example would be for the block
|
||||
containing the declaration of Z.</p>
|
||||
<p>The first intrinsic
|
||||
<tt>%<a href="#format_common_declare">llvm.dbg.declare</a></tt>
|
||||
encodes debugging information for the variable <tt>X</tt>. The metadata
|
||||
<tt>!dbg !7</tt> attached to the intrinsic provides scope information for the
|
||||
variable <tt>X</tt>.</p>
|
||||
|
||||
<p>Using regions to represent the boundaries of source-level functions allow
|
||||
LLVM interprocedural optimizations to arbitrarily modify LLVM functions
|
||||
without having to worry about breaking mapping information between the LLVM
|
||||
code and the and source-level program. In particular, the inliner requires
|
||||
no modification to support inlining with debugging information: there is no
|
||||
explicit correlation drawn between LLVM functions and their source-level
|
||||
counterparts (note however, that if the inliner inlines all instances of a
|
||||
non-strong-linkage function into its caller that it will not be possible for
|
||||
the user to manually invoke the inlined function from a debugger).</p>
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
!7 = metadata !{i32 2, i32 7, metadata !1, null}
|
||||
!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ]
|
||||
!2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"foo",
|
||||
metadata !"foo", metadata !"foo", metadata !3, i32 1,
|
||||
metadata !4, i1 false, i1 true}; [DW_TAG_subprogram ]
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>Once the function has been defined,
|
||||
the <a href="#format_common_stoppoint"><tt>stopping point</tt></a>
|
||||
corresponding to line #2 (column #2) of the function is encountered. At this
|
||||
point in the function, <b>no</b> local variables are live. As lines 2 and 3
|
||||
of the example are executed, their variable definitions are introduced into
|
||||
the program using
|
||||
%<a href="#format_common_declare"><tt>llvm.dbg.declare</tt></a>, without the
|
||||
need to specify a new region. These variables do not require new regions to
|
||||
be introduced because they go out of scope at the same point in the program:
|
||||
line 9.</p>
|
||||
<p>Here <tt>!7</tt> is metadata providing location information. It has four
|
||||
fields: line number, column number, scope, and original scope. The original
|
||||
scope represents inline location if this instruction is inlined inside a
|
||||
caller, and is null otherwise. In this example, scope is encoded by
|
||||
<tt>!1</tt>. <tt>!1</tt> represents a lexical block inside the scope
|
||||
<tt>!2</tt>, where <tt>!2</tt> is a
|
||||
<a href="#format_subprograms">subprogram descriptor</a>. This way the
|
||||
location information attached to the intrinsics indicates that the
|
||||
variable <tt>X</tt> is declared at line number 2 at a function level scope in
|
||||
function <tt>foo</tt>.</p>
|
||||
|
||||
<p>In contrast, the <tt>Z</tt> variable goes out of scope at a different time,
|
||||
on line 7. For this reason, it is defined within the inner region, which
|
||||
kills the availability of <tt>Z</tt> before the code for line 8 is executed.
|
||||
In this way, regions can support arbitrary source-language scoping rules, as
|
||||
long as they can only be nested (ie, one scope cannot partially overlap with
|
||||
a part of another scope).</p>
|
||||
<p>Now lets take another example.</p>
|
||||
|
||||
<p>It is worth noting that this scoping mechanism is used to control scoping of
|
||||
all declarations, not just variable declarations. For example, the scope of
|
||||
a C++ using declaration is controlled with this and could change how name
|
||||
lookup is performed.</p>
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
call void @llvm.dbg.declare({ }* %2, metadata !12), !dbg !14
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>The second intrinsic
|
||||
<tt>%<a href="#format_common_declare">llvm.dbg.declare</a></tt>
|
||||
encodes debugging information for variable <tt>Z</tt>. The metadata
|
||||
<tt>!dbg !14</tt> attached to the intrinsic provides scope information for
|
||||
the variable <tt>Z</tt>.</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
!13 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ]
|
||||
!14 = metadata !{i32 5, i32 9, metadata !13, null}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>Here <tt>!14</tt> indicates that <tt>Z</tt> is declaread at line number 5 and
|
||||
column number 9 inside of lexical scope <tt>!13</tt>. The lexical scope
|
||||
itself resides inside of lexical scope <tt>!1</tt> described above.</p>
|
||||
|
||||
<p>The scope information attached with each instruction provides a
|
||||
straightforward way to find instructions covered by a scope.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -1813,7 +1718,7 @@ enum Trees {
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-11-17 14:13:59 +0100 (Tue, 17 Nov 2009) $
|
||||
Last modified: $Date: 2009-12-01 01:59:58 +0100 (Tue, 01 Dec 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -15,16 +15,6 @@
|
||||
<div class="doc_title"> LLVM Tutorial: Table of Contents </div>
|
||||
|
||||
<ol>
|
||||
<li><!--<a href="Introduction.html">-->An Introduction to LLVM: Basic Concepts and Design</li>
|
||||
<li>Simple JIT Tutorials
|
||||
<ol>
|
||||
<li><a href="JITTutorial1.html">A First Function</a></li>
|
||||
<li><a href="JITTutorial2.html">A More Complicated Function</a></li>
|
||||
<li><!--<a href="Tutorial3.html">-->Running Optimizations</li>
|
||||
<li><!--<a href="Tutorial4.html">-->Reading and Writing Bitcode</li>
|
||||
<li><!--<a href="Tutorial5.html">-->Invoking the JIT</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>Kaleidoscope: Implementing a Language with LLVM
|
||||
<ol>
|
||||
<li><a href="LangImpl1.html">Tutorial Introduction and the Lexer</a></li>
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetSelect.h"
|
||||
using namespace llvm;
|
||||
|
||||
static Function *CreateFibFunction(Module *M, LLVMContext &Context) {
|
||||
@ -92,6 +93,7 @@ static Function *CreateFibFunction(Module *M, LLVMContext &Context) {
|
||||
int main(int argc, char **argv) {
|
||||
int n = argc > 1 ? atol(argv[1]) : 24;
|
||||
|
||||
InitializeNativeTarget();
|
||||
LLVMContext Context;
|
||||
|
||||
// Create some module to put our function into it.
|
||||
@ -101,7 +103,13 @@ int main(int argc, char **argv) {
|
||||
Function *FibF = CreateFibFunction(M, Context);
|
||||
|
||||
// Now we going to create JIT
|
||||
ExecutionEngine *EE = EngineBuilder(M).create();
|
||||
std::string errStr;
|
||||
ExecutionEngine *EE = EngineBuilder(M).setErrorStr(&errStr).setEngineKind(EngineKind::JIT).create();
|
||||
|
||||
if (!EE) {
|
||||
errs() << argv[0] << ": Failed to construct ExecutionEngine: " << errStr << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
errs() << "verifying... ";
|
||||
if (verifyModule(*M)) {
|
||||
|
@ -870,7 +870,7 @@ LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
|
||||
LLVMTypeRef DestTy, const char *Name);
|
||||
LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef, LLVMValueRef Val,
|
||||
LLVMTypeRef DestTy, const char *Name);
|
||||
LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val,
|
||||
LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val, /*Signed cast!*/
|
||||
LLVMTypeRef DestTy, const char *Name);
|
||||
LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef, LLVMValueRef Val,
|
||||
LLVMTypeRef DestTy, const char *Name);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define LLVM_ADT_STLEXTRAS_H
|
||||
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <cstdlib> // for qsort
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <utility> // for std::pair
|
||||
|
@ -38,12 +38,15 @@ class SmallString : public SmallVector<char, InternalLen> {
|
||||
// Extra methods.
|
||||
StringRef str() const { return StringRef(this->begin(), this->size()); }
|
||||
|
||||
// Implicit conversion to StringRef.
|
||||
operator StringRef() const { return str(); }
|
||||
|
||||
const char *c_str() {
|
||||
this->push_back(0);
|
||||
this->pop_back();
|
||||
return this->data();
|
||||
}
|
||||
|
||||
|
||||
// Extra operators.
|
||||
const SmallString &operator=(StringRef RHS) {
|
||||
this->clear();
|
||||
|
@ -10,9 +10,9 @@
|
||||
#ifndef LLVM_ADT_STRINGREF_H
|
||||
#define LLVM_ADT_STRINGREF_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
@ -39,6 +39,19 @@ namespace llvm {
|
||||
/// The length of the string.
|
||||
size_t Length;
|
||||
|
||||
// Workaround PR5482: nearly all gcc 4.x miscompile StringRef and std::min()
|
||||
// Changing the arg of min to be an integer, instead of a reference to an
|
||||
// integer works around this bug.
|
||||
size_t min(size_t a, size_t b) const
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
size_t max(size_t a, size_t b) const
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
public:
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
@ -108,7 +121,7 @@ namespace llvm {
|
||||
/// is lexicographically less than, equal to, or greater than the \arg RHS.
|
||||
int compare(StringRef RHS) const {
|
||||
// Check the prefix for a mismatch.
|
||||
if (int Res = memcmp(Data, RHS.Data, std::min(Length, RHS.Length)))
|
||||
if (int Res = memcmp(Data, RHS.Data, min(Length, RHS.Length)))
|
||||
return Res < 0 ? -1 : 1;
|
||||
|
||||
// Otherwise the prefixes match, so we only need to check the lengths.
|
||||
@ -163,7 +176,7 @@ namespace llvm {
|
||||
/// \return - The index of the first occurence of \arg C, or npos if not
|
||||
/// found.
|
||||
size_t find(char C, size_t From = 0) const {
|
||||
for (size_t i = std::min(From, Length), e = Length; i != e; ++i)
|
||||
for (size_t i = min(From, Length), e = Length; i != e; ++i)
|
||||
if (Data[i] == C)
|
||||
return i;
|
||||
return npos;
|
||||
@ -180,7 +193,7 @@ namespace llvm {
|
||||
/// \return - The index of the last occurence of \arg C, or npos if not
|
||||
/// found.
|
||||
size_t rfind(char C, size_t From = npos) const {
|
||||
From = std::min(From, Length);
|
||||
From = min(From, Length);
|
||||
size_t i = From;
|
||||
while (i != 0) {
|
||||
--i;
|
||||
@ -262,8 +275,8 @@ namespace llvm {
|
||||
/// exceeds the number of characters remaining in the string, the string
|
||||
/// suffix (starting with \arg Start) will be returned.
|
||||
StringRef substr(size_t Start, size_t N = npos) const {
|
||||
Start = std::min(Start, Length);
|
||||
return StringRef(Data + Start, std::min(N, Length - Start));
|
||||
Start = min(Start, Length);
|
||||
return StringRef(Data + Start, min(N, Length - Start));
|
||||
}
|
||||
|
||||
/// slice - Return a reference to the substring from [Start, End).
|
||||
@ -277,8 +290,8 @@ namespace llvm {
|
||||
/// number of characters remaining in the string, the string suffix
|
||||
/// (starting with \arg Start) will be returned.
|
||||
StringRef slice(size_t Start, size_t End) const {
|
||||
Start = std::min(Start, Length);
|
||||
End = std::min(std::max(Start, End), Length);
|
||||
Start = min(Start, Length);
|
||||
End = min(max(Start, End), Length);
|
||||
return StringRef(Data + Start, End - Start);
|
||||
}
|
||||
|
||||
|
@ -309,8 +309,7 @@ struct DOTGraphTraits<Trie<Payload> > : public DefaultDOTGraphTraits {
|
||||
return "Trie";
|
||||
}
|
||||
|
||||
static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T,
|
||||
bool ShortNames) {
|
||||
static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T) {
|
||||
if (T.getRoot() == Node)
|
||||
return "<Root>";
|
||||
else
|
||||
|
@ -64,7 +64,7 @@ class Triple {
|
||||
msp430, // MSP430: msp430
|
||||
pic16, // PIC16: pic16
|
||||
ppc, // PPC: powerpc
|
||||
ppc64, // PPC64: powerpc64
|
||||
ppc64, // PPC64: powerpc64, ppu
|
||||
sparc, // Sparc: sparc
|
||||
systemz, // SystemZ: s390x
|
||||
tce, // TCE (http://tce.cs.tut.fi/): tce
|
||||
@ -90,6 +90,7 @@ class Triple {
|
||||
DragonFly,
|
||||
FreeBSD,
|
||||
Linux,
|
||||
Lv2, // PS3
|
||||
MinGW32,
|
||||
MinGW64,
|
||||
NetBSD,
|
||||
|
@ -94,13 +94,12 @@ class AliasAnalysis {
|
||||
virtual AliasResult alias(const Value *V1, unsigned V1Size,
|
||||
const Value *V2, unsigned V2Size);
|
||||
|
||||
/// getMustAliases - If there are any pointers known that must alias this
|
||||
/// pointer, return them now. This allows alias-set based alias analyses to
|
||||
/// perform a form a value numbering (which is exposed by load-vn). If an
|
||||
/// alias analysis supports this, it should ADD any must aliased pointers to
|
||||
/// the specified vector.
|
||||
///
|
||||
virtual void getMustAliases(Value *P, std::vector<Value*> &RetVals);
|
||||
/// isNoAlias - A trivial helper function to check to see if the specified
|
||||
/// pointers are no-alias.
|
||||
bool isNoAlias(const Value *V1, unsigned V1Size,
|
||||
const Value *V2, unsigned V2Size) {
|
||||
return alias(V1, V1Size, V2, V2Size) == NoAlias;
|
||||
}
|
||||
|
||||
/// pointsToConstantMemory - If the specified pointer is known to point into
|
||||
/// constant global memory, return true. This allows disambiguation of store
|
||||
@ -262,14 +261,6 @@ class AliasAnalysis {
|
||||
///
|
||||
virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
|
||||
|
||||
/// hasNoModRefInfoForCalls - Return true if the analysis has no mod/ref
|
||||
/// information for pairs of function calls (other than "pure" and "const"
|
||||
/// functions). This can be used by clients to avoid many pointless queries.
|
||||
/// Remember that if you override this and chain to another analysis, you must
|
||||
/// make sure that it doesn't have mod/ref info either.
|
||||
///
|
||||
virtual bool hasNoModRefInfoForCalls() const;
|
||||
|
||||
public:
|
||||
/// Convenience functions...
|
||||
ModRefResult getModRefInfo(LoadInst *L, Value *P, unsigned Size);
|
||||
|
@ -24,23 +24,29 @@
|
||||
namespace llvm {
|
||||
template<>
|
||||
struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
|
||||
|
||||
DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
|
||||
|
||||
static std::string getGraphName(const Function *F) {
|
||||
return "CFG for '" + F->getNameStr() + "' function";
|
||||
}
|
||||
|
||||
static std::string getNodeLabel(const BasicBlock *Node,
|
||||
const Function *Graph,
|
||||
bool ShortNames) {
|
||||
if (ShortNames && !Node->getName().empty())
|
||||
return Node->getNameStr() + ":";
|
||||
static std::string getSimpleNodeLabel(const BasicBlock *Node,
|
||||
const Function *Graph) {
|
||||
if (!Node->getName().empty())
|
||||
return Node->getNameStr();
|
||||
|
||||
std::string Str;
|
||||
raw_string_ostream OS(Str);
|
||||
|
||||
if (ShortNames) {
|
||||
WriteAsOperand(OS, Node, false);
|
||||
return OS.str();
|
||||
}
|
||||
WriteAsOperand(OS, Node, false);
|
||||
return OS.str();
|
||||
}
|
||||
|
||||
static std::string getCompleteNodeLabel(const BasicBlock *Node,
|
||||
const Function *Graph) {
|
||||
std::string Str;
|
||||
raw_string_ostream OS(Str);
|
||||
|
||||
if (Node->getName().empty()) {
|
||||
WriteAsOperand(OS, Node, false);
|
||||
@ -65,6 +71,14 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
|
||||
return OutStr;
|
||||
}
|
||||
|
||||
std::string getNodeLabel(const BasicBlock *Node,
|
||||
const Function *Graph) {
|
||||
if (isSimple())
|
||||
return getSimpleNodeLabel(Node, Graph);
|
||||
else
|
||||
return getCompleteNodeLabel(Node, Graph);
|
||||
}
|
||||
|
||||
static std::string getEdgeSourceLabel(const BasicBlock *Node,
|
||||
succ_const_iterator I) {
|
||||
// Label source of conditional branches with "T" or "F"
|
||||
|
@ -21,8 +21,12 @@ namespace llvm {
|
||||
/// by the enclosing function (which is required to exist). This routine can
|
||||
/// be expensive, so consider caching the results. The boolean ReturnCaptures
|
||||
/// specifies whether returning the value (or part of it) from the function
|
||||
/// counts as capturing it or not. The boolean StoreCaptures specified whether
|
||||
/// storing the value (or part of it) into memory anywhere automatically
|
||||
/// counts as capturing it or not.
|
||||
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures);
|
||||
bool PointerMayBeCaptured(const Value *V,
|
||||
bool ReturnCaptures,
|
||||
bool StoreCaptures);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -55,7 +55,7 @@ namespace llvm {
|
||||
/// not, the debug info is corrupt and we ignore it.
|
||||
DIDescriptor(MDNode *N, unsigned RequiredTag);
|
||||
|
||||
const char *getStringField(unsigned Elt) const;
|
||||
StringRef getStringField(unsigned Elt) const;
|
||||
unsigned getUnsignedField(unsigned Elt) const {
|
||||
return (unsigned)getUInt64Field(Elt);
|
||||
}
|
||||
@ -137,8 +137,8 @@ namespace llvm {
|
||||
}
|
||||
virtual ~DIScope() {}
|
||||
|
||||
const char *getFilename() const;
|
||||
const char *getDirectory() const;
|
||||
StringRef getFilename() const;
|
||||
StringRef getDirectory() const;
|
||||
};
|
||||
|
||||
/// DICompileUnit - A wrapper for a compile unit.
|
||||
@ -150,9 +150,9 @@ namespace llvm {
|
||||
}
|
||||
|
||||
unsigned getLanguage() const { return getUnsignedField(2); }
|
||||
const char *getFilename() const { return getStringField(3); }
|
||||
const char *getDirectory() const { return getStringField(4); }
|
||||
const char *getProducer() const { return getStringField(5); }
|
||||
StringRef getFilename() const { return getStringField(3); }
|
||||
StringRef getDirectory() const { return getStringField(4); }
|
||||
StringRef getProducer() const { return getStringField(5); }
|
||||
|
||||
/// isMain - Each input file is encoded as a separate compile unit in LLVM
|
||||
/// debugging information output. However, many target specific tool chains
|
||||
@ -165,7 +165,7 @@ namespace llvm {
|
||||
|
||||
bool isMain() const { return getUnsignedField(6); }
|
||||
bool isOptimized() const { return getUnsignedField(7); }
|
||||
const char *getFlags() const { return getStringField(8); }
|
||||
StringRef getFlags() const { return getStringField(8); }
|
||||
unsigned getRunTimeVersion() const { return getUnsignedField(9); }
|
||||
|
||||
/// Verify - Verify that a compile unit is well formed.
|
||||
@ -183,7 +183,7 @@ namespace llvm {
|
||||
explicit DIEnumerator(MDNode *N = 0)
|
||||
: DIDescriptor(N, dwarf::DW_TAG_enumerator) {}
|
||||
|
||||
const char *getName() const { return getStringField(1); }
|
||||
StringRef getName() const { return getStringField(1); }
|
||||
uint64_t getEnumValue() const { return getUInt64Field(2); }
|
||||
};
|
||||
|
||||
@ -217,7 +217,7 @@ namespace llvm {
|
||||
virtual ~DIType() {}
|
||||
|
||||
DIDescriptor getContext() const { return getDescriptorField(1); }
|
||||
const char *getName() const { return getStringField(2); }
|
||||
StringRef getName() const { return getStringField(2); }
|
||||
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
|
||||
unsigned getLineNumber() const { return getUnsignedField(4); }
|
||||
uint64_t getSizeInBits() const { return getUInt64Field(5); }
|
||||
@ -317,9 +317,9 @@ namespace llvm {
|
||||
virtual ~DIGlobal() {}
|
||||
|
||||
DIDescriptor getContext() const { return getDescriptorField(2); }
|
||||
const char *getName() const { return getStringField(3); }
|
||||
const char *getDisplayName() const { return getStringField(4); }
|
||||
const char *getLinkageName() const { return getStringField(5); }
|
||||
StringRef getName() const { return getStringField(3); }
|
||||
StringRef getDisplayName() const { return getStringField(4); }
|
||||
StringRef getLinkageName() const { return getStringField(5); }
|
||||
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(6); }
|
||||
unsigned getLineNumber() const { return getUnsignedField(7); }
|
||||
DIType getType() const { return getFieldAs<DIType>(8); }
|
||||
@ -342,16 +342,16 @@ namespace llvm {
|
||||
}
|
||||
|
||||
DIDescriptor getContext() const { return getDescriptorField(2); }
|
||||
const char *getName() const { return getStringField(3); }
|
||||
const char *getDisplayName() const { return getStringField(4); }
|
||||
const char *getLinkageName() const { return getStringField(5); }
|
||||
StringRef getName() const { return getStringField(3); }
|
||||
StringRef getDisplayName() const { return getStringField(4); }
|
||||
StringRef getLinkageName() const { return getStringField(5); }
|
||||
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(6); }
|
||||
unsigned getLineNumber() const { return getUnsignedField(7); }
|
||||
DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
|
||||
|
||||
/// getReturnTypeName - Subprogram return types are encoded either as
|
||||
/// DIType or as DICompositeType.
|
||||
const char *getReturnTypeName() const {
|
||||
StringRef getReturnTypeName() const {
|
||||
DICompositeType DCT(getFieldAs<DICompositeType>(8));
|
||||
if (!DCT.isNull()) {
|
||||
DIArray A = DCT.getTypeArray();
|
||||
@ -366,8 +366,8 @@ namespace llvm {
|
||||
/// compile unit, like 'static' in C.
|
||||
unsigned isLocalToUnit() const { return getUnsignedField(9); }
|
||||
unsigned isDefinition() const { return getUnsignedField(10); }
|
||||
const char *getFilename() const { return getCompileUnit().getFilename();}
|
||||
const char *getDirectory() const { return getCompileUnit().getDirectory();}
|
||||
StringRef getFilename() const { return getCompileUnit().getFilename();}
|
||||
StringRef getDirectory() const { return getCompileUnit().getDirectory();}
|
||||
|
||||
/// Verify - Verify that a subprogram descriptor is well formed.
|
||||
bool Verify() const;
|
||||
@ -406,7 +406,7 @@ namespace llvm {
|
||||
}
|
||||
|
||||
DIDescriptor getContext() const { return getDescriptorField(1); }
|
||||
const char *getName() const { return getStringField(2); }
|
||||
StringRef getName() const { return getStringField(2); }
|
||||
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
|
||||
unsigned getLineNumber() const { return getUnsignedField(4); }
|
||||
DIType getType() const { return getFieldAs<DIType>(5); }
|
||||
@ -444,8 +444,8 @@ namespace llvm {
|
||||
DbgNode = 0;
|
||||
}
|
||||
DIScope getContext() const { return getFieldAs<DIScope>(1); }
|
||||
const char *getDirectory() const { return getContext().getDirectory(); }
|
||||
const char *getFilename() const { return getContext().getFilename(); }
|
||||
StringRef getDirectory() const { return getContext().getDirectory(); }
|
||||
StringRef getFilename() const { return getContext().getFilename(); }
|
||||
};
|
||||
|
||||
/// DILocation - This object holds location information. This object
|
||||
@ -458,8 +458,8 @@ namespace llvm {
|
||||
unsigned getColumnNumber() const { return getUnsignedField(1); }
|
||||
DIScope getScope() const { return getFieldAs<DIScope>(2); }
|
||||
DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
|
||||
const char *getFilename() const { return getScope().getFilename(); }
|
||||
const char *getDirectory() const { return getScope().getDirectory(); }
|
||||
StringRef getFilename() const { return getScope().getFilename(); }
|
||||
StringRef getDirectory() const { return getScope().getDirectory(); }
|
||||
};
|
||||
|
||||
/// DIFactory - This object assists with the construction of the various
|
||||
@ -489,26 +489,26 @@ namespace llvm {
|
||||
/// CreateCompileUnit - Create a new descriptor for the specified compile
|
||||
/// unit.
|
||||
DICompileUnit CreateCompileUnit(unsigned LangID,
|
||||
const char * Filename,
|
||||
const char * Directory,
|
||||
const char * Producer,
|
||||
StringRef Filename,
|
||||
StringRef Directory,
|
||||
StringRef Producer,
|
||||
bool isMain = false,
|
||||
bool isOptimized = false,
|
||||
const char *Flags = "",
|
||||
StringRef Flags = "",
|
||||
unsigned RunTimeVer = 0);
|
||||
|
||||
/// CreateEnumerator - Create a single enumerator value.
|
||||
DIEnumerator CreateEnumerator(const char * Name, uint64_t Val);
|
||||
DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
|
||||
|
||||
/// CreateBasicType - Create a basic type like int, float, etc.
|
||||
DIBasicType CreateBasicType(DIDescriptor Context, const char * Name,
|
||||
DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
|
||||
DICompileUnit CompileUnit, unsigned LineNumber,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits,
|
||||
uint64_t OffsetInBits, unsigned Flags,
|
||||
unsigned Encoding);
|
||||
|
||||
/// CreateBasicType - Create a basic type like int, float, etc.
|
||||
DIBasicType CreateBasicTypeEx(DIDescriptor Context, const char * Name,
|
||||
DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
|
||||
DICompileUnit CompileUnit, unsigned LineNumber,
|
||||
Constant *SizeInBits, Constant *AlignInBits,
|
||||
Constant *OffsetInBits, unsigned Flags,
|
||||
@ -517,7 +517,7 @@ namespace llvm {
|
||||
/// CreateDerivedType - Create a derived type like const qualified type,
|
||||
/// pointer, typedef, etc.
|
||||
DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits,
|
||||
@ -527,7 +527,7 @@ namespace llvm {
|
||||
/// CreateDerivedType - Create a derived type like const qualified type,
|
||||
/// pointer, typedef, etc.
|
||||
DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
Constant *SizeInBits, Constant *AlignInBits,
|
||||
@ -536,7 +536,7 @@ namespace llvm {
|
||||
|
||||
/// CreateCompositeType - Create a composite type like array, struct, etc.
|
||||
DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
uint64_t SizeInBits,
|
||||
@ -548,7 +548,7 @@ namespace llvm {
|
||||
|
||||
/// CreateCompositeType - Create a composite type like array, struct, etc.
|
||||
DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
Constant *SizeInBits,
|
||||
@ -560,25 +560,25 @@ namespace llvm {
|
||||
|
||||
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
|
||||
/// See comments in DISubprogram for descriptions of these fields.
|
||||
DISubprogram CreateSubprogram(DIDescriptor Context, const char * Name,
|
||||
const char * DisplayName,
|
||||
const char * LinkageName,
|
||||
DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
|
||||
StringRef DisplayName,
|
||||
StringRef LinkageName,
|
||||
DICompileUnit CompileUnit, unsigned LineNo,
|
||||
DIType Type, bool isLocalToUnit,
|
||||
bool isDefinition);
|
||||
|
||||
/// CreateGlobalVariable - Create a new descriptor for the specified global.
|
||||
DIGlobalVariable
|
||||
CreateGlobalVariable(DIDescriptor Context, const char * Name,
|
||||
const char * DisplayName,
|
||||
const char * LinkageName,
|
||||
CreateGlobalVariable(DIDescriptor Context, StringRef Name,
|
||||
StringRef DisplayName,
|
||||
StringRef LinkageName,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNo, DIType Type, bool isLocalToUnit,
|
||||
bool isDefinition, llvm::GlobalVariable *GV);
|
||||
|
||||
/// CreateVariable - Create a new descriptor for the specified variable.
|
||||
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit, unsigned LineNo,
|
||||
DIType Type);
|
||||
|
||||
@ -598,6 +598,10 @@ namespace llvm {
|
||||
DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
|
||||
DIScope S, DILocation OrigLoc);
|
||||
|
||||
/// CreateLocation - Creates a debug info location.
|
||||
DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
|
||||
DIScope S, MDNode *OrigLoc = 0);
|
||||
|
||||
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
|
||||
Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
|
||||
BasicBlock *InsertAtEnd);
|
||||
@ -669,6 +673,12 @@ bool getLocationInfo(const Value *V, std::string &DisplayName,
|
||||
DebugLoc ExtractDebugLocation(DbgFuncStartInst &FSI,
|
||||
DebugLocTracker &DebugLocInfo);
|
||||
|
||||
/// getDISubprogram - Find subprogram that is enclosing this scope.
|
||||
DISubprogram getDISubprogram(MDNode *Scope);
|
||||
|
||||
/// getDICompositeType - Find underlying composite type.
|
||||
DICompositeType getDICompositeType(DIType T);
|
||||
|
||||
class DebugInfoFinder {
|
||||
|
||||
public:
|
||||
|
@ -20,6 +20,11 @@ namespace llvm {
|
||||
class Instruction;
|
||||
class Value;
|
||||
class TargetData;
|
||||
|
||||
/// SimplifyAddInst - Given operands for an Add, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
|
||||
const TargetData *TD = 0);
|
||||
|
||||
/// SimplifyAndInst - Given operands for an And, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
@ -42,6 +47,11 @@ namespace llvm {
|
||||
const TargetData *TD = 0);
|
||||
|
||||
|
||||
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyGEPInst(Value * const *Ops, unsigned NumOps,
|
||||
const TargetData *TD = 0);
|
||||
|
||||
//=== Helper functions for higher up the class hierarchy.
|
||||
|
||||
|
||||
|
@ -49,9 +49,6 @@ namespace llvm {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// hasNoModRefInfoForCalls - We can provide mod/ref information against
|
||||
/// non-escaping allocations.
|
||||
virtual bool hasNoModRefInfoForCalls() const { return false; }
|
||||
private:
|
||||
ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
|
||||
CallSite CS, Value *P, unsigned Size);
|
||||
|
@ -269,8 +269,6 @@ class LoopBase {
|
||||
|
||||
/// getLoopLatch - If there is a single latch block for this loop, return it.
|
||||
/// A latch block is a block that contains a branch back to the header.
|
||||
/// A loop header in normal form has two edges into it: one from a preheader
|
||||
/// and one from a latch block.
|
||||
BlockT *getLoopLatch() const {
|
||||
BlockT *Header = getHeader();
|
||||
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
|
||||
@ -278,20 +276,12 @@ class LoopBase {
|
||||
InvBlockTraits::child_begin(Header);
|
||||
typename InvBlockTraits::ChildIteratorType PE =
|
||||
InvBlockTraits::child_end(Header);
|
||||
if (PI == PE) return 0; // no preds?
|
||||
|
||||
BlockT *Latch = 0;
|
||||
if (contains(*PI))
|
||||
Latch = *PI;
|
||||
++PI;
|
||||
if (PI == PE) return 0; // only one pred?
|
||||
|
||||
if (contains(*PI)) {
|
||||
if (Latch) return 0; // multiple backedges
|
||||
Latch = *PI;
|
||||
}
|
||||
++PI;
|
||||
if (PI != PE) return 0; // more than two preds
|
||||
for (; PI != PE; ++PI)
|
||||
if (contains(*PI)) {
|
||||
if (Latch) return 0;
|
||||
Latch = *PI;
|
||||
}
|
||||
|
||||
return Latch;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ namespace llvm {
|
||||
class TargetData;
|
||||
class MemoryDependenceAnalysis;
|
||||
class PredIteratorCache;
|
||||
class DominatorTree;
|
||||
|
||||
/// MemDepResult - A memory dependence query can return one of three different
|
||||
/// answers, described below.
|
||||
@ -244,6 +245,29 @@ namespace llvm {
|
||||
BasicBlock *BB,
|
||||
SmallVectorImpl<NonLocalDepEntry> &Result);
|
||||
|
||||
/// GetPHITranslatedValue - Find an available version of the specified value
|
||||
/// PHI translated across the specified edge. If MemDep isn't able to
|
||||
/// satisfy this request, it returns null.
|
||||
Value *GetPHITranslatedValue(Value *V,
|
||||
BasicBlock *CurBB, BasicBlock *PredBB,
|
||||
const TargetData *TD) const;
|
||||
|
||||
/// GetAvailablePHITranslatedValue - Return the value computed by
|
||||
/// PHITranslatePointer if it dominates PredBB, otherwise return null.
|
||||
Value *GetAvailablePHITranslatedValue(Value *V,
|
||||
BasicBlock *CurBB, BasicBlock *PredBB,
|
||||
const TargetData *TD,
|
||||
const DominatorTree &DT) const;
|
||||
|
||||
/// InsertPHITranslatedPointer - Insert a computation of the PHI translated
|
||||
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
|
||||
/// block. All newly created instructions are added to the NewInsts list.
|
||||
Value *InsertPHITranslatedPointer(Value *V,
|
||||
BasicBlock *CurBB, BasicBlock *PredBB,
|
||||
const TargetData *TD,
|
||||
const DominatorTree &DT,
|
||||
SmallVectorImpl<Instruction*> &NewInsts) const;
|
||||
|
||||
/// removeInstruction - Remove an instruction from the dependence analysis,
|
||||
/// updating the dependence of instructions that previously depended on it.
|
||||
void removeInstruction(Instruction *InstToRemove);
|
||||
|
@ -81,7 +81,10 @@ template <> struct GraphTraits<PostDominatorTree*>
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_begin(PostDominatorTree *N) {
|
||||
return df_begin(getEntryNode(N));
|
||||
if (getEntryNode(N))
|
||||
return df_begin(getEntryNode(N));
|
||||
else
|
||||
return df_end(getEntryNode(N));
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end(PostDominatorTree *N) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
template <typename T> class SmallVectorImpl;
|
||||
class Value;
|
||||
class Instruction;
|
||||
class APInt;
|
||||
@ -77,6 +78,26 @@ namespace llvm {
|
||||
///
|
||||
bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0);
|
||||
|
||||
/// DecomposeGEPExpression - If V is a symbolic pointer expression, decompose
|
||||
/// it into a base pointer with a constant offset and a number of scaled
|
||||
/// symbolic offsets.
|
||||
///
|
||||
/// The scaled symbolic offsets (represented by pairs of a Value* and a scale
|
||||
/// in the VarIndices vector) are Value*'s that are known to be scaled by the
|
||||
/// specified amount, but which may have other unrepresented high bits. As
|
||||
/// such, the gep cannot necessarily be reconstructed from its decomposed
|
||||
/// form.
|
||||
///
|
||||
/// When TargetData is around, this function is capable of analyzing
|
||||
/// everything that Value::getUnderlyingObject() can look through. When not,
|
||||
/// it just looks through pointer casts.
|
||||
///
|
||||
const Value *DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
|
||||
SmallVectorImpl<std::pair<const Value*, int64_t> > &VarIndices,
|
||||
const TargetData *TD);
|
||||
|
||||
|
||||
|
||||
/// FindScalarValue - Given an aggregrate and an sequence of indices, see if
|
||||
/// the scalar value indexed is already around as a register, for example if
|
||||
/// it were inserted directly into the aggregrate.
|
||||
@ -86,16 +107,14 @@ namespace llvm {
|
||||
Value *FindInsertedValue(Value *V,
|
||||
const unsigned *idx_begin,
|
||||
const unsigned *idx_end,
|
||||
LLVMContext &Context,
|
||||
Instruction *InsertBefore = 0);
|
||||
|
||||
/// This is a convenience wrapper for finding values indexed by a single index
|
||||
/// only.
|
||||
inline Value *FindInsertedValue(Value *V, const unsigned Idx,
|
||||
LLVMContext &Context,
|
||||
Instruction *InsertBefore = 0) {
|
||||
const unsigned Idxs[1] = { Idx };
|
||||
return FindInsertedValue(V, &Idxs[0], &Idxs[1], Context, InsertBefore);
|
||||
return FindInsertedValue(V, &Idxs[0], &Idxs[1], InsertBefore);
|
||||
}
|
||||
|
||||
/// GetConstantStringInfo - This function computes the length of a
|
||||
|
@ -297,7 +297,7 @@ namespace llvm {
|
||||
/// EmitString - Emit a string with quotes and a null terminator.
|
||||
/// Special characters are emitted properly.
|
||||
/// @verbatim (Eg. '\t') @endverbatim
|
||||
void EmitString(const std::string &String) const;
|
||||
void EmitString(const StringRef String) const;
|
||||
void EmitString(const char *String, unsigned Size) const;
|
||||
|
||||
/// EmitFile - Emit a .file directive.
|
||||
@ -345,9 +345,11 @@ namespace llvm {
|
||||
|
||||
/// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress
|
||||
/// uses of the specified basic block.
|
||||
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
|
||||
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA,
|
||||
const char *Suffix = "") const;
|
||||
MCSymbol *GetBlockAddressSymbol(const Function *F,
|
||||
const BasicBlock *BB) const;
|
||||
const BasicBlock *BB,
|
||||
const char *Suffix = "") const;
|
||||
|
||||
/// EmitBasicBlockStart - This method prints the label for the specified
|
||||
/// MachineBasicBlock, an alignment (if present) and a comment describing
|
||||
|
@ -68,23 +68,29 @@ class JITCodeEmitter : public MachineCodeEmitter {
|
||||
///
|
||||
virtual bool finishFunction(MachineFunction &F) = 0;
|
||||
|
||||
/// startGVStub - This callback is invoked when the JIT needs the
|
||||
/// address of a GV (e.g. function) that has not been code generated yet.
|
||||
/// The StubSize specifies the total size required by the stub.
|
||||
/// startGVStub - This callback is invoked when the JIT needs the address of a
|
||||
/// GV (e.g. function) that has not been code generated yet. The StubSize
|
||||
/// specifies the total size required by the stub. The BufferState must be
|
||||
/// passed to finishGVStub, and start/finish pairs with the same BufferState
|
||||
/// must be properly nested.
|
||||
///
|
||||
virtual void startGVStub(const GlobalValue* GV, unsigned StubSize,
|
||||
unsigned Alignment = 1) = 0;
|
||||
virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
|
||||
unsigned StubSize, unsigned Alignment = 1) = 0;
|
||||
|
||||
/// startGVStub - This callback is invoked when the JIT needs the address of a
|
||||
/// startGVStub - This callback is invoked when the JIT needs the address of a
|
||||
/// GV (e.g. function) that has not been code generated yet. Buffer points to
|
||||
/// memory already allocated for this stub.
|
||||
/// memory already allocated for this stub. The BufferState must be passed to
|
||||
/// finishGVStub, and start/finish pairs with the same BufferState must be
|
||||
/// properly nested.
|
||||
///
|
||||
virtual void startGVStub(const GlobalValue* GV, void *Buffer,
|
||||
virtual void startGVStub(BufferState &BS, void *Buffer,
|
||||
unsigned StubSize) = 0;
|
||||
|
||||
/// finishGVStub - This callback is invoked to terminate a GV stub.
|
||||
|
||||
/// finishGVStub - This callback is invoked to terminate a GV stub and returns
|
||||
/// the start address of the stub. The BufferState must first have been
|
||||
/// passed to startGVStub.
|
||||
///
|
||||
virtual void *finishGVStub(const GlobalValue* F) = 0;
|
||||
virtual void *finishGVStub(BufferState &BS) = 0;
|
||||
|
||||
/// emitByte - This callback is invoked when a byte needs to be written to the
|
||||
/// output stream.
|
||||
|
@ -40,18 +40,11 @@ namespace llvm {
|
||||
/// mobility.
|
||||
std::vector<unsigned> NumNodesSolelyBlocking;
|
||||
|
||||
/// IgnoreAntiDep - Ignore anti-dependencies
|
||||
bool IgnoreAntiDep;
|
||||
|
||||
/// Queue - The queue.
|
||||
PriorityQueue<SUnit*, std::vector<SUnit*>, latency_sort> Queue;
|
||||
|
||||
public:
|
||||
LatencyPriorityQueue() : IgnoreAntiDep(false), Queue(latency_sort(this)) {
|
||||
}
|
||||
|
||||
void setIgnoreAntiDep(bool ignore) {
|
||||
IgnoreAntiDep = ignore;
|
||||
LatencyPriorityQueue() : Queue(latency_sort(this)) {
|
||||
}
|
||||
|
||||
void initNodes(std::vector<SUnit> &sunits) {
|
||||
@ -72,7 +65,7 @@ namespace llvm {
|
||||
|
||||
unsigned getLatency(unsigned NodeNum) const {
|
||||
assert(NodeNum < (*SUnits).size());
|
||||
return (*SUnits)[NodeNum].getHeight(IgnoreAntiDep);
|
||||
return (*SUnits)[NodeNum].getHeight();
|
||||
}
|
||||
|
||||
unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
|
||||
|
@ -107,6 +107,13 @@ class LiveVariables : public MachineFunctionPass {
|
||||
/// findKill - Find a kill instruction in MBB. Return NULL if none is found.
|
||||
MachineInstr *findKill(const MachineBasicBlock *MBB) const;
|
||||
|
||||
/// isLiveIn - Is Reg live in to MBB? This means that Reg is live through
|
||||
/// MBB, or it is killed in MBB. If Reg is only used by PHI instructions in
|
||||
/// MBB, it is not considered live in.
|
||||
bool isLiveIn(const MachineBasicBlock &MBB,
|
||||
unsigned Reg,
|
||||
MachineRegisterInfo &MRI);
|
||||
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
@ -156,8 +163,13 @@ class LiveVariables : public MachineFunctionPass {
|
||||
SmallVector<unsigned, 4> &Defs);
|
||||
void UpdatePhysRegDefs(MachineInstr *MI, SmallVector<unsigned, 4> &Defs);
|
||||
|
||||
/// FindLastPartialDef - Return the last partial def of the specified register.
|
||||
/// Also returns the sub-registers that're defined by the instruction.
|
||||
/// FindLastRefOrPartRef - Return the last reference or partial reference of
|
||||
/// the specified register.
|
||||
MachineInstr *FindLastRefOrPartRef(unsigned Reg);
|
||||
|
||||
/// FindLastPartialDef - Return the last partial def of the specified
|
||||
/// register. Also returns the sub-registers that're defined by the
|
||||
/// instruction.
|
||||
MachineInstr *FindLastPartialDef(unsigned Reg,
|
||||
SmallSet<unsigned,4> &PartDefRegs);
|
||||
|
||||
@ -267,11 +279,17 @@ class LiveVariables : public MachineFunctionPass {
|
||||
void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
|
||||
MachineInstr *MI);
|
||||
|
||||
/// addNewBlock - Add a new basic block BB as an empty succcessor to
|
||||
/// DomBB. All variables that are live out of DomBB will be marked as passing
|
||||
/// live through BB. This method assumes that the machine code is still in SSA
|
||||
/// form.
|
||||
void addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB);
|
||||
bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB) {
|
||||
return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI);
|
||||
}
|
||||
|
||||
/// addNewBlock - Add a new basic block BB between DomBB and SuccBB. All
|
||||
/// variables that are live out of DomBB and live into SuccBB will be marked
|
||||
/// as passing live through BB. This method assumes that the machine code is
|
||||
/// still in SSA form.
|
||||
void addNewBlock(MachineBasicBlock *BB,
|
||||
MachineBasicBlock *DomBB,
|
||||
MachineBasicBlock *SuccBB);
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -92,10 +92,15 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
|
||||
public:
|
||||
/// getBasicBlock - Return the LLVM basic block that this instance
|
||||
/// corresponded to originally.
|
||||
/// corresponded to originally. Note that this may be NULL if this instance
|
||||
/// does not correspond directly to an LLVM basic block.
|
||||
///
|
||||
const BasicBlock *getBasicBlock() const { return BB; }
|
||||
|
||||
/// getName - Return the name of the corresponding LLVM basic block, or
|
||||
/// "(null)".
|
||||
StringRef getName() const;
|
||||
|
||||
/// hasAddressTaken - Test whether this block is potentially the target
|
||||
/// of an indirect branch.
|
||||
bool hasAddressTaken() const { return AddressTaken; }
|
||||
@ -266,6 +271,12 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
/// ends with an unconditional branch to some other block.
|
||||
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const;
|
||||
|
||||
/// canFallThrough - Return true if the block can implicitly transfer
|
||||
/// control to the block after it by falling off the end of it. This should
|
||||
/// return false if it can reach the block after it, but it uses an explicit
|
||||
/// branch to do so (e.g., a table jump). True is a conservative answer.
|
||||
bool canFallThrough();
|
||||
|
||||
/// getFirstTerminator - returns an iterator to the first terminator
|
||||
/// instruction of this basic block. If a terminator does not exist,
|
||||
/// it returns end()
|
||||
|
@ -48,17 +48,41 @@ class Function;
|
||||
/// occurred, more memory is allocated, and we reemit the code into it.
|
||||
///
|
||||
class MachineCodeEmitter {
|
||||
public:
|
||||
class BufferState {
|
||||
friend class MachineCodeEmitter;
|
||||
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
|
||||
/// allocated for this code buffer.
|
||||
uint8_t *BufferBegin, *BufferEnd;
|
||||
|
||||
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
|
||||
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
|
||||
/// this pointer is at BufferEnd, it will never move due to code emission,
|
||||
/// and all code emission requests will be ignored (this is the buffer
|
||||
/// overflow condition).
|
||||
uint8_t *CurBufferPtr;
|
||||
public:
|
||||
BufferState() : BufferBegin(NULL), BufferEnd(NULL), CurBufferPtr(NULL) {}
|
||||
};
|
||||
|
||||
protected:
|
||||
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
|
||||
/// allocated for this code buffer.
|
||||
uint8_t *BufferBegin, *BufferEnd;
|
||||
|
||||
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
|
||||
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
|
||||
/// this pointer is at BufferEnd, it will never move due to code emission, and
|
||||
/// all code emission requests will be ignored (this is the buffer overflow
|
||||
/// condition).
|
||||
uint8_t *CurBufferPtr;
|
||||
/// These have the same meanings as the fields in BufferState
|
||||
uint8_t *BufferBegin, *BufferEnd, *CurBufferPtr;
|
||||
|
||||
/// Save or restore the current buffer state. The BufferState objects must be
|
||||
/// used as a stack.
|
||||
void SaveStateTo(BufferState &BS) {
|
||||
assert(BS.BufferBegin == NULL &&
|
||||
"Can't save state into the same BufferState twice.");
|
||||
BS.BufferBegin = BufferBegin;
|
||||
BS.BufferEnd = BufferEnd;
|
||||
BS.CurBufferPtr = CurBufferPtr;
|
||||
}
|
||||
void RestoreStateFrom(BufferState &BS) {
|
||||
BufferBegin = BS.BufferBegin;
|
||||
BufferEnd = BS.BufferEnd;
|
||||
CurBufferPtr = BS.CurBufferPtr;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~MachineCodeEmitter() {}
|
||||
|
@ -135,9 +135,6 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
/// llvm.compiler.used.
|
||||
SmallPtrSet<const Function *, 32> UsedFunctions;
|
||||
|
||||
/// UsedDbgLabels - labels are used by debug info entries.
|
||||
SmallSet<unsigned, 8> UsedDbgLabels;
|
||||
|
||||
bool CallsEHReturn;
|
||||
bool CallsUnwindInit;
|
||||
|
||||
@ -232,19 +229,6 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
return LabelID ? LabelIDList[LabelID - 1] : 0;
|
||||
}
|
||||
|
||||
/// isDbgLabelUsed - Return true if label with LabelID is used by
|
||||
/// DwarfWriter.
|
||||
bool isDbgLabelUsed(unsigned LabelID) {
|
||||
return UsedDbgLabels.count(LabelID);
|
||||
}
|
||||
|
||||
/// RecordUsedDbgLabel - Mark label with LabelID as used. This is used
|
||||
/// by DwarfWriter to inform DebugLabelFolder that certain labels are
|
||||
/// not to be deleted.
|
||||
void RecordUsedDbgLabel(unsigned LabelID) {
|
||||
UsedDbgLabels.insert(LabelID);
|
||||
}
|
||||
|
||||
/// getFrameMoves - Returns a reference to a list of moves done in the current
|
||||
/// function's prologue. Used to construct frame maps for debug and exception
|
||||
/// handling comsumers.
|
||||
|
@ -435,10 +435,12 @@ class MachineOperand {
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateBA(BlockAddress *BA) {
|
||||
static MachineOperand CreateBA(BlockAddress *BA,
|
||||
unsigned char TargetFlags = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_BlockAddress);
|
||||
Op.Contents.OffsetedInfo.Val.BA = BA;
|
||||
Op.setOffset(0); // Offset is always 0.
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
|
||||
|
@ -129,6 +129,10 @@ namespace llvm {
|
||||
/// branches.
|
||||
FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge);
|
||||
|
||||
/// TailDuplicate Pass - Duplicate blocks with unconditional branches
|
||||
/// into tails of their predecessors.
|
||||
FunctionPass *createTailDuplicatePass();
|
||||
|
||||
/// IfConverter Pass - This pass performs machine code if conversion.
|
||||
FunctionPass *createIfConverterPass();
|
||||
|
||||
@ -136,11 +140,6 @@ namespace llvm {
|
||||
/// headers to target specific alignment boundary.
|
||||
FunctionPass *createCodePlacementOptPass();
|
||||
|
||||
/// DebugLabelFoldingPass - This pass prunes out redundant debug labels. This
|
||||
/// allows a debug emitter to determine if the range of two labels is empty,
|
||||
/// by seeing if the labels map to the same reduced label.
|
||||
FunctionPass *createDebugLabelFoldingPass();
|
||||
|
||||
/// getRegisterAllocator - This creates an instance of the register allocator
|
||||
/// for the Sparc.
|
||||
FunctionPass *getRegisterAllocator(TargetMachine &T);
|
||||
|
@ -340,34 +340,30 @@ namespace llvm {
|
||||
void removePred(const SDep &D);
|
||||
|
||||
/// getDepth - Return the depth of this node, which is the length of the
|
||||
/// maximum path up to any node with has no predecessors. If IgnoreAntiDep
|
||||
/// is true, ignore anti-dependence edges.
|
||||
unsigned getDepth(bool IgnoreAntiDep=false) const {
|
||||
/// maximum path up to any node with has no predecessors.
|
||||
unsigned getDepth() const {
|
||||
if (!isDepthCurrent)
|
||||
const_cast<SUnit *>(this)->ComputeDepth(IgnoreAntiDep);
|
||||
const_cast<SUnit *>(this)->ComputeDepth();
|
||||
return Depth;
|
||||
}
|
||||
|
||||
/// getHeight - Return the height of this node, which is the length of the
|
||||
/// maximum path down to any node with has no successors. If IgnoreAntiDep
|
||||
/// is true, ignore anti-dependence edges.
|
||||
unsigned getHeight(bool IgnoreAntiDep=false) const {
|
||||
/// maximum path down to any node with has no successors.
|
||||
unsigned getHeight() const {
|
||||
if (!isHeightCurrent)
|
||||
const_cast<SUnit *>(this)->ComputeHeight(IgnoreAntiDep);
|
||||
const_cast<SUnit *>(this)->ComputeHeight();
|
||||
return Height;
|
||||
}
|
||||
|
||||
/// setDepthToAtLeast - If NewDepth is greater than this node's
|
||||
/// depth value, set it to be the new depth value. This also
|
||||
/// recursively marks successor nodes dirty. If IgnoreAntiDep is
|
||||
/// true, ignore anti-dependence edges.
|
||||
void setDepthToAtLeast(unsigned NewDepth, bool IgnoreAntiDep=false);
|
||||
/// recursively marks successor nodes dirty.
|
||||
void setDepthToAtLeast(unsigned NewDepth);
|
||||
|
||||
/// setDepthToAtLeast - If NewDepth is greater than this node's
|
||||
/// depth value, set it to be the new height value. This also
|
||||
/// recursively marks predecessor nodes dirty. If IgnoreAntiDep is
|
||||
/// true, ignore anti-dependence edges.
|
||||
void setHeightToAtLeast(unsigned NewHeight, bool IgnoreAntiDep=false);
|
||||
/// recursively marks predecessor nodes dirty.
|
||||
void setHeightToAtLeast(unsigned NewHeight);
|
||||
|
||||
/// setDepthDirty - Set a flag in this node to indicate that its
|
||||
/// stored Depth value will require recomputation the next time
|
||||
@ -400,8 +396,8 @@ namespace llvm {
|
||||
void print(raw_ostream &O, const ScheduleDAG *G) const;
|
||||
|
||||
private:
|
||||
void ComputeDepth(bool IgnoreAntiDep);
|
||||
void ComputeHeight(bool IgnoreAntiDep);
|
||||
void ComputeDepth();
|
||||
void ComputeHeight();
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -322,12 +322,10 @@ class SelectionDAG {
|
||||
unsigned char TargetFlags = 0);
|
||||
SDValue getValueType(EVT);
|
||||
SDValue getRegister(unsigned Reg, EVT VT);
|
||||
SDValue getDbgStopPoint(DebugLoc DL, SDValue Root,
|
||||
unsigned Line, unsigned Col, MDNode *CU);
|
||||
SDValue getLabel(unsigned Opcode, DebugLoc dl, SDValue Root,
|
||||
unsigned LabelID);
|
||||
SDValue getBlockAddress(BlockAddress *BA, DebugLoc dl,
|
||||
bool isTarget = false);
|
||||
SDValue getBlockAddress(BlockAddress *BA, EVT VT,
|
||||
bool isTarget = false, unsigned char TargetFlags = 0);
|
||||
|
||||
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
|
||||
return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
|
||||
@ -884,6 +882,14 @@ class SelectionDAG {
|
||||
/// element of the result of the vector shuffle.
|
||||
SDValue getShuffleScalarElt(const ShuffleVectorSDNode *N, unsigned Idx);
|
||||
|
||||
/// UnrollVectorOp - Utility function used by legalize and lowering to
|
||||
/// "unroll" a vector operation by splitting out the scalars and operating
|
||||
/// on each element individually. If the ResNE is 0, fully unroll the vector
|
||||
/// op. If ResNE is less than the width of the vector op, unroll up to ResNE.
|
||||
/// If the ResNE is greater than the width of the vector op, unroll the
|
||||
/// vector op and fill the end of the resulting vector with UNDEFS.
|
||||
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
|
||||
|
||||
private:
|
||||
bool RemoveNodeFromCSEMaps(SDNode *N);
|
||||
void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener);
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
namespace llvm {
|
||||
class FastISel;
|
||||
class SelectionDAGLowering;
|
||||
class SelectionDAGBuilder;
|
||||
class SDValue;
|
||||
class MachineRegisterInfo;
|
||||
class MachineBasicBlock;
|
||||
@ -48,7 +48,7 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
MachineFunction *MF;
|
||||
MachineRegisterInfo *RegInfo;
|
||||
SelectionDAG *CurDAG;
|
||||
SelectionDAGLowering *SDL;
|
||||
SelectionDAGBuilder *SDB;
|
||||
MachineBasicBlock *BB;
|
||||
AliasAnalysis *AA;
|
||||
GCFunctionInfo *GFI;
|
||||
@ -127,7 +127,8 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
|
||||
void SelectBasicBlock(BasicBlock *LLVMBB,
|
||||
BasicBlock::iterator Begin,
|
||||
BasicBlock::iterator End);
|
||||
BasicBlock::iterator End,
|
||||
bool &HadTailCall);
|
||||
void CodeGenAndEmitDAG();
|
||||
void LowerArguments(BasicBlock *BB);
|
||||
|
||||
|
@ -494,10 +494,9 @@ namespace ISD {
|
||||
// Operand #last: Optional, an incoming flag.
|
||||
INLINEASM,
|
||||
|
||||
// DBG_LABEL, EH_LABEL - Represents a label in mid basic block used to track
|
||||
// EH_LABEL - Represents a label in mid basic block used to track
|
||||
// locations needed for debug and exception handling tables. These nodes
|
||||
// take a chain as input and return a chain.
|
||||
DBG_LABEL,
|
||||
EH_LABEL,
|
||||
|
||||
// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
|
||||
@ -546,18 +545,6 @@ namespace ISD {
|
||||
// HANDLENODE node - Used as a handle for various purposes.
|
||||
HANDLENODE,
|
||||
|
||||
// DBG_STOPPOINT - This node is used to represent a source location for
|
||||
// debug info. It takes token chain as input, and carries a line number,
|
||||
// column number, and a pointer to a CompileUnit object identifying
|
||||
// the containing compilation unit. It produces a token chain as output.
|
||||
DBG_STOPPOINT,
|
||||
|
||||
// DEBUG_LOC - This node is used to represent source line information
|
||||
// embedded in the code. It takes a token chain as input, then a line
|
||||
// number, then a column then a file id (provided by MachineModuleInfo.) It
|
||||
// produces a token chain as output.
|
||||
DEBUG_LOC,
|
||||
|
||||
// TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
|
||||
// It takes as input a token chain, the pointer to the trampoline,
|
||||
// the pointer to the nested function, the pointer to pass for the
|
||||
@ -636,10 +623,6 @@ namespace ISD {
|
||||
/// element is not an undef.
|
||||
bool isScalarToVector(const SDNode *N);
|
||||
|
||||
/// isDebugLabel - Return true if the specified node represents a debug
|
||||
/// label (i.e. ISD::DBG_LABEL or TargetInstrInfo::DBG_LABEL node).
|
||||
bool isDebugLabel(const SDNode *N);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// MemIndexedMode enum - This enum defines the load / store indexed
|
||||
/// addressing modes.
|
||||
@ -2004,37 +1987,18 @@ class RegisterSDNode : public SDNode {
|
||||
}
|
||||
};
|
||||
|
||||
class DbgStopPointSDNode : public SDNode {
|
||||
SDUse Chain;
|
||||
unsigned Line;
|
||||
unsigned Column;
|
||||
MDNode *CU;
|
||||
friend class SelectionDAG;
|
||||
DbgStopPointSDNode(SDValue ch, unsigned l, unsigned c,
|
||||
MDNode *cu)
|
||||
: SDNode(ISD::DBG_STOPPOINT, DebugLoc::getUnknownLoc(),
|
||||
getSDVTList(MVT::Other)), Line(l), Column(c), CU(cu) {
|
||||
InitOperands(&Chain, ch);
|
||||
}
|
||||
public:
|
||||
unsigned getLine() const { return Line; }
|
||||
unsigned getColumn() const { return Column; }
|
||||
MDNode *getCompileUnit() const { return CU; }
|
||||
|
||||
static bool classof(const DbgStopPointSDNode *) { return true; }
|
||||
static bool classof(const SDNode *N) {
|
||||
return N->getOpcode() == ISD::DBG_STOPPOINT;
|
||||
}
|
||||
};
|
||||
|
||||
class BlockAddressSDNode : public SDNode {
|
||||
BlockAddress *BA;
|
||||
unsigned char TargetFlags;
|
||||
friend class SelectionDAG;
|
||||
BlockAddressSDNode(unsigned NodeTy, DebugLoc dl, EVT VT, BlockAddress *ba)
|
||||
: SDNode(NodeTy, dl, getSDVTList(VT)), BA(ba) {
|
||||
BlockAddressSDNode(unsigned NodeTy, EVT VT, BlockAddress *ba,
|
||||
unsigned char Flags)
|
||||
: SDNode(NodeTy, DebugLoc::getUnknownLoc(), getSDVTList(VT)),
|
||||
BA(ba), TargetFlags(Flags) {
|
||||
}
|
||||
public:
|
||||
BlockAddress *getBlockAddress() const { return BA; }
|
||||
unsigned char getTargetFlags() const { return TargetFlags; }
|
||||
|
||||
static bool classof(const BlockAddressSDNode *) { return true; }
|
||||
static bool classof(const SDNode *N) {
|
||||
@ -2056,8 +2020,7 @@ class LabelSDNode : public SDNode {
|
||||
|
||||
static bool classof(const LabelSDNode *) { return true; }
|
||||
static bool classof(const SDNode *N) {
|
||||
return N->getOpcode() == ISD::DBG_LABEL ||
|
||||
N->getOpcode() == ISD::EH_LABEL;
|
||||
return N->getOpcode() == ISD::EH_LABEL;
|
||||
}
|
||||
};
|
||||
|
||||
|
29
include/llvm/Config/Disassemblers.def.in
Normal file
29
include/llvm/Config/Disassemblers.def.in
Normal file
@ -0,0 +1,29 @@
|
||||
//===- llvm/Config/Disassemblers.def - LLVM Assembly Parsers ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file enumerates all of the assembly-language parsers
|
||||
// supported by this build of LLVM. Clients of this file should define
|
||||
// the LLVM_ASM_PARSER macro to be a function-like macro with a
|
||||
// single parameter (the name of the target whose assembly can be
|
||||
// generated); including this file will then enumerate all of the
|
||||
// targets with assembly parsers.
|
||||
//
|
||||
// The set of targets supported by LLVM is generated at configuration
|
||||
// time, at which point this header is generated. Do not modify this
|
||||
// header directly.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DISASSEMBLER
|
||||
# error Please define the macro LLVM_DISASSEMBLER(TargetName)
|
||||
#endif
|
||||
|
||||
@LLVM_ENUM_DISASSEMBLERS@
|
||||
|
||||
#undef LLVM_DISASSEMBLER
|
@ -341,19 +341,25 @@ def int_init_trampoline : Intrinsic<[llvm_ptr_ty],
|
||||
|
||||
// Expose the carry flag from add operations on two integrals.
|
||||
def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>]>;
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrNoMem]>;
|
||||
def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>]>;
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>]>;
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrNoMem]>;
|
||||
def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>]>;
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrNoMem]>;
|
||||
|
||||
def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>]>;
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrNoMem]>;
|
||||
def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>]>;
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrNoMem]>;
|
||||
|
||||
//===------------------------- Atomic Intrinsics --------------------------===//
|
||||
//
|
||||
|
@ -671,12 +671,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
|
||||
|
||||
// Align ops
|
||||
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
|
||||
def int_x86_ssse3_palign_r : GCCBuiltin<"__builtin_ia32_palignr">,
|
||||
def int_x86_ssse3_palign_r :
|
||||
Intrinsic<[llvm_v1i64_ty], [llvm_v1i64_ty,
|
||||
llvm_v1i64_ty, llvm_i16_ty], [IntrNoMem]>;
|
||||
def int_x86_ssse3_palign_r_128 : GCCBuiltin<"__builtin_ia32_palignr128">,
|
||||
llvm_v1i64_ty, llvm_i8_ty], [IntrNoMem]>;
|
||||
def int_x86_ssse3_palign_r_128 :
|
||||
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
|
||||
llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -91,7 +91,7 @@ class MDNode : public MetadataBase, public FoldingSetNode {
|
||||
MDNode(const MDNode &); // DO NOT IMPLEMENT
|
||||
|
||||
friend class ElementVH;
|
||||
// Use CallbackVH to hold MDNOde elements.
|
||||
// Use CallbackVH to hold MDNode elements.
|
||||
struct ElementVH : public CallbackVH {
|
||||
MDNode *Parent;
|
||||
ElementVH() {}
|
||||
@ -264,7 +264,7 @@ class MetadataContext {
|
||||
/// the same metadata to In2.
|
||||
void copyMD(Instruction *In1, Instruction *In2);
|
||||
|
||||
/// getHandlerNames - Populate client supplied smallvector using custome
|
||||
/// getHandlerNames - Populate client supplied smallvector using custom
|
||||
/// metadata name and ID.
|
||||
void getHandlerNames(SmallVectorImpl<std::pair<unsigned, StringRef> >&) const;
|
||||
|
||||
|
@ -27,6 +27,17 @@ namespace llvm {
|
||||
/// implementations.
|
||||
///
|
||||
struct DefaultDOTGraphTraits {
|
||||
private:
|
||||
bool IsSimple;
|
||||
|
||||
protected:
|
||||
bool isSimple() {
|
||||
return IsSimple;
|
||||
}
|
||||
|
||||
public:
|
||||
DefaultDOTGraphTraits (bool simple=false) : IsSimple (simple) {}
|
||||
|
||||
/// getGraphName - Return the label for the graph as a whole. Printed at the
|
||||
/// top of the graph.
|
||||
///
|
||||
@ -51,8 +62,7 @@ struct DefaultDOTGraphTraits {
|
||||
/// getNodeLabel - Given a node and a pointer to the top level graph, return
|
||||
/// the label to print in the node.
|
||||
template<typename GraphType>
|
||||
static std::string getNodeLabel(const void *Node,
|
||||
const GraphType& Graph, bool ShortNames) {
|
||||
std::string getNodeLabel(const void *Node, const GraphType& Graph) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -135,7 +145,9 @@ struct DefaultDOTGraphTraits {
|
||||
/// from DefaultDOTGraphTraits if you don't need to override everything.
|
||||
///
|
||||
template <typename Ty>
|
||||
struct DOTGraphTraits : public DefaultDOTGraphTraits {};
|
||||
struct DOTGraphTraits : public DefaultDOTGraphTraits {
|
||||
DOTGraphTraits (bool simple=false) : DefaultDOTGraphTraits (simple) {}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -52,19 +52,48 @@ template<typename GraphType>
|
||||
class GraphWriter {
|
||||
raw_ostream &O;
|
||||
const GraphType &G;
|
||||
bool ShortNames;
|
||||
|
||||
typedef DOTGraphTraits<GraphType> DOTTraits;
|
||||
typedef GraphTraits<GraphType> GTraits;
|
||||
typedef typename GTraits::NodeType NodeType;
|
||||
typedef typename GTraits::nodes_iterator node_iterator;
|
||||
typedef typename GTraits::ChildIteratorType child_iterator;
|
||||
DOTTraits DTraits;
|
||||
|
||||
// Writes the edge labels of the node to O and returns true if there are any
|
||||
// edge labels not equal to the empty string "".
|
||||
bool getEdgeSourceLabels(raw_ostream &O, NodeType *Node) {
|
||||
child_iterator EI = GTraits::child_begin(Node);
|
||||
child_iterator EE = GTraits::child_end(Node);
|
||||
bool hasEdgeSourceLabels = false;
|
||||
|
||||
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
|
||||
std::string label = DTraits.getEdgeSourceLabel(Node, EI);
|
||||
|
||||
if (label == "")
|
||||
continue;
|
||||
|
||||
hasEdgeSourceLabels = true;
|
||||
|
||||
if (i)
|
||||
O << "|";
|
||||
|
||||
O << "<s" << i << ">" << DTraits.getEdgeSourceLabel(Node, EI);
|
||||
}
|
||||
|
||||
if (EI != EE && hasEdgeSourceLabels)
|
||||
O << "|<s64>truncated...";
|
||||
|
||||
return hasEdgeSourceLabels;
|
||||
}
|
||||
|
||||
public:
|
||||
GraphWriter(raw_ostream &o, const GraphType &g, bool SN) :
|
||||
O(o), G(g), ShortNames(SN) {}
|
||||
GraphWriter(raw_ostream &o, const GraphType &g, bool SN) : O(o), G(g) {
|
||||
DTraits = DOTTraits(SN);
|
||||
}
|
||||
|
||||
void writeHeader(const std::string &Name) {
|
||||
std::string GraphName = DOTTraits::getGraphName(G);
|
||||
std::string GraphName = DTraits.getGraphName(G);
|
||||
|
||||
if (!Name.empty())
|
||||
O << "digraph \"" << DOT::EscapeString(Name) << "\" {\n";
|
||||
@ -73,14 +102,14 @@ class GraphWriter {
|
||||
else
|
||||
O << "digraph unnamed {\n";
|
||||
|
||||
if (DOTTraits::renderGraphFromBottomUp())
|
||||
if (DTraits.renderGraphFromBottomUp())
|
||||
O << "\trankdir=\"BT\";\n";
|
||||
|
||||
if (!Name.empty())
|
||||
O << "\tlabel=\"" << DOT::EscapeString(Name) << "\";\n";
|
||||
else if (!GraphName.empty())
|
||||
O << "\tlabel=\"" << DOT::EscapeString(GraphName) << "\";\n";
|
||||
O << DOTTraits::getGraphProperties(G);
|
||||
O << DTraits.getGraphProperties(G);
|
||||
O << "\n";
|
||||
}
|
||||
|
||||
@ -105,53 +134,47 @@ class GraphWriter {
|
||||
}
|
||||
|
||||
void writeNode(NodeType *Node) {
|
||||
std::string NodeAttributes = DOTTraits::getNodeAttributes(Node, G);
|
||||
std::string NodeAttributes = DTraits.getNodeAttributes(Node, G);
|
||||
|
||||
O << "\tNode" << static_cast<const void*>(Node) << " [shape=record,";
|
||||
if (!NodeAttributes.empty()) O << NodeAttributes << ",";
|
||||
O << "label=\"{";
|
||||
|
||||
if (!DOTTraits::renderGraphFromBottomUp()) {
|
||||
O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G, ShortNames));
|
||||
if (!DTraits.renderGraphFromBottomUp()) {
|
||||
O << DOT::EscapeString(DTraits.getNodeLabel(Node, G));
|
||||
|
||||
// If we should include the address of the node in the label, do so now.
|
||||
if (DOTTraits::hasNodeAddressLabel(Node, G))
|
||||
if (DTraits.hasNodeAddressLabel(Node, G))
|
||||
O << "|" << (void*)Node;
|
||||
}
|
||||
|
||||
// Print out the fields of the current node...
|
||||
child_iterator EI = GTraits::child_begin(Node);
|
||||
child_iterator EE = GTraits::child_end(Node);
|
||||
if (EI != EE) {
|
||||
if (!DOTTraits::renderGraphFromBottomUp()) O << "|";
|
||||
O << "{";
|
||||
std::string edgeSourceLabels;
|
||||
raw_string_ostream EdgeSourceLabels(edgeSourceLabels);
|
||||
bool hasEdgeSourceLabels = getEdgeSourceLabels(EdgeSourceLabels, Node);
|
||||
|
||||
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
|
||||
if (i) O << "|";
|
||||
O << "<s" << i << ">" << DOTTraits::getEdgeSourceLabel(Node, EI);
|
||||
}
|
||||
if (hasEdgeSourceLabels) {
|
||||
if (!DTraits.renderGraphFromBottomUp()) O << "|";
|
||||
|
||||
if (EI != EE)
|
||||
O << "|<s64>truncated...";
|
||||
O << "}";
|
||||
if (DOTTraits::renderGraphFromBottomUp()) O << "|";
|
||||
O << "{" << EdgeSourceLabels.str() << "}";
|
||||
|
||||
if (DTraits.renderGraphFromBottomUp()) O << "|";
|
||||
}
|
||||
|
||||
if (DOTTraits::renderGraphFromBottomUp()) {
|
||||
O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G, ShortNames));
|
||||
if (DTraits.renderGraphFromBottomUp()) {
|
||||
O << DOT::EscapeString(DTraits.getNodeLabel(Node, G));
|
||||
|
||||
// If we should include the address of the node in the label, do so now.
|
||||
if (DOTTraits::hasNodeAddressLabel(Node, G))
|
||||
if (DTraits.hasNodeAddressLabel(Node, G))
|
||||
O << "|" << (void*)Node;
|
||||
}
|
||||
|
||||
if (DOTTraits::hasEdgeDestLabels()) {
|
||||
if (DTraits.hasEdgeDestLabels()) {
|
||||
O << "|{";
|
||||
|
||||
unsigned i = 0, e = DOTTraits::numEdgeDestLabels(Node);
|
||||
unsigned i = 0, e = DTraits.numEdgeDestLabels(Node);
|
||||
for (; i != e && i != 64; ++i) {
|
||||
if (i) O << "|";
|
||||
O << "<d" << i << ">" << DOTTraits::getEdgeDestLabel(Node, i);
|
||||
O << "<d" << i << ">" << DTraits.getEdgeDestLabel(Node, i);
|
||||
}
|
||||
|
||||
if (i != e)
|
||||
@ -162,7 +185,8 @@ class GraphWriter {
|
||||
O << "}\"];\n"; // Finish printing the "node" line
|
||||
|
||||
// Output all of the edges now
|
||||
EI = GTraits::child_begin(Node);
|
||||
child_iterator EI = GTraits::child_begin(Node);
|
||||
child_iterator EE = GTraits::child_end(Node);
|
||||
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
|
||||
writeEdge(Node, i, EI);
|
||||
for (; EI != EE; ++EI)
|
||||
@ -172,8 +196,8 @@ class GraphWriter {
|
||||
void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI) {
|
||||
if (NodeType *TargetNode = *EI) {
|
||||
int DestPort = -1;
|
||||
if (DOTTraits::edgeTargetsEdgeSource(Node, EI)) {
|
||||
child_iterator TargetIt = DOTTraits::getEdgeTarget(Node, EI);
|
||||
if (DTraits.edgeTargetsEdgeSource(Node, EI)) {
|
||||
child_iterator TargetIt = DTraits.getEdgeTarget(Node, EI);
|
||||
|
||||
// Figure out which edge this targets...
|
||||
unsigned Offset =
|
||||
@ -181,9 +205,12 @@ class GraphWriter {
|
||||
DestPort = static_cast<int>(Offset);
|
||||
}
|
||||
|
||||
if (DTraits.getEdgeSourceLabel(Node, EI) == "")
|
||||
edgeidx = -1;
|
||||
|
||||
emitEdge(static_cast<const void*>(Node), edgeidx,
|
||||
static_cast<const void*>(TargetNode), DestPort,
|
||||
DOTTraits::getEdgeAttributes(Node, EI));
|
||||
DTraits.getEdgeAttributes(Node, EI));
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,12 +248,8 @@ class GraphWriter {
|
||||
if (SrcNodePort >= 0)
|
||||
O << ":s" << SrcNodePort;
|
||||
O << " -> Node" << DestNodeID;
|
||||
if (DestNodePort >= 0) {
|
||||
if (DOTTraits::hasEdgeDestLabels())
|
||||
O << ":d" << DestNodePort;
|
||||
else
|
||||
O << ":s" << DestNodePort;
|
||||
}
|
||||
if (DestNodePort >= 0 && DTraits.hasEdgeDestLabels())
|
||||
O << ":d" << DestNodePort;
|
||||
|
||||
if (!Attrs.empty())
|
||||
O << "[" << Attrs << "]";
|
||||
|
@ -174,7 +174,7 @@ class NoFolder {
|
||||
}
|
||||
|
||||
Value *CreateExtractElement(Constant *Vec, Constant *Idx) const {
|
||||
return new ExtractElementInst(Vec, Idx);
|
||||
return ExtractElementInst::Create(Vec, Idx);
|
||||
}
|
||||
|
||||
Value *CreateInsertElement(Constant *Vec, Constant *NewElt,
|
||||
|
@ -120,7 +120,9 @@ class SourceMgr {
|
||||
///
|
||||
/// @param Type - If non-null, the kind of message (e.g., "error") which is
|
||||
/// prefixed to the message.
|
||||
void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
|
||||
/// @param ShowLine - Should the diagnostic show the source line.
|
||||
void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type,
|
||||
bool ShowLine = true) const;
|
||||
|
||||
|
||||
/// GetMessage - Return an SMDiagnostic at the specified location with the
|
||||
@ -128,8 +130,10 @@ class SourceMgr {
|
||||
///
|
||||
/// @param Type - If non-null, the kind of message (e.g., "error") which is
|
||||
/// prefixed to the message.
|
||||
/// @param ShowLine - Should the diagnostic show the source line.
|
||||
SMDiagnostic GetMessage(SMLoc Loc,
|
||||
const std::string &Msg, const char *Type) const;
|
||||
const std::string &Msg, const char *Type,
|
||||
bool ShowLine = true) const;
|
||||
|
||||
|
||||
private:
|
||||
@ -143,12 +147,15 @@ class SMDiagnostic {
|
||||
std::string Filename;
|
||||
int LineNo, ColumnNo;
|
||||
std::string Message, LineContents;
|
||||
unsigned ShowLine : 1;
|
||||
|
||||
public:
|
||||
SMDiagnostic() : LineNo(0), ColumnNo(0) {}
|
||||
SMDiagnostic(const std::string &FN, int Line, int Col,
|
||||
const std::string &Msg, const std::string &LineStr)
|
||||
const std::string &Msg, const std::string &LineStr,
|
||||
bool showline = true)
|
||||
: Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
|
||||
LineContents(LineStr) {}
|
||||
LineContents(LineStr), ShowLine(showline) {}
|
||||
|
||||
void Print(const char *ProgName, raw_ostream &S);
|
||||
};
|
||||
|
@ -380,6 +380,13 @@ namespace sys {
|
||||
/// in the file system.
|
||||
bool canWrite() const;
|
||||
|
||||
/// This function checks that what we're trying to work only on a regular file.
|
||||
/// Check for things like /dev/null, any block special file,
|
||||
/// or other things that aren't "regular" regular files.
|
||||
/// @returns true if the file is S_ISREG.
|
||||
/// @brief Determines if the file is a regular file
|
||||
bool isRegularFile() const;
|
||||
|
||||
/// This function determines if the path name references an executable
|
||||
/// file in the file system. This function checks for the existence and
|
||||
/// executability (by the current program) of the file.
|
||||
|
@ -514,6 +514,13 @@ class TargetInstrInfo {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isPredicable - Return true if the specified instruction can be predicated.
|
||||
/// By default, this returns true for every instruction with a
|
||||
/// PredicateOperand.
|
||||
virtual bool isPredicable(MachineInstr *MI) const {
|
||||
return MI->getDesc().isPredicable();
|
||||
}
|
||||
|
||||
/// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine
|
||||
/// instruction that defines the specified register class.
|
||||
virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
|
||||
@ -536,13 +543,6 @@ class TargetInstrInfo {
|
||||
/// length.
|
||||
virtual unsigned getInlineAsmLength(const char *Str,
|
||||
const MCAsmInfo &MAI) const;
|
||||
|
||||
/// TailDuplicationLimit - Returns the limit on the number of instructions
|
||||
/// in basic block MBB beyond which it will not be tail-duplicated.
|
||||
virtual unsigned TailDuplicationLimit(const MachineBasicBlock &MBB,
|
||||
unsigned DefaultLimit) const {
|
||||
return DefaultLimit;
|
||||
}
|
||||
};
|
||||
|
||||
/// TargetInstrInfoImpl - This is the default implementation of
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define LLVM_TARGET_TARGETJITINFO_H
|
||||
|
||||
#include <cassert>
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -48,22 +49,28 @@ namespace llvm {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Records the required size and alignment for a call stub in bytes.
|
||||
struct StubLayout {
|
||||
size_t Size;
|
||||
size_t Alignment;
|
||||
};
|
||||
/// Returns the maximum size and alignment for a call stub on this target.
|
||||
virtual StubLayout getStubLayout() {
|
||||
llvm_unreachable("This target doesn't implement getStubLayout!");
|
||||
StubLayout Result = {0, 0};
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
|
||||
/// small native function that simply calls the function at the specified
|
||||
/// address. Return the address of the resultant function.
|
||||
virtual void *emitFunctionStub(const Function* F, void *Fn,
|
||||
/// address. The JITCodeEmitter must already have storage allocated for the
|
||||
/// stub. Return the address of the resultant function, which may have been
|
||||
/// aligned from the address the JCE was set up to emit at.
|
||||
virtual void *emitFunctionStub(const Function* F, void *Target,
|
||||
JITCodeEmitter &JCE) {
|
||||
assert(0 && "This target doesn't implement emitFunctionStub!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// emitFunctionStubAtAddr - Use the specified JITCodeEmitter object to
|
||||
/// emit a small native function that simply calls Fn. Emit the stub into
|
||||
/// the supplied buffer.
|
||||
virtual void emitFunctionStubAtAddr(const Function* F, void *Fn,
|
||||
void *Buffer, JITCodeEmitter &JCE) {
|
||||
assert(0 && "This target doesn't implement emitFunctionStubAtAddr!");
|
||||
}
|
||||
|
||||
/// getPICJumpTableEntry - Returns the value of the jumptable entry for the
|
||||
/// specific basic block.
|
||||
|
@ -465,7 +465,7 @@ class TargetRegisterInfo {
|
||||
virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
|
||||
|
||||
/// getSubRegIndex - For a given register pair, return the sub-register index
|
||||
/// if they are second register is a sub-register of the second. Return zero
|
||||
/// if the are second register is a sub-register of the first. Return zero
|
||||
/// otherwise.
|
||||
virtual unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const = 0;
|
||||
|
||||
@ -656,7 +656,9 @@ class TargetRegisterInfo {
|
||||
MachineBasicBlock::iterator I,
|
||||
MachineBasicBlock::iterator &UseMI,
|
||||
const TargetRegisterClass *RC,
|
||||
unsigned Reg) const {return false;}
|
||||
unsigned Reg) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// eliminateFrameIndex - This method must be overriden to eliminate abstract
|
||||
/// frame indices from instructions which may use them. The instruction
|
||||
@ -696,6 +698,18 @@ class TargetRegisterInfo {
|
||||
/// the stack frame of the specified index.
|
||||
virtual int getFrameIndexOffset(MachineFunction &MF, int FI) const;
|
||||
|
||||
/// getFrameIndexReference - This method should return the base register
|
||||
/// and offset used to reference a frame index location. The offset is
|
||||
/// returned directly, and the base register is returned via FrameReg.
|
||||
virtual int getFrameIndexReference(MachineFunction &MF, int FI,
|
||||
unsigned &FrameReg) const {
|
||||
// By default, assume all frame indices are referenced via whatever
|
||||
// getFrameRegister() says. The target can override this if it's doing
|
||||
// something different.
|
||||
FrameReg = getFrameRegister(MF);
|
||||
return getFrameIndexOffset(MF, FI);
|
||||
}
|
||||
|
||||
/// getRARegister - This method should return the register where the return
|
||||
/// address can be found.
|
||||
virtual unsigned getRARegister() const = 0;
|
||||
|
@ -33,6 +33,10 @@ extern "C" {
|
||||
// Declare all of the available assembly parser initialization functions.
|
||||
#define LLVM_ASM_PARSER(TargetName) void LLVMInitialize##TargetName##AsmParser();
|
||||
#include "llvm/Config/AsmParsers.def"
|
||||
|
||||
// Declare all of the available disassembler initialization functions.
|
||||
#define LLVM_DISASSEMBLER(TargetName) void LLVMInitialize##TargetName##Disassembler();
|
||||
#include "llvm/Config/Disassemblers.def"
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
@ -79,6 +83,16 @@ namespace llvm {
|
||||
#include "llvm/Config/AsmParsers.def"
|
||||
}
|
||||
|
||||
/// InitializeAllDisassemblers - The main program should call this function if
|
||||
/// it wants all disassemblers that LLVM is configured to support, to make
|
||||
/// them available via the TargetRegistry.
|
||||
///
|
||||
/// It is legal for a client to make multiple calls to this function.
|
||||
inline void InitializeAllDisassemblers() {
|
||||
#define LLVM_DISASSEMBLER(TargetName) LLVMInitialize##TargetName##Disassembler();
|
||||
#include "llvm/Config/Disassemblers.def"
|
||||
}
|
||||
|
||||
/// InitializeNativeTarget - The main program should call this function to
|
||||
/// initialize the native target corresponding to the host. This is useful
|
||||
/// for JIT applications to ensure that the target gets linked in correctly.
|
||||
|
@ -864,10 +864,3 @@ class ComplexPattern<ValueType ty, int numops, string fn,
|
||||
list<SDNodeProperty> Properties = props;
|
||||
list<CPAttribute> Attributes = attrs;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Dwarf support.
|
||||
//
|
||||
def SDT_dwarf_loc : SDTypeProfile<0, 3,
|
||||
[SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
|
||||
def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>;
|
||||
|
@ -23,7 +23,6 @@ class AllocaInst;
|
||||
class DominatorTree;
|
||||
class DominanceFrontier;
|
||||
class AliasSetTracker;
|
||||
class LLVMContext;
|
||||
|
||||
/// isAllocaPromotable - Return true if this alloca is legal for promotion.
|
||||
/// This is true if there are only loads and stores to the alloca...
|
||||
@ -40,7 +39,6 @@ bool isAllocaPromotable(const AllocaInst *AI);
|
||||
///
|
||||
void PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
|
||||
DominatorTree &DT, DominanceFrontier &DF,
|
||||
LLVMContext &Context,
|
||||
AliasSetTracker *AST = 0);
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -49,21 +49,11 @@ AliasAnalysis::alias(const Value *V1, unsigned V1Size,
|
||||
return AA->alias(V1, V1Size, V2, V2Size);
|
||||
}
|
||||
|
||||
void AliasAnalysis::getMustAliases(Value *P, std::vector<Value*> &RetVals) {
|
||||
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
|
||||
return AA->getMustAliases(P, RetVals);
|
||||
}
|
||||
|
||||
bool AliasAnalysis::pointsToConstantMemory(const Value *P) {
|
||||
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
|
||||
return AA->pointsToConstantMemory(P);
|
||||
}
|
||||
|
||||
bool AliasAnalysis::hasNoModRefInfoForCalls() const {
|
||||
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
|
||||
return AA->hasNoModRefInfoForCalls();
|
||||
}
|
||||
|
||||
void AliasAnalysis::deleteValue(Value *V) {
|
||||
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
|
||||
AA->deleteValue(V);
|
||||
@ -137,17 +127,18 @@ AliasAnalysis::getModRefBehavior(Function *F,
|
||||
|
||||
AliasAnalysis::ModRefResult
|
||||
AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
|
||||
ModRefResult Mask = ModRef;
|
||||
ModRefBehavior MRB = getModRefBehavior(CS);
|
||||
if (MRB == DoesNotAccessMemory)
|
||||
return NoModRef;
|
||||
else if (MRB == OnlyReadsMemory)
|
||||
|
||||
ModRefResult Mask = ModRef;
|
||||
if (MRB == OnlyReadsMemory)
|
||||
Mask = Ref;
|
||||
else if (MRB == AliasAnalysis::AccessesArguments) {
|
||||
bool doesAlias = false;
|
||||
for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
|
||||
AI != AE; ++AI)
|
||||
if (alias(*AI, ~0U, P, Size) != NoAlias) {
|
||||
if (!isNoAlias(*AI, ~0U, P, Size)) {
|
||||
doesAlias = true;
|
||||
break;
|
||||
}
|
||||
|
@ -90,11 +90,6 @@ namespace {
|
||||
return AliasAnalysis::getModRefInfo(CS1,CS2);
|
||||
}
|
||||
|
||||
void getMustAliases(Value *P, std::vector<Value*> &RetVals) {
|
||||
assert(Vals.find(P) != Vals.end() && "Never seen value in AA before");
|
||||
return AliasAnalysis::getMustAliases(P, RetVals);
|
||||
}
|
||||
|
||||
bool pointsToConstantMemory(const Value *P) {
|
||||
assert(Vals.find(P) != Vals.end() && "Never seen value in AA before");
|
||||
return AliasAnalysis::pointsToConstantMemory(P);
|
||||
|
@ -153,9 +153,6 @@ bool AliasSet::aliasesPointer(const Value *Ptr, unsigned Size,
|
||||
|
||||
// Check the call sites list and invoke list...
|
||||
if (!CallSites.empty()) {
|
||||
if (AA.hasNoModRefInfoForCalls())
|
||||
return true;
|
||||
|
||||
for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
|
||||
if (AA.getModRefInfo(CallSites[i], const_cast<Value*>(Ptr), Size)
|
||||
!= AliasAnalysis::NoModRef)
|
||||
@ -169,9 +166,6 @@ bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const {
|
||||
if (AA.doesNotAccessMemory(CS))
|
||||
return false;
|
||||
|
||||
if (AA.hasNoModRefInfoForCalls())
|
||||
return true;
|
||||
|
||||
for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
|
||||
if (AA.getModRefInfo(CallSites[i], CS) != AliasAnalysis::NoModRef ||
|
||||
AA.getModRefInfo(CS, CallSites[i]) != AliasAnalysis::NoModRef)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@
|
||||
#include "llvm/Analysis/CaptureTracking.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Value.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/CallSite.h"
|
||||
@ -28,8 +29,11 @@ using namespace llvm;
|
||||
/// by the enclosing function (which is required to exist). This routine can
|
||||
/// be expensive, so consider caching the results. The boolean ReturnCaptures
|
||||
/// specifies whether returning the value (or part of it) from the function
|
||||
/// counts as capturing it or not. The boolean StoreCaptures specified whether
|
||||
/// storing the value (or part of it) into memory anywhere automatically
|
||||
/// counts as capturing it or not.
|
||||
bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
|
||||
bool llvm::PointerMayBeCaptured(const Value *V,
|
||||
bool ReturnCaptures, bool StoreCaptures) {
|
||||
assert(isa<PointerType>(V->getType()) && "Capture is for pointers only!");
|
||||
SmallVector<Use*, 16> Worklist;
|
||||
SmallSet<Use*, 16> Visited;
|
||||
@ -53,8 +57,7 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
|
||||
// Not captured if the callee is readonly, doesn't return a copy through
|
||||
// its return value and doesn't unwind (a readonly function can leak bits
|
||||
// by throwing an exception or not depending on the input value).
|
||||
if (CS.onlyReadsMemory() && CS.doesNotThrow() &&
|
||||
I->getType() == Type::getVoidTy(V->getContext()))
|
||||
if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType()->isVoidTy())
|
||||
break;
|
||||
|
||||
// Not captured if only passed via 'nocapture' arguments. Note that
|
||||
@ -82,7 +85,11 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
|
||||
break;
|
||||
case Instruction::Store:
|
||||
if (V == I->getOperand(0))
|
||||
// Stored the pointer - it may be captured.
|
||||
// Stored the pointer - conservatively assume it may be captured.
|
||||
// TODO: If StoreCaptures is not true, we could do Fancy analysis
|
||||
// to determine whether this store is not actually an escape point.
|
||||
// In that case, BasicAliasAnalysis should be updated as well to
|
||||
// take advantage of this.
|
||||
return true;
|
||||
// Storing to the pointee does not cause the pointer to be captured.
|
||||
break;
|
||||
@ -98,6 +105,18 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
|
||||
Worklist.push_back(U);
|
||||
}
|
||||
break;
|
||||
case Instruction::ICmp:
|
||||
// Don't count comparisons of a no-alias return value against null as
|
||||
// captures. This allows us to ignore comparisons of malloc results
|
||||
// with null, for example.
|
||||
if (isNoAliasCall(V->stripPointerCasts()))
|
||||
if (ConstantPointerNull *CPN =
|
||||
dyn_cast<ConstantPointerNull>(I->getOperand(1)))
|
||||
if (CPN->getType()->getAddressSpace() == 0)
|
||||
break;
|
||||
// Otherwise, be conservative. There are crazy ways to capture pointers
|
||||
// using comparisons.
|
||||
return true;
|
||||
default:
|
||||
// Something else - be conservative and say it is captured.
|
||||
return true;
|
||||
|
@ -564,6 +564,7 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps,
|
||||
// we eliminate over-indexing of the notional static type array bounds.
|
||||
// This makes it easy to determine if the getelementptr is "inbounds".
|
||||
// Also, this helps GlobalOpt do SROA on GlobalVariables.
|
||||
Ptr = cast<Constant>(Ptr->stripPointerCasts());
|
||||
const Type *Ty = Ptr->getType();
|
||||
SmallVector<Constant*, 32> NewIdxs;
|
||||
do {
|
||||
@ -671,8 +672,13 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
|
||||
Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE,
|
||||
const TargetData *TD) {
|
||||
SmallVector<Constant*, 8> Ops;
|
||||
for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
|
||||
Ops.push_back(cast<Constant>(*i));
|
||||
for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) {
|
||||
Constant *NewC = cast<Constant>(*i);
|
||||
// Recursively fold the ConstantExpr's operands.
|
||||
if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC))
|
||||
NewC = ConstantFoldConstantExpression(NewCE, TD);
|
||||
Ops.push_back(NewC);
|
||||
}
|
||||
|
||||
if (CE->isCompare())
|
||||
return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1],
|
||||
@ -687,6 +693,10 @@ Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE,
|
||||
/// attempting to fold instructions like loads and stores, which have no
|
||||
/// constant expression form.
|
||||
///
|
||||
/// TODO: This function neither utilizes nor preserves nsw/nuw/inbounds/etc
|
||||
/// information, due to only being passed an opcode and operands. Constant
|
||||
/// folding using this function strips this information.
|
||||
///
|
||||
Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
|
||||
Constant* const* Ops, unsigned NumOps,
|
||||
const TargetData *TD) {
|
||||
|
@ -78,19 +78,16 @@ DIDescriptor::DIDescriptor(MDNode *N, unsigned RequiredTag) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
StringRef
|
||||
DIDescriptor::getStringField(unsigned Elt) const {
|
||||
if (DbgNode == 0)
|
||||
return NULL;
|
||||
return StringRef();
|
||||
|
||||
if (Elt < DbgNode->getNumElements())
|
||||
if (MDString *MDS = dyn_cast_or_null<MDString>(DbgNode->getElement(Elt))) {
|
||||
if (MDS->getLength() == 0)
|
||||
return NULL;
|
||||
return MDS->getString().data();
|
||||
}
|
||||
if (MDString *MDS = dyn_cast_or_null<MDString>(DbgNode->getElement(Elt)))
|
||||
return MDS->getString();
|
||||
|
||||
return NULL;
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
|
||||
@ -310,8 +307,8 @@ void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) {
|
||||
bool DICompileUnit::Verify() const {
|
||||
if (isNull())
|
||||
return false;
|
||||
const char *N = getFilename();
|
||||
if (!N)
|
||||
StringRef N = getFilename();
|
||||
if (N.empty())
|
||||
return false;
|
||||
// It is possible that directory and produce string is empty.
|
||||
return true;
|
||||
@ -366,7 +363,7 @@ bool DIGlobalVariable::Verify() const {
|
||||
if (isNull())
|
||||
return false;
|
||||
|
||||
if (!getDisplayName())
|
||||
if (getDisplayName().empty())
|
||||
return false;
|
||||
|
||||
if (getContext().isNull())
|
||||
@ -426,15 +423,15 @@ uint64_t DIDerivedType::getOriginalTypeSize() const {
|
||||
/// information for the function F.
|
||||
bool DISubprogram::describes(const Function *F) {
|
||||
assert (F && "Invalid function");
|
||||
const char *Name = getLinkageName();
|
||||
if (!Name)
|
||||
StringRef Name = getLinkageName();
|
||||
if (Name.empty())
|
||||
Name = getName();
|
||||
if (strcmp(F->getName().data(), Name) == 0)
|
||||
if (F->getName() == Name)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *DIScope::getFilename() const {
|
||||
StringRef DIScope::getFilename() const {
|
||||
if (isLexicalBlock())
|
||||
return DILexicalBlock(DbgNode).getFilename();
|
||||
else if (isSubprogram())
|
||||
@ -443,10 +440,10 @@ const char *DIScope::getFilename() const {
|
||||
return DICompileUnit(DbgNode).getFilename();
|
||||
else
|
||||
assert (0 && "Invalid DIScope!");
|
||||
return NULL;
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
const char *DIScope::getDirectory() const {
|
||||
StringRef DIScope::getDirectory() const {
|
||||
if (isLexicalBlock())
|
||||
return DILexicalBlock(DbgNode).getDirectory();
|
||||
else if (isSubprogram())
|
||||
@ -455,7 +452,7 @@ const char *DIScope::getDirectory() const {
|
||||
return DICompileUnit(DbgNode).getDirectory();
|
||||
else
|
||||
assert (0 && "Invalid DIScope!");
|
||||
return NULL;
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -481,7 +478,8 @@ void DICompileUnit::dump() const {
|
||||
void DIType::dump() const {
|
||||
if (isNull()) return;
|
||||
|
||||
if (const char *Res = getName())
|
||||
StringRef Res = getName();
|
||||
if (!Res.empty())
|
||||
errs() << " [" << Res << "] ";
|
||||
|
||||
unsigned Tag = getTag();
|
||||
@ -538,7 +536,8 @@ void DICompositeType::dump() const {
|
||||
|
||||
/// dump - Print global.
|
||||
void DIGlobal::dump() const {
|
||||
if (const char *Res = getName())
|
||||
StringRef Res = getName();
|
||||
if (!Res.empty())
|
||||
errs() << " [" << Res << "] ";
|
||||
|
||||
unsigned Tag = getTag();
|
||||
@ -562,7 +561,8 @@ void DIGlobal::dump() const {
|
||||
|
||||
/// dump - Print subprogram.
|
||||
void DISubprogram::dump() const {
|
||||
if (const char *Res = getName())
|
||||
StringRef Res = getName();
|
||||
if (!Res.empty())
|
||||
errs() << " [" << Res << "] ";
|
||||
|
||||
unsigned Tag = getTag();
|
||||
@ -590,7 +590,8 @@ void DIGlobalVariable::dump() const {
|
||||
|
||||
/// dump - Print variable.
|
||||
void DIVariable::dump() const {
|
||||
if (const char *Res = getName())
|
||||
StringRef Res = getName();
|
||||
if (!Res.empty())
|
||||
errs() << " [" << Res << "] ";
|
||||
|
||||
getCompileUnit().dump();
|
||||
@ -651,12 +652,12 @@ DISubrange DIFactory::GetOrCreateSubrange(int64_t Lo, int64_t Hi) {
|
||||
/// CreateCompileUnit - Create a new descriptor for the specified compile
|
||||
/// unit. Note that this does not unique compile units within the module.
|
||||
DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
|
||||
const char * Filename,
|
||||
const char * Directory,
|
||||
const char * Producer,
|
||||
StringRef Filename,
|
||||
StringRef Directory,
|
||||
StringRef Producer,
|
||||
bool isMain,
|
||||
bool isOptimized,
|
||||
const char *Flags,
|
||||
StringRef Flags,
|
||||
unsigned RunTimeVer) {
|
||||
Value *Elts[] = {
|
||||
GetTagConstant(dwarf::DW_TAG_compile_unit),
|
||||
@ -675,7 +676,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
|
||||
}
|
||||
|
||||
/// CreateEnumerator - Create a single enumerator value.
|
||||
DIEnumerator DIFactory::CreateEnumerator(const char * Name, uint64_t Val){
|
||||
DIEnumerator DIFactory::CreateEnumerator(StringRef Name, uint64_t Val){
|
||||
Value *Elts[] = {
|
||||
GetTagConstant(dwarf::DW_TAG_enumerator),
|
||||
MDString::get(VMContext, Name),
|
||||
@ -687,7 +688,7 @@ DIEnumerator DIFactory::CreateEnumerator(const char * Name, uint64_t Val){
|
||||
|
||||
/// CreateBasicType - Create a basic type like int, float, etc.
|
||||
DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
uint64_t SizeInBits,
|
||||
@ -712,7 +713,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
|
||||
|
||||
/// CreateBasicType - Create a basic type like int, float, etc.
|
||||
DIBasicType DIFactory::CreateBasicTypeEx(DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
Constant *SizeInBits,
|
||||
@ -739,7 +740,7 @@ DIBasicType DIFactory::CreateBasicTypeEx(DIDescriptor Context,
|
||||
/// pointer, typedef, etc.
|
||||
DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
|
||||
DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
uint64_t SizeInBits,
|
||||
@ -767,7 +768,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
|
||||
/// pointer, typedef, etc.
|
||||
DIDerivedType DIFactory::CreateDerivedTypeEx(unsigned Tag,
|
||||
DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
Constant *SizeInBits,
|
||||
@ -794,7 +795,7 @@ DIDerivedType DIFactory::CreateDerivedTypeEx(unsigned Tag,
|
||||
/// CreateCompositeType - Create a composite type like array, struct, etc.
|
||||
DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
|
||||
DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
uint64_t SizeInBits,
|
||||
@ -826,7 +827,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
|
||||
/// CreateCompositeType - Create a composite type like array, struct, etc.
|
||||
DICompositeType DIFactory::CreateCompositeTypeEx(unsigned Tag,
|
||||
DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
Constant *SizeInBits,
|
||||
@ -859,9 +860,9 @@ DICompositeType DIFactory::CreateCompositeTypeEx(unsigned Tag,
|
||||
/// See comments in DISubprogram for descriptions of these fields. This
|
||||
/// method does not unique the generated descriptors.
|
||||
DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
|
||||
const char * Name,
|
||||
const char * DisplayName,
|
||||
const char * LinkageName,
|
||||
StringRef Name,
|
||||
StringRef DisplayName,
|
||||
StringRef LinkageName,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNo, DIType Type,
|
||||
bool isLocalToUnit,
|
||||
@ -885,9 +886,9 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
|
||||
|
||||
/// CreateGlobalVariable - Create a new descriptor for the specified global.
|
||||
DIGlobalVariable
|
||||
DIFactory::CreateGlobalVariable(DIDescriptor Context, const char * Name,
|
||||
const char * DisplayName,
|
||||
const char * LinkageName,
|
||||
DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name,
|
||||
StringRef DisplayName,
|
||||
StringRef LinkageName,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNo, DIType Type,bool isLocalToUnit,
|
||||
bool isDefinition, llvm::GlobalVariable *Val) {
|
||||
@ -919,7 +920,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const char * Name,
|
||||
|
||||
/// CreateVariable - Create a new descriptor for the specified variable.
|
||||
DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
|
||||
const char * Name,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit, unsigned LineNo,
|
||||
DIType Type) {
|
||||
Value *Elts[] = {
|
||||
@ -976,6 +977,17 @@ DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo,
|
||||
return DILocation(MDNode::get(VMContext, &Elts[0], 4));
|
||||
}
|
||||
|
||||
/// CreateLocation - Creates a debug info location.
|
||||
DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo,
|
||||
DIScope S, MDNode *OrigLoc) {
|
||||
Value *Elts[] = {
|
||||
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
|
||||
ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo),
|
||||
S.getNode(),
|
||||
OrigLoc
|
||||
};
|
||||
return DILocation(MDNode::get(VMContext, &Elts[0], 4));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DIFactory: Routines for inserting code into a function
|
||||
@ -1263,7 +1275,8 @@ bool getLocationInfo(const Value *V, std::string &DisplayName,
|
||||
if (!DIGV) return false;
|
||||
DIGlobalVariable Var(cast<MDNode>(DIGV));
|
||||
|
||||
if (const char *D = Var.getDisplayName())
|
||||
StringRef D = Var.getDisplayName();
|
||||
if (!D.empty())
|
||||
DisplayName = D;
|
||||
LineNo = Var.getLineNumber();
|
||||
Unit = Var.getCompileUnit();
|
||||
@ -1273,18 +1286,22 @@ bool getLocationInfo(const Value *V, std::string &DisplayName,
|
||||
if (!DDI) return false;
|
||||
DIVariable Var(cast<MDNode>(DDI->getVariable()));
|
||||
|
||||
if (const char *D = Var.getName())
|
||||
StringRef D = Var.getName();
|
||||
if (!D.empty())
|
||||
DisplayName = D;
|
||||
LineNo = Var.getLineNumber();
|
||||
Unit = Var.getCompileUnit();
|
||||
TypeD = Var.getType();
|
||||
}
|
||||
|
||||
if (const char *T = TypeD.getName())
|
||||
StringRef T = TypeD.getName();
|
||||
if (!T.empty())
|
||||
Type = T;
|
||||
if (const char *F = Unit.getFilename())
|
||||
StringRef F = Unit.getFilename();
|
||||
if (!F.empty())
|
||||
File = F;
|
||||
if (const char *D = Unit.getDirectory())
|
||||
StringRef D = Unit.getDirectory();
|
||||
if (!D.empty())
|
||||
Dir = D;
|
||||
return true;
|
||||
}
|
||||
@ -1398,4 +1415,36 @@ bool getLocationInfo(const Value *V, std::string &DisplayName,
|
||||
|
||||
return DebugLoc::get(Id);
|
||||
}
|
||||
|
||||
/// getDISubprogram - Find subprogram that is enclosing this scope.
|
||||
DISubprogram getDISubprogram(MDNode *Scope) {
|
||||
DIDescriptor D(Scope);
|
||||
if (D.isNull())
|
||||
return DISubprogram();
|
||||
|
||||
if (D.isCompileUnit())
|
||||
return DISubprogram();
|
||||
|
||||
if (D.isSubprogram())
|
||||
return DISubprogram(Scope);
|
||||
|
||||
if (D.isLexicalBlock())
|
||||
return getDISubprogram(DILexicalBlock(Scope).getContext().getNode());
|
||||
|
||||
return DISubprogram();
|
||||
}
|
||||
|
||||
/// getDICompositeType - Find underlying composite type.
|
||||
DICompositeType getDICompositeType(DIType T) {
|
||||
if (T.isNull())
|
||||
return DICompositeType();
|
||||
|
||||
if (T.isCompositeType())
|
||||
return DICompositeType(T.getNode());
|
||||
|
||||
if (T.isDerivedType())
|
||||
return getDICompositeType(DIDerivedType(T.getNode()).getTypeDerivedFrom());
|
||||
|
||||
return DICompositeType();
|
||||
}
|
||||
}
|
||||
|
@ -30,46 +30,55 @@ using namespace llvm;
|
||||
namespace llvm {
|
||||
template<>
|
||||
struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
|
||||
static std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph,
|
||||
bool ShortNames) {
|
||||
|
||||
DOTGraphTraits (bool isSimple=false)
|
||||
: DefaultDOTGraphTraits(isSimple) {}
|
||||
|
||||
std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
|
||||
|
||||
BasicBlock *BB = Node->getBlock();
|
||||
|
||||
if (!BB)
|
||||
return "Post dominance root node";
|
||||
|
||||
return DOTGraphTraits<const Function*>::getNodeLabel(BB, BB->getParent(),
|
||||
ShortNames);
|
||||
|
||||
if (isSimple())
|
||||
return DOTGraphTraits<const Function*>
|
||||
::getSimpleNodeLabel(BB, BB->getParent());
|
||||
else
|
||||
return DOTGraphTraits<const Function*>
|
||||
::getCompleteNodeLabel(BB, BB->getParent());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
|
||||
|
||||
DOTGraphTraits (bool isSimple=false)
|
||||
: DOTGraphTraits<DomTreeNode*>(isSimple) {}
|
||||
|
||||
static std::string getGraphName(DominatorTree *DT) {
|
||||
return "Dominator tree";
|
||||
}
|
||||
|
||||
static std::string getNodeLabel(DomTreeNode *Node,
|
||||
DominatorTree *G,
|
||||
bool ShortNames) {
|
||||
return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode(),
|
||||
ShortNames);
|
||||
std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
|
||||
return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct DOTGraphTraits<PostDominatorTree*>
|
||||
: public DOTGraphTraits<DomTreeNode*> {
|
||||
|
||||
DOTGraphTraits (bool isSimple=false)
|
||||
: DOTGraphTraits<DomTreeNode*>(isSimple) {}
|
||||
|
||||
static std::string getGraphName(PostDominatorTree *DT) {
|
||||
return "Post dominator tree";
|
||||
}
|
||||
static std::string getNodeLabel(DomTreeNode *Node,
|
||||
PostDominatorTree *G,
|
||||
bool ShortNames) {
|
||||
return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node,
|
||||
G->getRootNode(),
|
||||
ShortNames);
|
||||
|
||||
std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
|
||||
return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -85,9 +94,11 @@ struct GenericGraphViewer : public FunctionPass {
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
Analysis *Graph;
|
||||
|
||||
std::string Title, GraphName;
|
||||
Graph = &getAnalysis<Analysis>();
|
||||
ViewGraph(Graph, Name, OnlyBBS);
|
||||
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||
Title = GraphName + " for '" + F.getNameStr() + "' function";
|
||||
ViewGraph(Graph, Name, OnlyBBS, Title);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -163,8 +174,12 @@ struct GenericGraphPrinter : public FunctionPass {
|
||||
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
|
||||
Graph = &getAnalysis<Analysis>();
|
||||
|
||||
std::string Title, GraphName;
|
||||
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||
Title = GraphName + " for '" + F.getNameStr() + "' function";
|
||||
|
||||
if (ErrorInfo.empty())
|
||||
WriteGraph(File, Graph, OnlyBBS);
|
||||
WriteGraph(File, Graph, OnlyBBS, Name, Title);
|
||||
else
|
||||
errs() << " error opening file for writing!";
|
||||
errs() << "\n";
|
||||
|
@ -484,7 +484,6 @@ namespace {
|
||||
const Value *V2, unsigned V2Size);
|
||||
virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
|
||||
virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
|
||||
void getMustAliases(Value *P, std::vector<Value*> &RetVals);
|
||||
bool pointsToConstantMemory(const Value *P);
|
||||
|
||||
virtual void deleteValue(Value *V) {
|
||||
@ -680,32 +679,6 @@ Andersens::getModRefInfo(CallSite CS1, CallSite CS2) {
|
||||
return AliasAnalysis::getModRefInfo(CS1,CS2);
|
||||
}
|
||||
|
||||
/// getMustAlias - We can provide must alias information if we know that a
|
||||
/// pointer can only point to a specific function or the null pointer.
|
||||
/// Unfortunately we cannot determine must-alias information for global
|
||||
/// variables or any other memory memory objects because we do not track whether
|
||||
/// a pointer points to the beginning of an object or a field of it.
|
||||
void Andersens::getMustAliases(Value *P, std::vector<Value*> &RetVals) {
|
||||
Node *N = &GraphNodes[FindNode(getNode(P))];
|
||||
if (N->PointsTo->count() == 1) {
|
||||
Node *Pointee = &GraphNodes[N->PointsTo->find_first()];
|
||||
// If a function is the only object in the points-to set, then it must be
|
||||
// the destination. Note that we can't handle global variables here,
|
||||
// because we don't know if the pointer is actually pointing to a field of
|
||||
// the global or to the beginning of it.
|
||||
if (Value *V = Pointee->getValue()) {
|
||||
if (Function *F = dyn_cast<Function>(V))
|
||||
RetVals.push_back(F);
|
||||
} else {
|
||||
// If the object in the points-to set is the null object, then the null
|
||||
// pointer is a must alias.
|
||||
if (Pointee == &GraphNodes[NullObject])
|
||||
RetVals.push_back(Constant::getNullValue(P->getType()));
|
||||
}
|
||||
}
|
||||
AliasAnalysis::getMustAliases(P, RetVals);
|
||||
}
|
||||
|
||||
/// pointsToConstantMemory - If we can determine that this pointer only points
|
||||
/// to constant memory, return true. In practice, this means that if the
|
||||
/// pointer can only point to constant globals, functions, or the null pointer,
|
||||
|
@ -111,7 +111,6 @@ namespace {
|
||||
ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
|
||||
return AliasAnalysis::getModRefInfo(CS1,CS2);
|
||||
}
|
||||
bool hasNoModRefInfoForCalls() const { return false; }
|
||||
|
||||
/// getModRefBehavior - Return the behavior of the specified function if
|
||||
/// called from the specified call site. The call site may be null in which
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
|
||||
@ -32,10 +31,6 @@ char IVUsers::ID = 0;
|
||||
static RegisterPass<IVUsers>
|
||||
X("iv-users", "Induction Variable Users", false, true);
|
||||
|
||||
static cl::opt<bool>
|
||||
SimplifyIVUsers("simplify-iv-users", cl::Hidden, cl::init(false),
|
||||
cl::desc("Restrict IV Users to loop-invariant strides"));
|
||||
|
||||
Pass *llvm::createIVUsersPass() {
|
||||
return new IVUsers();
|
||||
}
|
||||
@ -214,8 +209,7 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
|
||||
return false; // Non-reducible symbolic expression, bail out.
|
||||
|
||||
// Keep things simple. Don't touch loop-variant strides.
|
||||
if (SimplifyIVUsers && !Stride->isLoopInvariant(L)
|
||||
&& L->contains(I->getParent()))
|
||||
if (!Stride->isLoopInvariant(L) && L->contains(I->getParent()))
|
||||
return false;
|
||||
|
||||
SmallPtrSet<Instruction *, 4> UniqueUsers;
|
||||
|
@ -21,10 +21,38 @@
|
||||
using namespace llvm;
|
||||
using namespace llvm::PatternMatch;
|
||||
|
||||
/// SimplifyAddInst - Given operands for an Add, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const TargetData *TD) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::Add, CLHS->getType(),
|
||||
Ops, 2, TD);
|
||||
}
|
||||
|
||||
// Canonicalize the constant to the RHS.
|
||||
std::swap(Op0, Op1);
|
||||
}
|
||||
|
||||
if (Constant *Op1C = dyn_cast<Constant>(Op1)) {
|
||||
// X + undef -> undef
|
||||
if (isa<UndefValue>(Op1C))
|
||||
return Op1C;
|
||||
|
||||
// X + 0 --> X
|
||||
if (Op1C->isNullValue())
|
||||
return Op0;
|
||||
}
|
||||
|
||||
// FIXME: Could pull several more out of instcombine.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// SimplifyAndInst - Given operands for an And, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1,
|
||||
const TargetData *TD) {
|
||||
Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
@ -83,8 +111,7 @@ Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1,
|
||||
|
||||
/// SimplifyOrInst - Given operands for an Or, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1,
|
||||
const TargetData *TD) {
|
||||
Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
@ -142,8 +169,6 @@ Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static const Type *GetCompareTy(Value *Op) {
|
||||
return CmpInst::makeCmpResultType(Op->getType());
|
||||
}
|
||||
@ -264,6 +289,34 @@ Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps,
|
||||
const TargetData *TD) {
|
||||
// getelementptr P -> P.
|
||||
if (NumOps == 1)
|
||||
return Ops[0];
|
||||
|
||||
// TODO.
|
||||
//if (isa<UndefValue>(Ops[0]))
|
||||
// return UndefValue::get(GEP.getType());
|
||||
|
||||
// getelementptr P, 0 -> P.
|
||||
if (NumOps == 2)
|
||||
if (ConstantInt *C = dyn_cast<ConstantInt>(Ops[1]))
|
||||
if (C->isZero())
|
||||
return Ops[0];
|
||||
|
||||
// Check to see if this is constant foldable.
|
||||
for (unsigned i = 0; i != NumOps; ++i)
|
||||
if (!isa<Constant>(Ops[i]))
|
||||
return 0;
|
||||
|
||||
return ConstantExpr::getGetElementPtr(cast<Constant>(Ops[0]),
|
||||
(Constant *const*)Ops+1, NumOps-1);
|
||||
}
|
||||
|
||||
|
||||
//=== Helper functions for higher up the class hierarchy.
|
||||
|
||||
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
|
||||
@ -299,6 +352,10 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD) {
|
||||
switch (I->getOpcode()) {
|
||||
default:
|
||||
return ConstantFoldInstruction(I, TD);
|
||||
case Instruction::Add:
|
||||
return SimplifyAddInst(I->getOperand(0), I->getOperand(1),
|
||||
cast<BinaryOperator>(I)->hasNoSignedWrap(),
|
||||
cast<BinaryOperator>(I)->hasNoUnsignedWrap(), TD);
|
||||
case Instruction::And:
|
||||
return SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD);
|
||||
case Instruction::Or:
|
||||
@ -309,6 +366,10 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD) {
|
||||
case Instruction::FCmp:
|
||||
return SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
|
||||
I->getOperand(0), I->getOperand(1), TD);
|
||||
case Instruction::GetElementPtr: {
|
||||
SmallVector<Value*, 8> Ops(I->op_begin(), I->op_end());
|
||||
return SimplifyGEPInst(&Ops[0], Ops.size(), TD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,6 +243,11 @@ unsigned Loop::getSmallConstantTripMultiple() const {
|
||||
case BinaryOperator::Mul:
|
||||
Result = dyn_cast<ConstantInt>(BO->getOperand(1));
|
||||
break;
|
||||
case BinaryOperator::Shl:
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1)))
|
||||
if (CI->getValue().getActiveBits() <= 5)
|
||||
return 1u << CI->getZExtValue();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "llvm/IntrinsicInst.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/MemoryBuiltins.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
@ -117,10 +119,6 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall,
|
||||
Pointer = Inst->getOperand(1);
|
||||
// calls to free() erase the entire structure
|
||||
PointerSize = ~0ULL;
|
||||
} else if (isFreeCall(Inst)) {
|
||||
Pointer = Inst->getOperand(0);
|
||||
// calls to free() erase the entire structure
|
||||
PointerSize = ~0ULL;
|
||||
} else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
|
||||
// Debug intrinsics don't cause dependences.
|
||||
if (isa<DbgInfoIntrinsic>(Inst)) continue;
|
||||
@ -174,7 +172,7 @@ MemDepResult MemoryDependenceAnalysis::
|
||||
getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
|
||||
BasicBlock::iterator ScanIt, BasicBlock *BB) {
|
||||
|
||||
Value* invariantTag = 0;
|
||||
Value *invariantTag = 0;
|
||||
|
||||
// Walk backwards through the basic block, looking for dependencies.
|
||||
while (ScanIt != BB->begin()) {
|
||||
@ -185,12 +183,12 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
|
||||
if (invariantTag == Inst) {
|
||||
invariantTag = 0;
|
||||
continue;
|
||||
} else if (IntrinsicInst* II = dyn_cast<IntrinsicInst>(Inst)) {
|
||||
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
|
||||
// If we pass an invariant-end marker, then we've just entered an
|
||||
// invariant region and can start ignoring dependencies.
|
||||
if (II->getIntrinsicID() == Intrinsic::invariant_end) {
|
||||
uint64_t invariantSize = ~0ULL;
|
||||
if (ConstantInt* CI = dyn_cast<ConstantInt>(II->getOperand(2)))
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(II->getOperand(2)))
|
||||
invariantSize = CI->getZExtValue();
|
||||
|
||||
AliasAnalysis::AliasResult R =
|
||||
@ -203,9 +201,9 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
|
||||
// If we reach a lifetime begin or end marker, then the query ends here
|
||||
// because the value is undefined.
|
||||
} else if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
|
||||
II->getIntrinsicID() == Intrinsic::lifetime_end) {
|
||||
II->getIntrinsicID() == Intrinsic::lifetime_end) {
|
||||
uint64_t invariantSize = ~0ULL;
|
||||
if (ConstantInt* CI = dyn_cast<ConstantInt>(II->getOperand(1)))
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(II->getOperand(1)))
|
||||
invariantSize = CI->getZExtValue();
|
||||
|
||||
AliasAnalysis::AliasResult R =
|
||||
@ -371,20 +369,41 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) {
|
||||
// calls to free() erase the entire structure, not just a field.
|
||||
MemSize = ~0UL;
|
||||
} else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
|
||||
CallSite QueryCS = CallSite::get(QueryInst);
|
||||
bool isReadOnly = AA->onlyReadsMemory(QueryCS);
|
||||
LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos,
|
||||
QueryParent);
|
||||
int IntrinsicID = 0; // Intrinsic IDs start at 1.
|
||||
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(QueryInst))
|
||||
IntrinsicID = II->getIntrinsicID();
|
||||
|
||||
switch (IntrinsicID) {
|
||||
case Intrinsic::lifetime_start:
|
||||
case Intrinsic::lifetime_end:
|
||||
case Intrinsic::invariant_start:
|
||||
MemPtr = QueryInst->getOperand(2);
|
||||
MemSize = cast<ConstantInt>(QueryInst->getOperand(1))->getZExtValue();
|
||||
break;
|
||||
case Intrinsic::invariant_end:
|
||||
MemPtr = QueryInst->getOperand(3);
|
||||
MemSize = cast<ConstantInt>(QueryInst->getOperand(2))->getZExtValue();
|
||||
break;
|
||||
default:
|
||||
CallSite QueryCS = CallSite::get(QueryInst);
|
||||
bool isReadOnly = AA->onlyReadsMemory(QueryCS);
|
||||
LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos,
|
||||
QueryParent);
|
||||
}
|
||||
} else {
|
||||
// Non-memory instruction.
|
||||
LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
|
||||
}
|
||||
|
||||
// If we need to do a pointer scan, make it happen.
|
||||
if (MemPtr)
|
||||
LocalCache = getPointerDependencyFrom(MemPtr, MemSize,
|
||||
isa<LoadInst>(QueryInst),
|
||||
ScanPos, QueryParent);
|
||||
if (MemPtr) {
|
||||
bool isLoad = !QueryInst->mayWriteToMemory();
|
||||
if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) {
|
||||
isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_end;
|
||||
}
|
||||
LocalCache = getPointerDependencyFrom(MemPtr, MemSize, isLoad, ScanPos,
|
||||
QueryParent);
|
||||
}
|
||||
|
||||
// Remember the result!
|
||||
if (Instruction *I = LocalCache.getInst())
|
||||
@ -688,6 +707,274 @@ SortNonLocalDepInfoCache(MemoryDependenceAnalysis::NonLocalDepInfo &Cache,
|
||||
}
|
||||
}
|
||||
|
||||
/// isPHITranslatable - Return true if the specified computation is derived from
|
||||
/// a PHI node in the current block and if it is simple enough for us to handle.
|
||||
static bool isPHITranslatable(Instruction *Inst) {
|
||||
if (isa<PHINode>(Inst))
|
||||
return true;
|
||||
|
||||
// We can handle bitcast of a PHI, but the PHI needs to be in the same block
|
||||
// as the bitcast.
|
||||
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
|
||||
Instruction *OpI = dyn_cast<Instruction>(BC->getOperand(0));
|
||||
if (OpI == 0 || OpI->getParent() != Inst->getParent())
|
||||
return true;
|
||||
return isPHITranslatable(OpI);
|
||||
}
|
||||
|
||||
// We can translate a GEP if all of its operands defined in this block are phi
|
||||
// translatable.
|
||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
|
||||
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
|
||||
Instruction *OpI = dyn_cast<Instruction>(GEP->getOperand(i));
|
||||
if (OpI == 0 || OpI->getParent() != Inst->getParent())
|
||||
continue;
|
||||
|
||||
if (!isPHITranslatable(OpI))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Inst->getOpcode() == Instruction::Add &&
|
||||
isa<ConstantInt>(Inst->getOperand(1))) {
|
||||
Instruction *OpI = dyn_cast<Instruction>(Inst->getOperand(0));
|
||||
if (OpI == 0 || OpI->getParent() != Inst->getParent())
|
||||
return true;
|
||||
return isPHITranslatable(OpI);
|
||||
}
|
||||
|
||||
// cerr << "MEMDEP: Could not PHI translate: " << *Pointer;
|
||||
// if (isa<BitCastInst>(PtrInst) || isa<GetElementPtrInst>(PtrInst))
|
||||
// cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// GetPHITranslatedValue - Given a computation that satisfied the
|
||||
/// isPHITranslatable predicate, see if we can translate the computation into
|
||||
/// the specified predecessor block. If so, return that value.
|
||||
Value *MemoryDependenceAnalysis::
|
||||
GetPHITranslatedValue(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
|
||||
const TargetData *TD) const {
|
||||
// If the input value is not an instruction, or if it is not defined in CurBB,
|
||||
// then we don't need to phi translate it.
|
||||
Instruction *Inst = dyn_cast<Instruction>(InVal);
|
||||
if (Inst == 0 || Inst->getParent() != CurBB)
|
||||
return InVal;
|
||||
|
||||
if (PHINode *PN = dyn_cast<PHINode>(Inst))
|
||||
return PN->getIncomingValueForBlock(Pred);
|
||||
|
||||
// Handle bitcast of PHI.
|
||||
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
|
||||
// PHI translate the input operand.
|
||||
Value *PHIIn = GetPHITranslatedValue(BC->getOperand(0), CurBB, Pred, TD);
|
||||
if (PHIIn == 0) return 0;
|
||||
|
||||
// Constants are trivial to phi translate.
|
||||
if (Constant *C = dyn_cast<Constant>(PHIIn))
|
||||
return ConstantExpr::getBitCast(C, BC->getType());
|
||||
|
||||
// Otherwise we have to see if a bitcasted version of the incoming pointer
|
||||
// is available. If so, we can use it, otherwise we have to fail.
|
||||
for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end();
|
||||
UI != E; ++UI) {
|
||||
if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI))
|
||||
if (BCI->getType() == BC->getType())
|
||||
return BCI;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle getelementptr with at least one PHI translatable operand.
|
||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
|
||||
SmallVector<Value*, 8> GEPOps;
|
||||
BasicBlock *CurBB = GEP->getParent();
|
||||
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
|
||||
Value *GEPOp = GEP->getOperand(i);
|
||||
// No PHI translation is needed of operands whose values are live in to
|
||||
// the predecessor block.
|
||||
if (!isa<Instruction>(GEPOp) ||
|
||||
cast<Instruction>(GEPOp)->getParent() != CurBB) {
|
||||
GEPOps.push_back(GEPOp);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the operand is a phi node, do phi translation.
|
||||
Value *InOp = GetPHITranslatedValue(GEPOp, CurBB, Pred, TD);
|
||||
if (InOp == 0) return 0;
|
||||
|
||||
GEPOps.push_back(InOp);
|
||||
}
|
||||
|
||||
// Simplify the GEP to handle 'gep x, 0' -> x etc.
|
||||
if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD))
|
||||
return V;
|
||||
|
||||
// Scan to see if we have this GEP available.
|
||||
Value *APHIOp = GEPOps[0];
|
||||
for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end();
|
||||
UI != E; ++UI) {
|
||||
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
|
||||
if (GEPI->getType() == GEP->getType() &&
|
||||
GEPI->getNumOperands() == GEPOps.size() &&
|
||||
GEPI->getParent()->getParent() == CurBB->getParent()) {
|
||||
bool Mismatch = false;
|
||||
for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
|
||||
if (GEPI->getOperand(i) != GEPOps[i]) {
|
||||
Mismatch = true;
|
||||
break;
|
||||
}
|
||||
if (!Mismatch)
|
||||
return GEPI;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle add with a constant RHS.
|
||||
if (Inst->getOpcode() == Instruction::Add &&
|
||||
isa<ConstantInt>(Inst->getOperand(1))) {
|
||||
// PHI translate the LHS.
|
||||
Value *LHS;
|
||||
Constant *RHS = cast<ConstantInt>(Inst->getOperand(1));
|
||||
Instruction *OpI = dyn_cast<Instruction>(Inst->getOperand(0));
|
||||
bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
|
||||
bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();
|
||||
|
||||
if (OpI == 0 || OpI->getParent() != Inst->getParent())
|
||||
LHS = Inst->getOperand(0);
|
||||
else {
|
||||
LHS = GetPHITranslatedValue(Inst->getOperand(0), CurBB, Pred, TD);
|
||||
if (LHS == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If the PHI translated LHS is an add of a constant, fold the immediates.
|
||||
if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(LHS))
|
||||
if (BOp->getOpcode() == Instruction::Add)
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
|
||||
LHS = BOp->getOperand(0);
|
||||
RHS = ConstantExpr::getAdd(RHS, CI);
|
||||
isNSW = isNUW = false;
|
||||
}
|
||||
|
||||
// See if the add simplifies away.
|
||||
if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD))
|
||||
return Res;
|
||||
|
||||
// Otherwise, see if we have this add available somewhere.
|
||||
for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end();
|
||||
UI != E; ++UI) {
|
||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*UI))
|
||||
if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
|
||||
BO->getParent()->getParent() == CurBB->getParent())
|
||||
return BO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// GetAvailablePHITranslatePointer - Return the value computed by
|
||||
/// PHITranslatePointer if it dominates PredBB, otherwise return null.
|
||||
Value *MemoryDependenceAnalysis::
|
||||
GetAvailablePHITranslatedValue(Value *V,
|
||||
BasicBlock *CurBB, BasicBlock *PredBB,
|
||||
const TargetData *TD,
|
||||
const DominatorTree &DT) const {
|
||||
// See if PHI translation succeeds.
|
||||
V = GetPHITranslatedValue(V, CurBB, PredBB, TD);
|
||||
if (V == 0) return 0;
|
||||
|
||||
// Make sure the value is live in the predecessor.
|
||||
if (Instruction *Inst = dyn_cast_or_null<Instruction>(V))
|
||||
if (!DT.dominates(Inst->getParent(), PredBB))
|
||||
return 0;
|
||||
return V;
|
||||
}
|
||||
|
||||
|
||||
/// InsertPHITranslatedPointer - Insert a computation of the PHI translated
|
||||
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
|
||||
/// block. All newly created instructions are added to the NewInsts list.
|
||||
///
|
||||
Value *MemoryDependenceAnalysis::
|
||||
InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB,
|
||||
BasicBlock *PredBB, const TargetData *TD,
|
||||
const DominatorTree &DT,
|
||||
SmallVectorImpl<Instruction*> &NewInsts) const {
|
||||
// See if we have a version of this value already available and dominating
|
||||
// PredBB. If so, there is no need to insert a new copy.
|
||||
if (Value *Res = GetAvailablePHITranslatedValue(InVal, CurBB, PredBB, TD, DT))
|
||||
return Res;
|
||||
|
||||
// If we don't have an available version of this value, it must be an
|
||||
// instruction.
|
||||
Instruction *Inst = cast<Instruction>(InVal);
|
||||
|
||||
// Handle bitcast of PHI translatable value.
|
||||
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
|
||||
Value *OpVal = InsertPHITranslatedPointer(BC->getOperand(0),
|
||||
CurBB, PredBB, TD, DT, NewInsts);
|
||||
if (OpVal == 0) return 0;
|
||||
|
||||
// Otherwise insert a bitcast at the end of PredBB.
|
||||
BitCastInst *New = new BitCastInst(OpVal, InVal->getType(),
|
||||
InVal->getName()+".phi.trans.insert",
|
||||
PredBB->getTerminator());
|
||||
NewInsts.push_back(New);
|
||||
return New;
|
||||
}
|
||||
|
||||
// Handle getelementptr with at least one PHI operand.
|
||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
|
||||
SmallVector<Value*, 8> GEPOps;
|
||||
BasicBlock *CurBB = GEP->getParent();
|
||||
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
|
||||
Value *OpVal = InsertPHITranslatedPointer(GEP->getOperand(i),
|
||||
CurBB, PredBB, TD, DT, NewInsts);
|
||||
if (OpVal == 0) return 0;
|
||||
GEPOps.push_back(OpVal);
|
||||
}
|
||||
|
||||
GetElementPtrInst *Result =
|
||||
GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(),
|
||||
InVal->getName()+".phi.trans.insert",
|
||||
PredBB->getTerminator());
|
||||
Result->setIsInBounds(GEP->isInBounds());
|
||||
NewInsts.push_back(Result);
|
||||
return Result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// FIXME: This code works, but it is unclear that we actually want to insert
|
||||
// a big chain of computation in order to make a value available in a block.
|
||||
// This needs to be evaluated carefully to consider its cost trade offs.
|
||||
|
||||
// Handle add with a constant RHS.
|
||||
if (Inst->getOpcode() == Instruction::Add &&
|
||||
isa<ConstantInt>(Inst->getOperand(1))) {
|
||||
// PHI translate the LHS.
|
||||
Value *OpVal = InsertPHITranslatedPointer(Inst->getOperand(0),
|
||||
CurBB, PredBB, TD, DT, NewInsts);
|
||||
if (OpVal == 0) return 0;
|
||||
|
||||
BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1),
|
||||
InVal->getName()+".phi.trans.insert",
|
||||
PredBB->getTerminator());
|
||||
Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap());
|
||||
Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap());
|
||||
NewInsts.push_back(Res);
|
||||
return Res;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getNonLocalPointerDepFromBB - Perform a dependency query based on
|
||||
/// pointer/pointeesize starting at the end of StartBB. Add any clobber/def
|
||||
@ -831,66 +1118,107 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
|
||||
NumSortedEntries = Cache->size();
|
||||
}
|
||||
|
||||
// If this is directly a PHI node, just use the incoming values for each
|
||||
// pred as the phi translated version.
|
||||
if (PHINode *PtrPHI = dyn_cast<PHINode>(PtrInst)) {
|
||||
Cache = 0;
|
||||
// If this is a computation derived from a PHI node, use the suitably
|
||||
// translated incoming values for each pred as the phi translated version.
|
||||
if (!isPHITranslatable(PtrInst))
|
||||
goto PredTranslationFailure;
|
||||
|
||||
Cache = 0;
|
||||
|
||||
for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) {
|
||||
BasicBlock *Pred = *PI;
|
||||
Value *PredPtr = PtrPHI->getIncomingValueForBlock(Pred);
|
||||
|
||||
// Check to see if we have already visited this pred block with another
|
||||
// pointer. If so, we can't do this lookup. This failure can occur
|
||||
// with PHI translation when a critical edge exists and the PHI node in
|
||||
// the successor translates to a pointer value different than the
|
||||
// pointer the block was first analyzed with.
|
||||
std::pair<DenseMap<BasicBlock*,Value*>::iterator, bool>
|
||||
InsertRes = Visited.insert(std::make_pair(Pred, PredPtr));
|
||||
for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) {
|
||||
BasicBlock *Pred = *PI;
|
||||
// Get the PHI translated pointer in this predecessor. This can fail and
|
||||
// return null if not translatable.
|
||||
Value *PredPtr = GetPHITranslatedValue(PtrInst, BB, Pred, TD);
|
||||
|
||||
// Check to see if we have already visited this pred block with another
|
||||
// pointer. If so, we can't do this lookup. This failure can occur
|
||||
// with PHI translation when a critical edge exists and the PHI node in
|
||||
// the successor translates to a pointer value different than the
|
||||
// pointer the block was first analyzed with.
|
||||
std::pair<DenseMap<BasicBlock*,Value*>::iterator, bool>
|
||||
InsertRes = Visited.insert(std::make_pair(Pred, PredPtr));
|
||||
|
||||
if (!InsertRes.second) {
|
||||
// If the predecessor was visited with PredPtr, then we already did
|
||||
// the analysis and can ignore it.
|
||||
if (InsertRes.first->second == PredPtr)
|
||||
continue;
|
||||
|
||||
// Otherwise, the block was previously analyzed with a different
|
||||
// pointer. We can't represent the result of this case, so we just
|
||||
// treat this as a phi translation failure.
|
||||
goto PredTranslationFailure;
|
||||
}
|
||||
|
||||
// FIXME: it is entirely possible that PHI translating will end up with
|
||||
// the same value. Consider PHI translating something like:
|
||||
// X = phi [x, bb1], [y, bb2]. PHI translating for bb1 doesn't *need*
|
||||
// to recurse here, pedantically speaking.
|
||||
if (!InsertRes.second) {
|
||||
// If the predecessor was visited with PredPtr, then we already did
|
||||
// the analysis and can ignore it.
|
||||
if (InsertRes.first->second == PredPtr)
|
||||
continue;
|
||||
|
||||
// If we have a problem phi translating, fall through to the code below
|
||||
// to handle the failure condition.
|
||||
if (getNonLocalPointerDepFromBB(PredPtr, PointeeSize, isLoad, Pred,
|
||||
Result, Visited))
|
||||
goto PredTranslationFailure;
|
||||
// Otherwise, the block was previously analyzed with a different
|
||||
// pointer. We can't represent the result of this case, so we just
|
||||
// treat this as a phi translation failure.
|
||||
goto PredTranslationFailure;
|
||||
}
|
||||
|
||||
// Refresh the CacheInfo/Cache pointer so that it isn't invalidated.
|
||||
CacheInfo = &NonLocalPointerDeps[CacheKey];
|
||||
Cache = &CacheInfo->second;
|
||||
NumSortedEntries = Cache->size();
|
||||
// If PHI translation was unable to find an available pointer in this
|
||||
// predecessor, then we have to assume that the pointer is clobbered in
|
||||
// that predecessor. We can still do PRE of the load, which would insert
|
||||
// a computation of the pointer in this predecessor.
|
||||
if (PredPtr == 0) {
|
||||
// Add the entry to the Result list.
|
||||
NonLocalDepEntry Entry(Pred,
|
||||
MemDepResult::getClobber(Pred->getTerminator()));
|
||||
Result.push_back(Entry);
|
||||
|
||||
// Add it to the cache for this CacheKey so that subsequent queries get
|
||||
// this result.
|
||||
Cache = &NonLocalPointerDeps[CacheKey].second;
|
||||
MemoryDependenceAnalysis::NonLocalDepInfo::iterator It =
|
||||
std::upper_bound(Cache->begin(), Cache->end(), Entry);
|
||||
|
||||
if (It != Cache->begin() && prior(It)->first == Pred)
|
||||
--It;
|
||||
|
||||
if (It == Cache->end() || It->first != Pred) {
|
||||
Cache->insert(It, Entry);
|
||||
// Add it to the reverse map.
|
||||
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
|
||||
} else if (!It->second.isDirty()) {
|
||||
// noop
|
||||
} else if (It->second.getInst() == Pred->getTerminator()) {
|
||||
// Same instruction, clear the dirty marker.
|
||||
It->second = Entry.second;
|
||||
} else if (It->second.getInst() == 0) {
|
||||
// Dirty, with no instruction, just add this.
|
||||
It->second = Entry.second;
|
||||
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
|
||||
} else {
|
||||
// Otherwise, dirty with a different instruction.
|
||||
RemoveFromReverseMap(ReverseNonLocalPtrDeps, It->second.getInst(),
|
||||
CacheKey);
|
||||
It->second = Entry.second;
|
||||
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
|
||||
}
|
||||
Cache = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: it is entirely possible that PHI translating will end up with
|
||||
// the same value. Consider PHI translating something like:
|
||||
// X = phi [x, bb1], [y, bb2]. PHI translating for bb1 doesn't *need*
|
||||
// to recurse here, pedantically speaking.
|
||||
|
||||
// Since we did phi translation, the "Cache" set won't contain all of the
|
||||
// results for the query. This is ok (we can still use it to accelerate
|
||||
// specific block queries) but we can't do the fastpath "return all
|
||||
// results from the set" Clear out the indicator for this.
|
||||
CacheInfo->first = BBSkipFirstBlockPair();
|
||||
SkipFirstBlock = false;
|
||||
continue;
|
||||
// If we have a problem phi translating, fall through to the code below
|
||||
// to handle the failure condition.
|
||||
if (getNonLocalPointerDepFromBB(PredPtr, PointeeSize, isLoad, Pred,
|
||||
Result, Visited))
|
||||
goto PredTranslationFailure;
|
||||
}
|
||||
|
||||
// TODO: BITCAST, GEP.
|
||||
// Refresh the CacheInfo/Cache pointer so that it isn't invalidated.
|
||||
CacheInfo = &NonLocalPointerDeps[CacheKey];
|
||||
Cache = &CacheInfo->second;
|
||||
NumSortedEntries = Cache->size();
|
||||
|
||||
// cerr << "MEMDEP: Could not PHI translate: " << *Pointer;
|
||||
// if (isa<BitCastInst>(PtrInst) || isa<GetElementPtrInst>(PtrInst))
|
||||
// cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0);
|
||||
// Since we did phi translation, the "Cache" set won't contain all of the
|
||||
// results for the query. This is ok (we can still use it to accelerate
|
||||
// specific block queries) but we can't do the fastpath "return all
|
||||
// results from the set" Clear out the indicator for this.
|
||||
CacheInfo->first = BBSkipFirstBlockPair();
|
||||
SkipFirstBlock = false;
|
||||
continue;
|
||||
|
||||
PredTranslationFailure:
|
||||
|
||||
if (Cache == 0) {
|
||||
|
@ -3644,7 +3644,7 @@ EvaluateConstantChrecAtConstant(const SCEVAddRecExpr *AddRec, ConstantInt *C,
|
||||
/// the addressed element of the initializer or null if the index expression is
|
||||
/// invalid.
|
||||
static Constant *
|
||||
GetAddressedElementFromGlobal(LLVMContext &Context, GlobalVariable *GV,
|
||||
GetAddressedElementFromGlobal(GlobalVariable *GV,
|
||||
const std::vector<ConstantInt*> &Indices) {
|
||||
Constant *Init = GV->getInitializer();
|
||||
for (unsigned i = 0, e = Indices.size(); i != e; ++i) {
|
||||
@ -3732,7 +3732,7 @@ ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
|
||||
// Form the GEP offset.
|
||||
Indexes[VarIdxNum] = Val;
|
||||
|
||||
Constant *Result = GetAddressedElementFromGlobal(getContext(), GV, Indexes);
|
||||
Constant *Result = GetAddressedElementFromGlobal(GV, Indexes);
|
||||
if (Result == 0) break; // Cannot compute!
|
||||
|
||||
// Evaluate the condition for this iteration.
|
||||
|
@ -325,7 +325,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
APInt Mask2(Mask.shl(ShiftAmt));
|
||||
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero,KnownOne, TD,
|
||||
Depth+1);
|
||||
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
KnownZero = APIntOps::lshr(KnownZero, ShiftAmt);
|
||||
KnownOne = APIntOps::lshr(KnownOne, ShiftAmt);
|
||||
// high bits known zero.
|
||||
@ -343,7 +343,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
APInt Mask2(Mask.shl(ShiftAmt));
|
||||
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero, KnownOne, TD,
|
||||
Depth+1);
|
||||
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
KnownZero = APIntOps::lshr(KnownZero, ShiftAmt);
|
||||
KnownOne = APIntOps::lshr(KnownOne, ShiftAmt);
|
||||
|
||||
@ -380,7 +380,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
}
|
||||
// fall through
|
||||
case Instruction::Add: {
|
||||
// If one of the operands has trailing zeros, than the bits that the
|
||||
// If one of the operands has trailing zeros, then the bits that the
|
||||
// other operand has in those bit positions will be preserved in the
|
||||
// result. For an add, this works with either operand. For a subtract,
|
||||
// this only works if the known zeros are in the right operand.
|
||||
@ -436,7 +436,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
|
||||
KnownZero |= KnownZero2 & Mask;
|
||||
|
||||
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -449,7 +449,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
KnownZero |= ~LowBits & Mask;
|
||||
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero, KnownOne, TD,
|
||||
Depth+1);
|
||||
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -833,14 +833,12 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
|
||||
|
||||
switch (I->getOpcode()) {
|
||||
default: break;
|
||||
case Instruction::SExt: {
|
||||
case Instruction::SExt:
|
||||
if (!LookThroughSExt) return false;
|
||||
// otherwise fall through to ZExt
|
||||
}
|
||||
case Instruction::ZExt: {
|
||||
case Instruction::ZExt:
|
||||
return ComputeMultiple(I->getOperand(0), Base, Multiple,
|
||||
LookThroughSExt, Depth+1);
|
||||
}
|
||||
case Instruction::Shl:
|
||||
case Instruction::Mul: {
|
||||
Value *Op0 = I->getOperand(0);
|
||||
@ -950,6 +948,195 @@ bool llvm::CannotBeNegativeZero(const Value *V, unsigned Depth) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// GetLinearExpression - Analyze the specified value as a linear expression:
|
||||
/// "A*V + B", where A and B are constant integers. Return the scale and offset
|
||||
/// values as APInts and return V as a Value*. The incoming Value is known to
|
||||
/// have IntegerType. Note that this looks through extends, so the high bits
|
||||
/// may not be represented in the result.
|
||||
static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
|
||||
const TargetData *TD, unsigned Depth) {
|
||||
assert(isa<IntegerType>(V->getType()) && "Not an integer value");
|
||||
|
||||
// Limit our recursion depth.
|
||||
if (Depth == 6) {
|
||||
Scale = 1;
|
||||
Offset = 0;
|
||||
return V;
|
||||
}
|
||||
|
||||
if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(V)) {
|
||||
if (ConstantInt *RHSC = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
|
||||
switch (BOp->getOpcode()) {
|
||||
default: break;
|
||||
case Instruction::Or:
|
||||
// X|C == X+C if all the bits in C are unset in X. Otherwise we can't
|
||||
// analyze it.
|
||||
if (!MaskedValueIsZero(BOp->getOperand(0), RHSC->getValue(), TD))
|
||||
break;
|
||||
// FALL THROUGH.
|
||||
case Instruction::Add:
|
||||
V = GetLinearExpression(BOp->getOperand(0), Scale, Offset, TD, Depth+1);
|
||||
Offset += RHSC->getValue();
|
||||
return V;
|
||||
case Instruction::Mul:
|
||||
V = GetLinearExpression(BOp->getOperand(0), Scale, Offset, TD, Depth+1);
|
||||
Offset *= RHSC->getValue();
|
||||
Scale *= RHSC->getValue();
|
||||
return V;
|
||||
case Instruction::Shl:
|
||||
V = GetLinearExpression(BOp->getOperand(0), Scale, Offset, TD, Depth+1);
|
||||
Offset <<= RHSC->getValue().getLimitedValue();
|
||||
Scale <<= RHSC->getValue().getLimitedValue();
|
||||
return V;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Since clients don't care about the high bits of the value, just scales and
|
||||
// offsets, we can look through extensions.
|
||||
if (isa<SExtInst>(V) || isa<ZExtInst>(V)) {
|
||||
Value *CastOp = cast<CastInst>(V)->getOperand(0);
|
||||
unsigned OldWidth = Scale.getBitWidth();
|
||||
unsigned SmallWidth = CastOp->getType()->getPrimitiveSizeInBits();
|
||||
Scale.trunc(SmallWidth);
|
||||
Offset.trunc(SmallWidth);
|
||||
Value *Result = GetLinearExpression(CastOp, Scale, Offset, TD, Depth+1);
|
||||
Scale.zext(OldWidth);
|
||||
Offset.zext(OldWidth);
|
||||
return Result;
|
||||
}
|
||||
|
||||
Scale = 1;
|
||||
Offset = 0;
|
||||
return V;
|
||||
}
|
||||
|
||||
/// DecomposeGEPExpression - If V is a symbolic pointer expression, decompose it
|
||||
/// into a base pointer with a constant offset and a number of scaled symbolic
|
||||
/// offsets.
|
||||
///
|
||||
/// The scaled symbolic offsets (represented by pairs of a Value* and a scale in
|
||||
/// the VarIndices vector) are Value*'s that are known to be scaled by the
|
||||
/// specified amount, but which may have other unrepresented high bits. As such,
|
||||
/// the gep cannot necessarily be reconstructed from its decomposed form.
|
||||
///
|
||||
/// When TargetData is around, this function is capable of analyzing everything
|
||||
/// that Value::getUnderlyingObject() can look through. When not, it just looks
|
||||
/// through pointer casts.
|
||||
///
|
||||
const Value *llvm::DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
|
||||
SmallVectorImpl<std::pair<const Value*, int64_t> > &VarIndices,
|
||||
const TargetData *TD) {
|
||||
// Limit recursion depth to limit compile time in crazy cases.
|
||||
unsigned MaxLookup = 6;
|
||||
|
||||
BaseOffs = 0;
|
||||
do {
|
||||
// See if this is a bitcast or GEP.
|
||||
const Operator *Op = dyn_cast<Operator>(V);
|
||||
if (Op == 0) {
|
||||
// The only non-operator case we can handle are GlobalAliases.
|
||||
if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
|
||||
if (!GA->mayBeOverridden()) {
|
||||
V = GA->getAliasee();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return V;
|
||||
}
|
||||
|
||||
if (Op->getOpcode() == Instruction::BitCast) {
|
||||
V = Op->getOperand(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
const GEPOperator *GEPOp = dyn_cast<GEPOperator>(Op);
|
||||
if (GEPOp == 0)
|
||||
return V;
|
||||
|
||||
// Don't attempt to analyze GEPs over unsized objects.
|
||||
if (!cast<PointerType>(GEPOp->getOperand(0)->getType())
|
||||
->getElementType()->isSized())
|
||||
return V;
|
||||
|
||||
// If we are lacking TargetData information, we can't compute the offets of
|
||||
// elements computed by GEPs. However, we can handle bitcast equivalent
|
||||
// GEPs.
|
||||
if (!TD) {
|
||||
if (!GEPOp->hasAllZeroIndices())
|
||||
return V;
|
||||
V = GEPOp->getOperand(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Walk the indices of the GEP, accumulating them into BaseOff/VarIndices.
|
||||
gep_type_iterator GTI = gep_type_begin(GEPOp);
|
||||
for (User::const_op_iterator I = GEPOp->op_begin()+1,
|
||||
E = GEPOp->op_end(); I != E; ++I) {
|
||||
Value *Index = *I;
|
||||
// Compute the (potentially symbolic) offset in bytes for this index.
|
||||
if (const StructType *STy = dyn_cast<StructType>(*GTI++)) {
|
||||
// For a struct, add the member offset.
|
||||
unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();
|
||||
if (FieldNo == 0) continue;
|
||||
|
||||
BaseOffs += TD->getStructLayout(STy)->getElementOffset(FieldNo);
|
||||
continue;
|
||||
}
|
||||
|
||||
// For an array/pointer, add the element offset, explicitly scaled.
|
||||
if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Index)) {
|
||||
if (CIdx->isZero()) continue;
|
||||
BaseOffs += TD->getTypeAllocSize(*GTI)*CIdx->getSExtValue();
|
||||
continue;
|
||||
}
|
||||
|
||||
uint64_t Scale = TD->getTypeAllocSize(*GTI);
|
||||
|
||||
// Use GetLinearExpression to decompose the index into a C1*V+C2 form.
|
||||
unsigned Width = cast<IntegerType>(Index->getType())->getBitWidth();
|
||||
APInt IndexScale(Width, 0), IndexOffset(Width, 0);
|
||||
Index = GetLinearExpression(Index, IndexScale, IndexOffset, TD, 0);
|
||||
|
||||
// The GEP index scale ("Scale") scales C1*V+C2, yielding (C1*V+C2)*Scale.
|
||||
// This gives us an aggregate computation of (C1*Scale)*V + C2*Scale.
|
||||
BaseOffs += IndexOffset.getZExtValue()*Scale;
|
||||
Scale *= IndexScale.getZExtValue();
|
||||
|
||||
|
||||
// If we already had an occurrance of this index variable, merge this
|
||||
// scale into it. For example, we want to handle:
|
||||
// A[x][x] -> x*16 + x*4 -> x*20
|
||||
// This also ensures that 'x' only appears in the index list once.
|
||||
for (unsigned i = 0, e = VarIndices.size(); i != e; ++i) {
|
||||
if (VarIndices[i].first == Index) {
|
||||
Scale += VarIndices[i].second;
|
||||
VarIndices.erase(VarIndices.begin()+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that we have a scale that makes sense for this target's
|
||||
// pointer size.
|
||||
if (unsigned ShiftBits = 64-TD->getPointerSizeInBits()) {
|
||||
Scale <<= ShiftBits;
|
||||
Scale >>= ShiftBits;
|
||||
}
|
||||
|
||||
if (Scale)
|
||||
VarIndices.push_back(std::make_pair(Index, Scale));
|
||||
}
|
||||
|
||||
// Analyze the base pointer next.
|
||||
V = GEPOp->getOperand(0);
|
||||
} while (--MaxLookup);
|
||||
|
||||
// If the chain of expressions is too deep, just return early.
|
||||
return V;
|
||||
}
|
||||
|
||||
|
||||
// This is the recursive version of BuildSubAggregate. It takes a few different
|
||||
// arguments. Idxs is the index within the nested struct From that we are
|
||||
// looking at now (which is of type IndexedType). IdxSkip is the number of
|
||||
@ -959,7 +1146,6 @@ bool llvm::CannotBeNegativeZero(const Value *V, unsigned Depth) {
|
||||
static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
|
||||
SmallVector<unsigned, 10> &Idxs,
|
||||
unsigned IdxSkip,
|
||||
LLVMContext &Context,
|
||||
Instruction *InsertBefore) {
|
||||
const llvm::StructType *STy = llvm::dyn_cast<llvm::StructType>(IndexedType);
|
||||
if (STy) {
|
||||
@ -971,7 +1157,7 @@ static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
|
||||
Idxs.push_back(i);
|
||||
Value *PrevTo = To;
|
||||
To = BuildSubAggregate(From, To, STy->getElementType(i), Idxs, IdxSkip,
|
||||
Context, InsertBefore);
|
||||
InsertBefore);
|
||||
Idxs.pop_back();
|
||||
if (!To) {
|
||||
// Couldn't find any inserted value for this index? Cleanup
|
||||
@ -994,7 +1180,7 @@ static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
|
||||
// we might be able to find the complete struct somewhere.
|
||||
|
||||
// Find the value that is at that particular spot
|
||||
Value *V = FindInsertedValue(From, Idxs.begin(), Idxs.end(), Context);
|
||||
Value *V = FindInsertedValue(From, Idxs.begin(), Idxs.end());
|
||||
|
||||
if (!V)
|
||||
return NULL;
|
||||
@ -1017,7 +1203,7 @@ static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
|
||||
//
|
||||
// All inserted insertvalue instructions are inserted before InsertBefore
|
||||
static Value *BuildSubAggregate(Value *From, const unsigned *idx_begin,
|
||||
const unsigned *idx_end, LLVMContext &Context,
|
||||
const unsigned *idx_end,
|
||||
Instruction *InsertBefore) {
|
||||
assert(InsertBefore && "Must have someplace to insert!");
|
||||
const Type *IndexedType = ExtractValueInst::getIndexedType(From->getType(),
|
||||
@ -1027,8 +1213,7 @@ static Value *BuildSubAggregate(Value *From, const unsigned *idx_begin,
|
||||
SmallVector<unsigned, 10> Idxs(idx_begin, idx_end);
|
||||
unsigned IdxSkip = Idxs.size();
|
||||
|
||||
return BuildSubAggregate(From, To, IndexedType, Idxs, IdxSkip,
|
||||
Context, InsertBefore);
|
||||
return BuildSubAggregate(From, To, IndexedType, Idxs, IdxSkip, InsertBefore);
|
||||
}
|
||||
|
||||
/// FindInsertedValue - Given an aggregrate and an sequence of indices, see if
|
||||
@ -1038,8 +1223,7 @@ static Value *BuildSubAggregate(Value *From, const unsigned *idx_begin,
|
||||
/// If InsertBefore is not null, this function will duplicate (modified)
|
||||
/// insertvalues when a part of a nested struct is extracted.
|
||||
Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
const unsigned *idx_end, LLVMContext &Context,
|
||||
Instruction *InsertBefore) {
|
||||
const unsigned *idx_end, Instruction *InsertBefore) {
|
||||
// Nothing to index? Just return V then (this is useful at the end of our
|
||||
// recursion)
|
||||
if (idx_begin == idx_end)
|
||||
@ -1063,7 +1247,7 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
if (isa<ConstantArray>(C) || isa<ConstantStruct>(C))
|
||||
// Recursively process this constant
|
||||
return FindInsertedValue(C->getOperand(*idx_begin), idx_begin + 1,
|
||||
idx_end, Context, InsertBefore);
|
||||
idx_end, InsertBefore);
|
||||
} else if (InsertValueInst *I = dyn_cast<InsertValueInst>(V)) {
|
||||
// Loop the indices for the insertvalue instruction in parallel with the
|
||||
// requested indices
|
||||
@ -1082,8 +1266,7 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
// %C = insertvalue {i32, i32 } %A, i32 11, 1
|
||||
// which allows the unused 0,0 element from the nested struct to be
|
||||
// removed.
|
||||
return BuildSubAggregate(V, idx_begin, req_idx,
|
||||
Context, InsertBefore);
|
||||
return BuildSubAggregate(V, idx_begin, req_idx, InsertBefore);
|
||||
else
|
||||
// We can't handle this without inserting insertvalues
|
||||
return 0;
|
||||
@ -1094,13 +1277,13 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
// looking for, then.
|
||||
if (*req_idx != *i)
|
||||
return FindInsertedValue(I->getAggregateOperand(), idx_begin, idx_end,
|
||||
Context, InsertBefore);
|
||||
InsertBefore);
|
||||
}
|
||||
// If we end up here, the indices of the insertvalue match with those
|
||||
// requested (though possibly only partially). Now we recursively look at
|
||||
// the inserted value, passing any remaining indices.
|
||||
return FindInsertedValue(I->getInsertedValueOperand(), req_idx, idx_end,
|
||||
Context, InsertBefore);
|
||||
InsertBefore);
|
||||
} else if (ExtractValueInst *I = dyn_cast<ExtractValueInst>(V)) {
|
||||
// If we're extracting a value from an aggregrate that was extracted from
|
||||
// something else, we can extract from that something else directly instead.
|
||||
@ -1124,7 +1307,7 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
&& "Number of indices added not correct?");
|
||||
|
||||
return FindInsertedValue(I->getAggregateOperand(), Idxs.begin(), Idxs.end(),
|
||||
Context, InsertBefore);
|
||||
InsertBefore);
|
||||
}
|
||||
// Otherwise, we don't know (such as, extracting from a function return value
|
||||
// or load instruction)
|
||||
|
@ -2701,6 +2701,10 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
||||
// Add all of the arguments we parsed to the function.
|
||||
Function::arg_iterator ArgIt = Fn->arg_begin();
|
||||
for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) {
|
||||
// If we run out of arguments in the Function prototype, exit early.
|
||||
// FIXME: REMOVE THIS IN LLVM 3.0, this is just for the mismatch case above.
|
||||
if (ArgIt == Fn->arg_end()) break;
|
||||
|
||||
// If the argument has a name, insert it into the argument symbol table.
|
||||
if (ArgList[i].Name.empty()) continue;
|
||||
|
||||
|
@ -28,10 +28,15 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
// If DebugDiv > 0 then only break antidep with (ID % DebugDiv) == DebugMod
|
||||
static cl::opt<int>
|
||||
AntiDepTrials("agg-antidep-trials",
|
||||
cl::desc("Maximum number of anti-dependency breaking passes"),
|
||||
cl::init(1), cl::Hidden);
|
||||
DebugDiv("agg-antidep-debugdiv",
|
||||
cl::desc("Debug control for aggressive anti-dep breaker"),
|
||||
cl::init(0), cl::Hidden);
|
||||
static cl::opt<int>
|
||||
DebugMod("agg-antidep-debugmod",
|
||||
cl::desc("Debug control for aggressive anti-dep breaker"),
|
||||
cl::init(0), cl::Hidden);
|
||||
|
||||
AggressiveAntiDepState::AggressiveAntiDepState(MachineBasicBlock *BB) :
|
||||
GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) {
|
||||
@ -108,7 +113,7 @@ AggressiveAntiDepBreaker(MachineFunction& MFi,
|
||||
MRI(MF.getRegInfo()),
|
||||
TRI(MF.getTarget().getRegisterInfo()),
|
||||
AllocatableSet(TRI->getAllocatableSet(MF)),
|
||||
State(NULL), SavedState(NULL) {
|
||||
State(NULL) {
|
||||
/* Collect a bitset of all registers that are only broken if they
|
||||
are on the critical path. */
|
||||
for (unsigned i = 0, e = CriticalPathRCs.size(); i < e; ++i) {
|
||||
@ -128,13 +133,6 @@ AggressiveAntiDepBreaker(MachineFunction& MFi,
|
||||
|
||||
AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() {
|
||||
delete State;
|
||||
delete SavedState;
|
||||
}
|
||||
|
||||
unsigned AggressiveAntiDepBreaker::GetMaxTrials() {
|
||||
if (AntiDepTrials <= 0)
|
||||
return 1;
|
||||
return AntiDepTrials;
|
||||
}
|
||||
|
||||
void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {
|
||||
@ -206,8 +204,6 @@ void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {
|
||||
void AggressiveAntiDepBreaker::FinishBlock() {
|
||||
delete State;
|
||||
State = NULL;
|
||||
delete SavedState;
|
||||
SavedState = NULL;
|
||||
}
|
||||
|
||||
void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
|
||||
@ -241,10 +237,6 @@ void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
|
||||
}
|
||||
}
|
||||
DEBUG(errs() << '\n');
|
||||
|
||||
// We're starting a new schedule region so forget any saved state.
|
||||
delete SavedState;
|
||||
SavedState = NULL;
|
||||
}
|
||||
|
||||
bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI,
|
||||
@ -283,27 +275,20 @@ void AggressiveAntiDepBreaker::GetPassthruRegs(MachineInstr *MI,
|
||||
}
|
||||
}
|
||||
|
||||
/// AntiDepEdges - Return in Edges the anti- and output-
|
||||
/// dependencies on Regs in SU that we want to consider for breaking.
|
||||
static void AntiDepEdges(SUnit *SU,
|
||||
const AntiDepBreaker::AntiDepRegVector& Regs,
|
||||
std::vector<SDep*>& Edges) {
|
||||
AntiDepBreaker::AntiDepRegSet RegSet;
|
||||
for (unsigned i = 0, e = Regs.size(); i < e; ++i)
|
||||
RegSet.insert(Regs[i]);
|
||||
|
||||
/// AntiDepEdges - Return in Edges the anti- and output- dependencies
|
||||
/// in SU that we want to consider for breaking.
|
||||
static void AntiDepEdges(SUnit *SU, std::vector<SDep*>& Edges) {
|
||||
SmallSet<unsigned, 4> RegSet;
|
||||
for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end();
|
||||
P != PE; ++P) {
|
||||
if ((P->getKind() == SDep::Anti) || (P->getKind() == SDep::Output)) {
|
||||
unsigned Reg = P->getReg();
|
||||
if (RegSet.count(Reg) != 0) {
|
||||
if (RegSet.count(Reg) == 0) {
|
||||
Edges.push_back(&*P);
|
||||
RegSet.erase(Reg);
|
||||
RegSet.insert(Reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(RegSet.empty() && "Expected all antidep registers to be found");
|
||||
}
|
||||
|
||||
/// CriticalPathStep - Return the next SUnit after SU on the bottom-up
|
||||
@ -332,7 +317,8 @@ static SUnit *CriticalPathStep(SUnit *SU) {
|
||||
}
|
||||
|
||||
void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,
|
||||
const char *tag) {
|
||||
const char *tag, const char *header,
|
||||
const char *footer) {
|
||||
unsigned *KillIndices = State->GetKillIndices();
|
||||
unsigned *DefIndices = State->GetDefIndices();
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
@ -343,6 +329,8 @@ void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,
|
||||
DefIndices[Reg] = ~0u;
|
||||
RegRefs.erase(Reg);
|
||||
State->LeaveGroup(Reg);
|
||||
DEBUG(if (header != NULL) {
|
||||
errs() << header << TRI->getName(Reg); header = NULL; });
|
||||
DEBUG(errs() << "->g" << State->GetGroup(Reg) << tag);
|
||||
}
|
||||
// Repeat for subregisters.
|
||||
@ -354,10 +342,14 @@ void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,
|
||||
DefIndices[SubregReg] = ~0u;
|
||||
RegRefs.erase(SubregReg);
|
||||
State->LeaveGroup(SubregReg);
|
||||
DEBUG(if (header != NULL) {
|
||||
errs() << header << TRI->getName(Reg); header = NULL; });
|
||||
DEBUG(errs() << " " << TRI->getName(SubregReg) << "->g" <<
|
||||
State->GetGroup(SubregReg) << tag);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(if ((header == NULL) && (footer != NULL)) errs() << footer);
|
||||
}
|
||||
|
||||
void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Count,
|
||||
@ -377,9 +369,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
|
||||
unsigned Reg = MO.getReg();
|
||||
if (Reg == 0) continue;
|
||||
|
||||
DEBUG(errs() << "\tDead Def: " << TRI->getName(Reg));
|
||||
HandleLastUse(Reg, Count + 1, "");
|
||||
DEBUG(errs() << '\n');
|
||||
HandleLastUse(Reg, Count + 1, "", "\tDead Def: ", "\n");
|
||||
}
|
||||
|
||||
DEBUG(errs() << "\tDef Groups:");
|
||||
@ -427,15 +417,17 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
|
||||
if (!MO.isReg() || !MO.isDef()) continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (Reg == 0) continue;
|
||||
// Ignore passthru registers for liveness...
|
||||
if (PassthruRegs.count(Reg) != 0) continue;
|
||||
// Ignore KILLs and passthru registers for liveness...
|
||||
if ((MI->getOpcode() == TargetInstrInfo::KILL) ||
|
||||
(PassthruRegs.count(Reg) != 0))
|
||||
continue;
|
||||
|
||||
// Update def for Reg and subregs.
|
||||
// Update def for Reg and aliases.
|
||||
DefIndices[Reg] = Count;
|
||||
for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
|
||||
*Subreg; ++Subreg) {
|
||||
unsigned SubregReg = *Subreg;
|
||||
DefIndices[SubregReg] = Count;
|
||||
for (const unsigned *Alias = TRI->getAliasSet(Reg);
|
||||
*Alias; ++Alias) {
|
||||
unsigned AliasReg = *Alias;
|
||||
DefIndices[AliasReg] = Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -589,72 +581,108 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: for now just handle single register in group case...
|
||||
if (Regs.size() > 1) {
|
||||
DEBUG(errs() << "\tMultiple rename registers in group\n");
|
||||
return false;
|
||||
#ifndef NDEBUG
|
||||
// If DebugDiv > 0 then only rename (renamecnt % DebugDiv) == DebugMod
|
||||
if (DebugDiv > 0) {
|
||||
static int renamecnt = 0;
|
||||
if (renamecnt++ % DebugDiv != DebugMod)
|
||||
return false;
|
||||
|
||||
errs() << "*** Performing rename " << TRI->getName(SuperReg) <<
|
||||
" for debug ***\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check each possible rename register for SuperReg in round-robin
|
||||
// order. If that register is available, and the corresponding
|
||||
// registers are available for the other group subregisters, then we
|
||||
// can use those registers to rename.
|
||||
BitVector SuperBV = RenameRegisterMap[SuperReg];
|
||||
const TargetRegisterClass *SuperRC =
|
||||
TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other);
|
||||
|
||||
const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF);
|
||||
const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF);
|
||||
if (RB == RE) {
|
||||
DEBUG(errs() << "\tEmpty Regclass!!\n");
|
||||
DEBUG(errs() << "\tEmpty Super Regclass!!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG(errs() << "\tFind Registers:");
|
||||
|
||||
if (RenameOrder.count(SuperRC) == 0)
|
||||
RenameOrder.insert(RenameOrderType::value_type(SuperRC, RE));
|
||||
|
||||
DEBUG(errs() << "\tFind Register:");
|
||||
|
||||
const TargetRegisterClass::iterator OrigR = RenameOrder[SuperRC];
|
||||
const TargetRegisterClass::iterator EndR = ((OrigR == RE) ? RB : OrigR);
|
||||
TargetRegisterClass::iterator R = OrigR;
|
||||
do {
|
||||
if (R == RB) R = RE;
|
||||
--R;
|
||||
const unsigned Reg = *R;
|
||||
const unsigned NewSuperReg = *R;
|
||||
// Don't replace a register with itself.
|
||||
if (Reg == SuperReg) continue;
|
||||
if (NewSuperReg == SuperReg) continue;
|
||||
|
||||
DEBUG(errs() << " " << TRI->getName(Reg));
|
||||
|
||||
// If Reg is dead and Reg's most recent def is not before
|
||||
// SuperRegs's kill, it's safe to replace SuperReg with Reg. We
|
||||
// must also check all subregisters of Reg.
|
||||
if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) {
|
||||
DEBUG(errs() << "(live)");
|
||||
continue;
|
||||
} else {
|
||||
bool found = false;
|
||||
for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
|
||||
*Subreg; ++Subreg) {
|
||||
unsigned SubregReg = *Subreg;
|
||||
if (State->IsLive(SubregReg) || (KillIndices[SuperReg] > DefIndices[SubregReg])) {
|
||||
DEBUG(errs() << "(subreg " << TRI->getName(SubregReg) << " live)");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
DEBUG(errs() << " [" << TRI->getName(NewSuperReg) << ':');
|
||||
RenameMap.clear();
|
||||
|
||||
// For each referenced group register (which must be a SuperReg or
|
||||
// a subregister of SuperReg), find the corresponding subregister
|
||||
// of NewSuperReg and make sure it is free to be renamed.
|
||||
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
||||
unsigned Reg = Regs[i];
|
||||
unsigned NewReg = 0;
|
||||
if (Reg == SuperReg) {
|
||||
NewReg = NewSuperReg;
|
||||
} else {
|
||||
unsigned NewSubRegIdx = TRI->getSubRegIndex(SuperReg, Reg);
|
||||
if (NewSubRegIdx != 0)
|
||||
NewReg = TRI->getSubReg(NewSuperReg, NewSubRegIdx);
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
DEBUG(errs() << " " << TRI->getName(NewReg));
|
||||
|
||||
// Check if Reg can be renamed to NewReg.
|
||||
BitVector BV = RenameRegisterMap[Reg];
|
||||
if (!BV.test(NewReg)) {
|
||||
DEBUG(errs() << "(no rename)");
|
||||
goto next_super_reg;
|
||||
}
|
||||
|
||||
// If NewReg is dead and NewReg's most recent def is not before
|
||||
// Regs's kill, it's safe to replace Reg with NewReg. We
|
||||
// must also check all aliases of NewReg, because we can't define a
|
||||
// register when any sub or super is already live.
|
||||
if (State->IsLive(NewReg) || (KillIndices[Reg] > DefIndices[NewReg])) {
|
||||
DEBUG(errs() << "(live)");
|
||||
goto next_super_reg;
|
||||
} else {
|
||||
bool found = false;
|
||||
for (const unsigned *Alias = TRI->getAliasSet(NewReg);
|
||||
*Alias; ++Alias) {
|
||||
unsigned AliasReg = *Alias;
|
||||
if (State->IsLive(AliasReg) || (KillIndices[Reg] > DefIndices[AliasReg])) {
|
||||
DEBUG(errs() << "(alias " << TRI->getName(AliasReg) << " live)");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
goto next_super_reg;
|
||||
}
|
||||
|
||||
// Record that 'Reg' can be renamed to 'NewReg'.
|
||||
RenameMap.insert(std::pair<unsigned, unsigned>(Reg, NewReg));
|
||||
}
|
||||
|
||||
if (Reg != 0) {
|
||||
DEBUG(errs() << '\n');
|
||||
RenameOrder.erase(SuperRC);
|
||||
RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
|
||||
RenameMap.insert(std::pair<unsigned, unsigned>(SuperReg, Reg));
|
||||
return true;
|
||||
}
|
||||
// If we fall-out here, then every register in the group can be
|
||||
// renamed, as recorded in RenameMap.
|
||||
RenameOrder.erase(SuperRC);
|
||||
RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
|
||||
DEBUG(errs() << "]\n");
|
||||
return true;
|
||||
|
||||
next_super_reg:
|
||||
DEBUG(errs() << ']');
|
||||
} while (R != EndR);
|
||||
|
||||
DEBUG(errs() << '\n');
|
||||
@ -668,7 +696,6 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
///
|
||||
unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
std::vector<SUnit>& SUnits,
|
||||
CandidateMap& Candidates,
|
||||
MachineBasicBlock::iterator& Begin,
|
||||
MachineBasicBlock::iterator& End,
|
||||
unsigned InsertPosIndex) {
|
||||
@ -681,16 +708,6 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
// so just duck out immediately if the block is empty.
|
||||
if (SUnits.empty()) return 0;
|
||||
|
||||
// Manage saved state to enable multiple passes...
|
||||
if (AntiDepTrials > 1) {
|
||||
if (SavedState == NULL) {
|
||||
SavedState = new AggressiveAntiDepState(*State);
|
||||
} else {
|
||||
delete State;
|
||||
State = new AggressiveAntiDepState(*SavedState);
|
||||
}
|
||||
}
|
||||
|
||||
// For each regclass the next register to use for renaming.
|
||||
RenameOrderType RenameOrder;
|
||||
|
||||
@ -719,21 +736,14 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
CriticalPathMI = CriticalPathSU->getInstr();
|
||||
}
|
||||
|
||||
// Even if there are no anti-dependencies we still need to go
|
||||
// through the instructions to update Def, Kills, etc.
|
||||
#ifndef NDEBUG
|
||||
if (Candidates.empty()) {
|
||||
DEBUG(errs() << "\n===== No anti-dependency candidates\n");
|
||||
} else {
|
||||
DEBUG(errs() << "\n===== Attempting to break " << Candidates.size() <<
|
||||
" anti-dependencies\n");
|
||||
DEBUG(errs() << "Available regs:");
|
||||
for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) {
|
||||
if (!State->IsLive(Reg))
|
||||
DEBUG(errs() << " " << TRI->getName(Reg));
|
||||
}
|
||||
DEBUG(errs() << '\n');
|
||||
DEBUG(errs() << "\n===== Aggressive anti-dependency breaking\n");
|
||||
DEBUG(errs() << "Available regs:");
|
||||
for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) {
|
||||
if (!State->IsLive(Reg))
|
||||
DEBUG(errs() << " " << TRI->getName(Reg));
|
||||
}
|
||||
DEBUG(errs() << '\n');
|
||||
#endif
|
||||
|
||||
// Attempt to break anti-dependence edges. Walk the instructions
|
||||
@ -754,14 +764,11 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
// Process the defs in MI...
|
||||
PrescanInstruction(MI, Count, PassthruRegs);
|
||||
|
||||
// The the dependence edges that represent anti- and output-
|
||||
// The dependence edges that represent anti- and output-
|
||||
// dependencies that are candidates for breaking.
|
||||
std::vector<SDep*> Edges;
|
||||
SUnit *PathSU = MISUnitMap[MI];
|
||||
AntiDepBreaker::CandidateMap::iterator
|
||||
citer = Candidates.find(PathSU);
|
||||
if (citer != Candidates.end())
|
||||
AntiDepEdges(PathSU, citer->second, Edges);
|
||||
AntiDepEdges(PathSU, Edges);
|
||||
|
||||
// If MI is not on the critical path, then we don't rename
|
||||
// registers in the CriticalPathSet.
|
||||
@ -817,12 +824,32 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
// anti-dependency since those edges would prevent such
|
||||
// units from being scheduled past each other
|
||||
// regardless.
|
||||
//
|
||||
// Also, if there are dependencies on other SUnits with the
|
||||
// same register as the anti-dependency, don't attempt to
|
||||
// break it.
|
||||
for (SUnit::pred_iterator P = PathSU->Preds.begin(),
|
||||
PE = PathSU->Preds.end(); P != PE; ++P) {
|
||||
if ((P->getSUnit() == NextSU) && (P->getKind() != SDep::Anti)) {
|
||||
if (P->getSUnit() == NextSU ?
|
||||
(P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) :
|
||||
(P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) {
|
||||
AntiDepReg = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (SUnit::pred_iterator P = PathSU->Preds.begin(),
|
||||
PE = PathSU->Preds.end(); P != PE; ++P) {
|
||||
if ((P->getSUnit() == NextSU) && (P->getKind() != SDep::Anti) &&
|
||||
(P->getKind() != SDep::Output)) {
|
||||
DEBUG(errs() << " (real dependency)\n");
|
||||
AntiDepReg = 0;
|
||||
break;
|
||||
} else if ((P->getSUnit() != NextSU) &&
|
||||
(P->getKind() == SDep::Data) &&
|
||||
(P->getReg() == AntiDepReg)) {
|
||||
DEBUG(errs() << " (other dependency)\n");
|
||||
AntiDepReg = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,11 @@
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
/// Class AggressiveAntiDepState
|
||||
/// Contains all the state necessary for anti-dep breaking. We place
|
||||
/// into a separate class so be can conveniently save/restore it to
|
||||
/// enable multi-pass anti-dep breaking.
|
||||
/// Contains all the state necessary for anti-dep breaking.
|
||||
class AggressiveAntiDepState {
|
||||
public:
|
||||
/// RegisterReference - Information about a register reference
|
||||
@ -126,23 +125,11 @@ namespace llvm {
|
||||
/// registers.
|
||||
AggressiveAntiDepState *State;
|
||||
|
||||
/// SavedState - The state for the start of an anti-dep
|
||||
/// region. Used to restore the state at the beginning of each
|
||||
/// pass
|
||||
AggressiveAntiDepState *SavedState;
|
||||
|
||||
public:
|
||||
AggressiveAntiDepBreaker(MachineFunction& MFi,
|
||||
TargetSubtarget::RegClassVector& CriticalPathRCs);
|
||||
~AggressiveAntiDepBreaker();
|
||||
|
||||
/// GetMaxTrials - As anti-dependencies are broken, additional
|
||||
/// dependencies may be exposed, so multiple passes are required.
|
||||
unsigned GetMaxTrials();
|
||||
|
||||
/// NeedCandidates - Candidates required.
|
||||
bool NeedCandidates() { return true; }
|
||||
|
||||
/// Start - Initialize anti-dep breaking for a new basic block.
|
||||
void StartBlock(MachineBasicBlock *BB);
|
||||
|
||||
@ -150,7 +137,6 @@ namespace llvm {
|
||||
/// of the ScheduleDAG and break them by renaming registers.
|
||||
///
|
||||
unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits,
|
||||
CandidateMap& Candidates,
|
||||
MachineBasicBlock::iterator& Begin,
|
||||
MachineBasicBlock::iterator& End,
|
||||
unsigned InsertPosIndex);
|
||||
@ -175,7 +161,9 @@ namespace llvm {
|
||||
/// return that register and all subregisters.
|
||||
void GetPassthruRegs(MachineInstr *MI, std::set<unsigned>& PassthruRegs);
|
||||
|
||||
void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag);
|
||||
void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag,
|
||||
const char *header =NULL, const char *footer =NULL);
|
||||
|
||||
void PrescanInstruction(MachineInstr *MI, unsigned Count,
|
||||
std::set<unsigned>& PassthruRegs);
|
||||
void ScanInstruction(MachineInstr *MI, unsigned Count);
|
||||
|
@ -21,9 +21,7 @@
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -32,20 +30,8 @@ namespace llvm {
|
||||
/// anti-dependencies.
|
||||
class AntiDepBreaker {
|
||||
public:
|
||||
typedef SmallSet<unsigned, 4> AntiDepRegSet;
|
||||
typedef SmallVector<unsigned, 4> AntiDepRegVector;
|
||||
typedef std::map<SUnit *, AntiDepRegVector> CandidateMap;
|
||||
|
||||
virtual ~AntiDepBreaker();
|
||||
|
||||
/// GetMaxTrials - Return the maximum number of anti-dependence
|
||||
/// breaking attempts that will be made for a block.
|
||||
virtual unsigned GetMaxTrials() =0;
|
||||
|
||||
/// NeedCandidates - Return true if the schedule must provide
|
||||
/// candidates with BreakAntiDependencies().
|
||||
virtual bool NeedCandidates() =0;
|
||||
|
||||
/// Start - Initialize anti-dep breaking for a new basic block.
|
||||
virtual void StartBlock(MachineBasicBlock *BB) =0;
|
||||
|
||||
@ -54,7 +40,6 @@ class AntiDepBreaker {
|
||||
/// the number of anti-dependencies broken.
|
||||
///
|
||||
virtual unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits,
|
||||
CandidateMap& Candidates,
|
||||
MachineBasicBlock::iterator& Begin,
|
||||
MachineBasicBlock::iterator& End,
|
||||
unsigned InsertPosIndex) =0;
|
||||
|
@ -728,7 +728,7 @@ static void printStringChar(formatted_raw_ostream &O, unsigned char C) {
|
||||
/// EmitString - Emit a string with quotes and a null terminator.
|
||||
/// Special characters are emitted properly.
|
||||
/// \literal (Eg. '\t') \endliteral
|
||||
void AsmPrinter::EmitString(const std::string &String) const {
|
||||
void AsmPrinter::EmitString(const StringRef String) const {
|
||||
EmitString(String.data(), String.size());
|
||||
}
|
||||
|
||||
@ -1630,12 +1630,14 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
return true;
|
||||
}
|
||||
|
||||
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
|
||||
return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock());
|
||||
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA,
|
||||
const char *Suffix) const {
|
||||
return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock(), Suffix);
|
||||
}
|
||||
|
||||
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
|
||||
const BasicBlock *BB) const {
|
||||
const BasicBlock *BB,
|
||||
const char *Suffix) const {
|
||||
assert(BB->hasName() &&
|
||||
"Address of anonymous basic block not supported yet!");
|
||||
|
||||
@ -1647,7 +1649,8 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
|
||||
SmallString<60> Name;
|
||||
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BA"
|
||||
<< FuncName.size() << '_' << FuncName << '_'
|
||||
<< Mang->makeNameProper(BB->getName());
|
||||
<< Mang->makeNameProper(BB->getName())
|
||||
<< Suffix;
|
||||
|
||||
return OutContext.GetOrCreateSymbol(Name.str());
|
||||
}
|
||||
|
@ -105,26 +105,14 @@ DIE::~DIE() {
|
||||
delete Children[i];
|
||||
}
|
||||
|
||||
/// AddSiblingOffset - Add a sibling offset field to the front of the DIE.
|
||||
/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
|
||||
///
|
||||
void DIE::AddSiblingOffset() {
|
||||
void DIE::addSiblingOffset() {
|
||||
DIEInteger *DI = new DIEInteger(0);
|
||||
Values.insert(Values.begin(), DI);
|
||||
Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void DIE::Profile(FoldingSetNodeID &ID) {
|
||||
Abbrev.Profile(ID);
|
||||
|
||||
for (unsigned i = 0, N = Children.size(); i < N; ++i)
|
||||
ID.AddPointer(Children[i]);
|
||||
|
||||
for (unsigned j = 0, M = Values.size(); j < M; ++j)
|
||||
ID.AddPointer(Values[j]);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIE::print(raw_ostream &O, unsigned IncIndent) {
|
||||
IndentCount += IncIndent;
|
||||
@ -231,16 +219,6 @@ unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void DIEInteger::Profile(FoldingSetNodeID &ID, unsigned Int) {
|
||||
ID.AddInteger(isInteger);
|
||||
ID.AddInteger(Int);
|
||||
}
|
||||
void DIEInteger::Profile(FoldingSetNodeID &ID) {
|
||||
Profile(ID, Integer);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIEInteger::print(raw_ostream &O) {
|
||||
O << "Int: " << (int64_t)Integer
|
||||
@ -258,16 +236,6 @@ void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
|
||||
D->getAsm()->EmitString(Str);
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void DIEString::Profile(FoldingSetNodeID &ID, const std::string &Str) {
|
||||
ID.AddInteger(isString);
|
||||
ID.AddString(Str);
|
||||
}
|
||||
void DIEString::Profile(FoldingSetNodeID &ID) {
|
||||
Profile(ID, Str);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIEString::print(raw_ostream &O) {
|
||||
O << "Str: \"" << Str << "\"";
|
||||
@ -292,16 +260,6 @@ unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
|
||||
return TD->getPointerSize();
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void DIEDwarfLabel::Profile(FoldingSetNodeID &ID, const DWLabel &Label) {
|
||||
ID.AddInteger(isLabel);
|
||||
Label.Profile(ID);
|
||||
}
|
||||
void DIEDwarfLabel::Profile(FoldingSetNodeID &ID) {
|
||||
Profile(ID, Label);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIEDwarfLabel::print(raw_ostream &O) {
|
||||
O << "Lbl: ";
|
||||
@ -327,16 +285,6 @@ unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
|
||||
return TD->getPointerSize();
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void DIEObjectLabel::Profile(FoldingSetNodeID &ID, const std::string &Label) {
|
||||
ID.AddInteger(isAsIsLabel);
|
||||
ID.AddString(Label);
|
||||
}
|
||||
void DIEObjectLabel::Profile(FoldingSetNodeID &ID) {
|
||||
Profile(ID, Label.c_str());
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIEObjectLabel::print(raw_ostream &O) {
|
||||
O << "Obj: " << Label;
|
||||
@ -363,20 +311,6 @@ unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
|
||||
return TD->getPointerSize();
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void DIESectionOffset::Profile(FoldingSetNodeID &ID, const DWLabel &Label,
|
||||
const DWLabel &Section) {
|
||||
ID.AddInteger(isSectionOffset);
|
||||
Label.Profile(ID);
|
||||
Section.Profile(ID);
|
||||
// IsEH and UseSet are specific to the Label/Section that we will emit the
|
||||
// offset for; so Label/Section are enough for uniqueness.
|
||||
}
|
||||
void DIESectionOffset::Profile(FoldingSetNodeID &ID) {
|
||||
Profile(ID, Label, Section);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIESectionOffset::print(raw_ostream &O) {
|
||||
O << "Off: ";
|
||||
@ -405,18 +339,6 @@ unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
|
||||
return TD->getPointerSize();
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void DIEDelta::Profile(FoldingSetNodeID &ID, const DWLabel &LabelHi,
|
||||
const DWLabel &LabelLo) {
|
||||
ID.AddInteger(isDelta);
|
||||
LabelHi.Profile(ID);
|
||||
LabelLo.Profile(ID);
|
||||
}
|
||||
void DIEDelta::Profile(FoldingSetNodeID &ID) {
|
||||
Profile(ID, LabelHi, LabelLo);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIEDelta::print(raw_ostream &O) {
|
||||
O << "Del: ";
|
||||
@ -436,21 +358,6 @@ void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
|
||||
D->getAsm()->EmitInt32(Entry->getOffset());
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void DIEEntry::Profile(FoldingSetNodeID &ID, DIE *Entry) {
|
||||
ID.AddInteger(isEntry);
|
||||
ID.AddPointer(Entry);
|
||||
}
|
||||
void DIEEntry::Profile(FoldingSetNodeID &ID) {
|
||||
ID.AddInteger(isEntry);
|
||||
|
||||
if (Entry)
|
||||
ID.AddPointer(Entry);
|
||||
else
|
||||
ID.AddPointer(this);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIEEntry::print(raw_ostream &O) {
|
||||
O << format("Die: 0x%lx", (long)(intptr_t)Entry);
|
||||
@ -505,11 +412,6 @@ unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DIEBlock::Profile(FoldingSetNodeID &ID) {
|
||||
ID.AddInteger(isBlock);
|
||||
DIE::Profile(ID);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DIEBlock::print(raw_ostream &O) {
|
||||
O << "Blk: ";
|
||||
|
@ -113,7 +113,7 @@ namespace llvm {
|
||||
class CompileUnit;
|
||||
class DIEValue;
|
||||
|
||||
class DIE : public FoldingSetNode {
|
||||
class DIE {
|
||||
protected:
|
||||
/// Abbrev - Buffer for constructing abbreviation.
|
||||
///
|
||||
@ -161,38 +161,28 @@ namespace llvm {
|
||||
void setSize(unsigned S) { Size = S; }
|
||||
void setAbstractCompileUnit(CompileUnit *CU) { AbstractCU = CU; }
|
||||
|
||||
/// AddValue - Add a value and attributes to a DIE.
|
||||
/// addValue - Add a value and attributes to a DIE.
|
||||
///
|
||||
void AddValue(unsigned Attribute, unsigned Form, DIEValue *Value) {
|
||||
void addValue(unsigned Attribute, unsigned Form, DIEValue *Value) {
|
||||
Abbrev.AddAttribute(Attribute, Form);
|
||||
Values.push_back(Value);
|
||||
}
|
||||
|
||||
/// SiblingOffset - Return the offset of the debug information entry's
|
||||
/// sibling.
|
||||
unsigned SiblingOffset() const { return Offset + Size; }
|
||||
unsigned getSiblingOffset() const { return Offset + Size; }
|
||||
|
||||
/// AddSiblingOffset - Add a sibling offset field to the front of the DIE.
|
||||
/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
|
||||
///
|
||||
void AddSiblingOffset();
|
||||
void addSiblingOffset();
|
||||
|
||||
/// AddChild - Add a child to the DIE.
|
||||
/// addChild - Add a child to the DIE.
|
||||
///
|
||||
void AddChild(DIE *Child) {
|
||||
void addChild(DIE *Child) {
|
||||
Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
|
||||
Children.push_back(Child);
|
||||
}
|
||||
|
||||
/// Detach - Detaches objects connected to it after copying.
|
||||
///
|
||||
void Detach() {
|
||||
Children.clear();
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
void Profile(FoldingSetNodeID &ID) ;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void print(raw_ostream &O, unsigned IncIndent = 0);
|
||||
void dump();
|
||||
@ -202,7 +192,7 @@ namespace llvm {
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIEValue - A debug information entry value.
|
||||
///
|
||||
class DIEValue : public FoldingSetNode {
|
||||
class DIEValue {
|
||||
public:
|
||||
enum {
|
||||
isInteger,
|
||||
@ -233,10 +223,6 @@ namespace llvm {
|
||||
///
|
||||
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const = 0;
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
virtual void Profile(FoldingSetNodeID &ID) = 0;
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *) { return true; }
|
||||
|
||||
@ -277,10 +263,6 @@ namespace llvm {
|
||||
///
|
||||
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
static void Profile(FoldingSetNodeID &ID, unsigned Int);
|
||||
virtual void Profile(FoldingSetNodeID &ID);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEInteger *) { return true; }
|
||||
@ -295,9 +277,9 @@ namespace llvm {
|
||||
/// DIEString - A string value DIE.
|
||||
///
|
||||
class DIEString : public DIEValue {
|
||||
const std::string Str;
|
||||
const StringRef Str;
|
||||
public:
|
||||
explicit DIEString(const std::string &S) : DIEValue(isString), Str(S) {}
|
||||
explicit DIEString(const StringRef S) : DIEValue(isString), Str(S) {}
|
||||
|
||||
/// EmitValue - Emit string value.
|
||||
///
|
||||
@ -309,11 +291,6 @@ namespace llvm {
|
||||
return Str.size() + sizeof(char); // sizeof('\0');
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
static void Profile(FoldingSetNodeID &ID, const std::string &Str);
|
||||
virtual void Profile(FoldingSetNodeID &ID);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEString *) { return true; }
|
||||
static bool classof(const DIEValue *S) { return S->getType() == isString; }
|
||||
@ -339,11 +316,6 @@ namespace llvm {
|
||||
///
|
||||
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
static void Profile(FoldingSetNodeID &ID, const DWLabel &Label);
|
||||
virtual void Profile(FoldingSetNodeID &ID);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEDwarfLabel *) { return true; }
|
||||
static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
|
||||
@ -370,11 +342,6 @@ namespace llvm {
|
||||
///
|
||||
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
static void Profile(FoldingSetNodeID &ID, const std::string &Label);
|
||||
virtual void Profile(FoldingSetNodeID &ID);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEObjectLabel *) { return true; }
|
||||
static bool classof(const DIEValue *L) {
|
||||
@ -408,12 +375,6 @@ namespace llvm {
|
||||
///
|
||||
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
static void Profile(FoldingSetNodeID &ID, const DWLabel &Label,
|
||||
const DWLabel &Section);
|
||||
virtual void Profile(FoldingSetNodeID &ID);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIESectionOffset *) { return true; }
|
||||
static bool classof(const DIEValue *D) {
|
||||
@ -443,12 +404,6 @@ namespace llvm {
|
||||
///
|
||||
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
static void Profile(FoldingSetNodeID &ID, const DWLabel &LabelHi,
|
||||
const DWLabel &LabelLo);
|
||||
virtual void Profile(FoldingSetNodeID &ID);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEDelta *) { return true; }
|
||||
static bool classof(const DIEValue *D) { return D->getType() == isDelta; }
|
||||
@ -480,11 +435,6 @@ namespace llvm {
|
||||
return sizeof(int32_t);
|
||||
}
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
static void Profile(FoldingSetNodeID &ID, DIE *Entry);
|
||||
virtual void Profile(FoldingSetNodeID &ID);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEEntry *) { return true; }
|
||||
static bool classof(const DIEValue *E) { return E->getType() == isEntry; }
|
||||
@ -525,10 +475,6 @@ namespace llvm {
|
||||
///
|
||||
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
|
||||
|
||||
/// Profile - Used to gather unique data for the value folding set.
|
||||
///
|
||||
virtual void Profile(FoldingSetNodeID &ID);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEBlock *) { return true; }
|
||||
static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -106,13 +106,9 @@ class DwarfDebug : public Dwarf {
|
||||
/// Lines - List of of source line correspondence.
|
||||
std::vector<SrcLineInfo> Lines;
|
||||
|
||||
/// ValuesSet - Used to uniquely define values.
|
||||
/// DIEValues - A list of all the unique values in use.
|
||||
///
|
||||
FoldingSet<DIEValue> ValuesSet;
|
||||
|
||||
/// Values - A list of all the unique values in use.
|
||||
///
|
||||
std::vector<DIEValue *> Values;
|
||||
std::vector<DIEValue *> DIEValues;
|
||||
|
||||
/// StringPool - A UniqueVector of strings used by indirect references.
|
||||
///
|
||||
@ -229,137 +225,135 @@ class DwarfDebug : public Dwarf {
|
||||
return SourceIds.size();
|
||||
}
|
||||
|
||||
/// AssignAbbrevNumber - Define a unique number for the abbreviation.
|
||||
/// assignAbbrevNumber - Define a unique number for the abbreviation.
|
||||
///
|
||||
void AssignAbbrevNumber(DIEAbbrev &Abbrev);
|
||||
void assignAbbrevNumber(DIEAbbrev &Abbrev);
|
||||
|
||||
/// CreateDIEEntry - Creates a new DIEEntry to be a proxy for a debug
|
||||
/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
|
||||
/// information entry.
|
||||
DIEEntry *CreateDIEEntry(DIE *Entry = NULL);
|
||||
DIEEntry *createDIEEntry(DIE *Entry = NULL);
|
||||
|
||||
/// SetDIEEntry - Set a DIEEntry once the debug information entry is defined.
|
||||
/// addUInt - Add an unsigned integer attribute data and value.
|
||||
///
|
||||
void SetDIEEntry(DIEEntry *Value, DIE *Entry);
|
||||
void addUInt(DIE *Die, unsigned Attribute, unsigned Form, uint64_t Integer);
|
||||
|
||||
/// AddUInt - Add an unsigned integer attribute data and value.
|
||||
/// addSInt - Add an signed integer attribute data and value.
|
||||
///
|
||||
void AddUInt(DIE *Die, unsigned Attribute, unsigned Form, uint64_t Integer);
|
||||
void addSInt(DIE *Die, unsigned Attribute, unsigned Form, int64_t Integer);
|
||||
|
||||
/// AddSInt - Add an signed integer attribute data and value.
|
||||
/// addString - Add a string attribute data and value.
|
||||
///
|
||||
void AddSInt(DIE *Die, unsigned Attribute, unsigned Form, int64_t Integer);
|
||||
void addString(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
const StringRef Str);
|
||||
|
||||
/// AddString - Add a string attribute data and value.
|
||||
/// addLabel - Add a Dwarf label attribute data and value.
|
||||
///
|
||||
void AddString(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
const std::string &String);
|
||||
|
||||
/// AddLabel - Add a Dwarf label attribute data and value.
|
||||
///
|
||||
void AddLabel(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
void addLabel(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
const DWLabel &Label);
|
||||
|
||||
/// AddObjectLabel - Add an non-Dwarf label attribute data and value.
|
||||
/// addObjectLabel - Add an non-Dwarf label attribute data and value.
|
||||
///
|
||||
void AddObjectLabel(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
void addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
const std::string &Label);
|
||||
|
||||
/// AddSectionOffset - Add a section offset label attribute data and value.
|
||||
/// addSectionOffset - Add a section offset label attribute data and value.
|
||||
///
|
||||
void AddSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
void addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
const DWLabel &Label, const DWLabel &Section,
|
||||
bool isEH = false, bool useSet = true);
|
||||
|
||||
/// AddDelta - Add a label delta attribute data and value.
|
||||
/// addDelta - Add a label delta attribute data and value.
|
||||
///
|
||||
void AddDelta(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
void addDelta(DIE *Die, unsigned Attribute, unsigned Form,
|
||||
const DWLabel &Hi, const DWLabel &Lo);
|
||||
|
||||
/// AddDIEEntry - Add a DIE attribute data and value.
|
||||
/// addDIEEntry - Add a DIE attribute data and value.
|
||||
///
|
||||
void AddDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry) {
|
||||
Die->AddValue(Attribute, Form, CreateDIEEntry(Entry));
|
||||
void addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry) {
|
||||
Die->addValue(Attribute, Form, createDIEEntry(Entry));
|
||||
}
|
||||
|
||||
/// AddBlock - Add block data.
|
||||
/// addBlock - Add block data.
|
||||
///
|
||||
void AddBlock(DIE *Die, unsigned Attribute, unsigned Form, DIEBlock *Block);
|
||||
void addBlock(DIE *Die, unsigned Attribute, unsigned Form, DIEBlock *Block);
|
||||
|
||||
/// AddSourceLine - Add location information to specified debug information
|
||||
/// addSourceLine - Add location information to specified debug information
|
||||
/// entry.
|
||||
void AddSourceLine(DIE *Die, const DIVariable *V);
|
||||
void AddSourceLine(DIE *Die, const DIGlobal *G);
|
||||
void AddSourceLine(DIE *Die, const DISubprogram *SP);
|
||||
void AddSourceLine(DIE *Die, const DIType *Ty);
|
||||
void addSourceLine(DIE *Die, const DIVariable *V);
|
||||
void addSourceLine(DIE *Die, const DIGlobal *G);
|
||||
void addSourceLine(DIE *Die, const DISubprogram *SP);
|
||||
void addSourceLine(DIE *Die, const DIType *Ty);
|
||||
|
||||
/// AddAddress - Add an address attribute to a die based on the location
|
||||
/// addAddress - Add an address attribute to a die based on the location
|
||||
/// provided.
|
||||
void AddAddress(DIE *Die, unsigned Attribute,
|
||||
void addAddress(DIE *Die, unsigned Attribute,
|
||||
const MachineLocation &Location);
|
||||
|
||||
/// AddComplexAddress - Start with the address based on the location provided,
|
||||
/// addComplexAddress - Start with the address based on the location provided,
|
||||
/// and generate the DWARF information necessary to find the actual variable
|
||||
/// (navigating the extra location information encoded in the type) based on
|
||||
/// the starting location. Add the DWARF information to the die.
|
||||
///
|
||||
void AddComplexAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
|
||||
void addComplexAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
|
||||
const MachineLocation &Location);
|
||||
|
||||
// FIXME: Should be reformulated in terms of AddComplexAddress.
|
||||
/// AddBlockByrefAddress - Start with the address based on the location
|
||||
// FIXME: Should be reformulated in terms of addComplexAddress.
|
||||
/// addBlockByrefAddress - Start with the address based on the location
|
||||
/// provided, and generate the DWARF information necessary to find the
|
||||
/// actual Block variable (navigating the Block struct) based on the
|
||||
/// starting location. Add the DWARF information to the die. Obsolete,
|
||||
/// please use AddComplexAddress instead.
|
||||
/// please use addComplexAddress instead.
|
||||
///
|
||||
void AddBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
|
||||
void addBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
|
||||
const MachineLocation &Location);
|
||||
|
||||
/// AddType - Add a new type attribute to the specified entity.
|
||||
void AddType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty);
|
||||
/// addType - Add a new type attribute to the specified entity.
|
||||
void addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty);
|
||||
|
||||
/// ConstructTypeDIE - Construct basic type die from DIBasicType.
|
||||
void ConstructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
|
||||
void addPubTypes(DISubprogram SP);
|
||||
|
||||
/// constructTypeDIE - Construct basic type die from DIBasicType.
|
||||
void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
|
||||
DIBasicType BTy);
|
||||
|
||||
/// ConstructTypeDIE - Construct derived type die from DIDerivedType.
|
||||
void ConstructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
|
||||
/// constructTypeDIE - Construct derived type die from DIDerivedType.
|
||||
void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
|
||||
DIDerivedType DTy);
|
||||
|
||||
/// ConstructTypeDIE - Construct type DIE from DICompositeType.
|
||||
void ConstructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
|
||||
/// constructTypeDIE - Construct type DIE from DICompositeType.
|
||||
void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
|
||||
DICompositeType CTy);
|
||||
|
||||
/// ConstructSubrangeDIE - Construct subrange DIE from DISubrange.
|
||||
void ConstructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy);
|
||||
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
|
||||
void constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy);
|
||||
|
||||
/// ConstructArrayTypeDIE - Construct array type DIE from DICompositeType.
|
||||
void ConstructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
|
||||
/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
|
||||
void constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
|
||||
DICompositeType *CTy);
|
||||
|
||||
/// ConstructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
|
||||
DIE *ConstructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy);
|
||||
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
|
||||
DIE *constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy);
|
||||
|
||||
/// CreateGlobalVariableDIE - Create new DIE using GV.
|
||||
DIE *CreateGlobalVariableDIE(CompileUnit *DW_Unit,
|
||||
/// createGlobalVariableDIE - Create new DIE using GV.
|
||||
DIE *createGlobalVariableDIE(CompileUnit *DW_Unit,
|
||||
const DIGlobalVariable &GV);
|
||||
|
||||
/// CreateMemberDIE - Create new member DIE.
|
||||
DIE *CreateMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT);
|
||||
/// createMemberDIE - Create new member DIE.
|
||||
DIE *createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT);
|
||||
|
||||
/// CreateSubprogramDIE - Create new DIE using SP.
|
||||
DIE *CreateSubprogramDIE(CompileUnit *DW_Unit,
|
||||
/// createSubprogramDIE - Create new DIE using SP.
|
||||
DIE *createSubprogramDIE(CompileUnit *DW_Unit,
|
||||
const DISubprogram &SP,
|
||||
bool IsConstructor = false,
|
||||
bool IsInlined = false);
|
||||
|
||||
/// FindCompileUnit - Get the compile unit for the given descriptor.
|
||||
/// findCompileUnit - Get the compile unit for the given descriptor.
|
||||
///
|
||||
CompileUnit &FindCompileUnit(DICompileUnit Unit) const;
|
||||
CompileUnit &findCompileUnit(DICompileUnit Unit) const;
|
||||
|
||||
/// CreateDbgScopeVariable - Create a new scope variable.
|
||||
/// createDbgScopeVariable - Create a new scope variable.
|
||||
///
|
||||
DIE *CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit);
|
||||
DIE *createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit);
|
||||
|
||||
/// getUpdatedDbgScope - Find or create DbgScope assicated with
|
||||
/// the instruction. Initialize scope and update scope hierarchy.
|
||||
@ -374,88 +368,101 @@ class DwarfDebug : public Dwarf {
|
||||
DbgVariable *findAbstractVariable(DIVariable &Var, unsigned FrameIdx,
|
||||
DILocation &Loc);
|
||||
|
||||
DIE *UpdateSubprogramScopeDIE(MDNode *SPNode);
|
||||
DIE *ConstructLexicalScopeDIE(DbgScope *Scope);
|
||||
DIE *ConstructScopeDIE(DbgScope *Scope);
|
||||
DIE *ConstructInlinedScopeDIE(DbgScope *Scope);
|
||||
DIE *ConstructVariableDIE(DbgVariable *DV, DbgScope *S, CompileUnit *Unit);
|
||||
/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
|
||||
/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
|
||||
/// If there are global variables in this scope then create and insert
|
||||
/// DIEs for these variables.
|
||||
DIE *updateSubprogramScopeDIE(MDNode *SPNode);
|
||||
|
||||
/// ConstructDbgScope - Construct the components of a scope.
|
||||
///
|
||||
void ConstructDbgScope(DbgScope *ParentScope,
|
||||
unsigned ParentStartID, unsigned ParentEndID,
|
||||
DIE *ParentDie, CompileUnit *Unit);
|
||||
/// constructLexicalScope - Construct new DW_TAG_lexical_block
|
||||
/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
|
||||
DIE *constructLexicalScopeDIE(DbgScope *Scope);
|
||||
|
||||
/// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc
|
||||
/// constructInlinedScopeDIE - This scope represents inlined body of
|
||||
/// a function. Construct DIE to represent this concrete inlined copy
|
||||
/// of the function.
|
||||
DIE *constructInlinedScopeDIE(DbgScope *Scope);
|
||||
|
||||
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
|
||||
DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S, CompileUnit *Unit);
|
||||
|
||||
/// constructScopeDIE - Construct a DIE for this scope.
|
||||
DIE *constructScopeDIE(DbgScope *Scope);
|
||||
|
||||
/// emitInitial - Emit initial Dwarf declarations. This is necessary for cc
|
||||
/// tools to recognize the object file contains Dwarf information.
|
||||
void EmitInitial();
|
||||
void emitInitial();
|
||||
|
||||
/// EmitDIE - Recusively Emits a debug information entry.
|
||||
/// emitDIE - Recusively Emits a debug information entry.
|
||||
///
|
||||
void EmitDIE(DIE *Die);
|
||||
void emitDIE(DIE *Die);
|
||||
|
||||
/// SizeAndOffsetDie - Compute the size and offset of a DIE.
|
||||
/// computeSizeAndOffset - Compute the size and offset of a DIE.
|
||||
///
|
||||
unsigned SizeAndOffsetDie(DIE *Die, unsigned Offset, bool Last);
|
||||
unsigned computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last);
|
||||
|
||||
/// SizeAndOffsets - Compute the size and offset of all the DIEs.
|
||||
/// computeSizeAndOffsets - Compute the size and offset of all the DIEs.
|
||||
///
|
||||
void SizeAndOffsets();
|
||||
void computeSizeAndOffsets();
|
||||
|
||||
/// EmitDebugInfo / EmitDebugInfoPerCU - Emit the debug info section.
|
||||
/// EmitDebugInfo / emitDebugInfoPerCU - Emit the debug info section.
|
||||
///
|
||||
void EmitDebugInfoPerCU(CompileUnit *Unit);
|
||||
void emitDebugInfoPerCU(CompileUnit *Unit);
|
||||
|
||||
void EmitDebugInfo();
|
||||
void emitDebugInfo();
|
||||
|
||||
/// EmitAbbreviations - Emit the abbreviation section.
|
||||
/// emitAbbreviations - Emit the abbreviation section.
|
||||
///
|
||||
void EmitAbbreviations() const;
|
||||
void emitAbbreviations() const;
|
||||
|
||||
/// EmitEndOfLineMatrix - Emit the last address of the section and the end of
|
||||
/// emitEndOfLineMatrix - Emit the last address of the section and the end of
|
||||
/// the line matrix.
|
||||
///
|
||||
void EmitEndOfLineMatrix(unsigned SectionEnd);
|
||||
void emitEndOfLineMatrix(unsigned SectionEnd);
|
||||
|
||||
/// EmitDebugLines - Emit source line information.
|
||||
/// emitDebugLines - Emit source line information.
|
||||
///
|
||||
void EmitDebugLines();
|
||||
void emitDebugLines();
|
||||
|
||||
/// EmitCommonDebugFrame - Emit common frame info into a debug frame section.
|
||||
/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
|
||||
///
|
||||
void EmitCommonDebugFrame();
|
||||
void emitCommonDebugFrame();
|
||||
|
||||
/// EmitFunctionDebugFrame - Emit per function frame info into a debug frame
|
||||
/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
|
||||
/// section.
|
||||
void EmitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo);
|
||||
void emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo);
|
||||
|
||||
void EmitDebugPubNamesPerCU(CompileUnit *Unit);
|
||||
void emitDebugPubNamesPerCU(CompileUnit *Unit);
|
||||
|
||||
/// EmitDebugPubNames - Emit visible names into a debug pubnames section.
|
||||
/// emitDebugPubNames - Emit visible names into a debug pubnames section.
|
||||
///
|
||||
void EmitDebugPubNames();
|
||||
void emitDebugPubNames();
|
||||
|
||||
/// EmitDebugStr - Emit visible names into a debug str section.
|
||||
/// emitDebugPubTypes - Emit visible types into a debug pubtypes section.
|
||||
///
|
||||
void EmitDebugStr();
|
||||
void emitDebugPubTypes();
|
||||
|
||||
/// EmitDebugLoc - Emit visible names into a debug loc section.
|
||||
/// emitDebugStr - Emit visible names into a debug str section.
|
||||
///
|
||||
void EmitDebugLoc();
|
||||
void emitDebugStr();
|
||||
|
||||
/// emitDebugLoc - Emit visible names into a debug loc section.
|
||||
///
|
||||
void emitDebugLoc();
|
||||
|
||||
/// EmitDebugARanges - Emit visible names into a debug aranges section.
|
||||
///
|
||||
void EmitDebugARanges();
|
||||
|
||||
/// EmitDebugRanges - Emit visible names into a debug ranges section.
|
||||
/// emitDebugRanges - Emit visible names into a debug ranges section.
|
||||
///
|
||||
void EmitDebugRanges();
|
||||
void emitDebugRanges();
|
||||
|
||||
/// EmitDebugMacInfo - Emit visible names into a debug macinfo section.
|
||||
/// emitDebugMacInfo - Emit visible names into a debug macinfo section.
|
||||
///
|
||||
void EmitDebugMacInfo();
|
||||
void emitDebugMacInfo();
|
||||
|
||||
/// EmitDebugInlineInfo - Emit inline info using following format.
|
||||
/// emitDebugInlineInfo - Emit inline info using following format.
|
||||
/// Section Header:
|
||||
/// 1. length of section
|
||||
/// 2. Dwarf version number
|
||||
@ -473,26 +480,25 @@ class DwarfDebug : public Dwarf {
|
||||
/// inlined instance; the die_offset points to the inlined_subroutine die in
|
||||
/// the __debug_info section, and the low_pc is the starting address for the
|
||||
/// inlining instance.
|
||||
void EmitDebugInlineInfo();
|
||||
void emitDebugInlineInfo();
|
||||
|
||||
/// GetOrCreateSourceID - Look up the source id with the given directory and
|
||||
/// source file names. If none currently exists, create a new id and insert it
|
||||
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
|
||||
/// as well.
|
||||
unsigned GetOrCreateSourceID(const char *DirName,
|
||||
const char *FileName);
|
||||
unsigned GetOrCreateSourceID(StringRef DirName, StringRef FileName);
|
||||
|
||||
void ConstructCompileUnit(MDNode *N);
|
||||
void constructCompileUnit(MDNode *N);
|
||||
|
||||
void ConstructGlobalVariableDIE(MDNode *N);
|
||||
void constructGlobalVariableDIE(MDNode *N);
|
||||
|
||||
void ConstructSubprogram(MDNode *N);
|
||||
void constructSubprogramDIE(MDNode *N);
|
||||
|
||||
// FIXME: This should go away in favor of complex addresses.
|
||||
/// Find the type the programmer originally declared the variable to be
|
||||
/// and return that type. Obsolete, use GetComplexAddrType instead.
|
||||
///
|
||||
DIType GetBlockByrefType(DIType Ty, std::string Name);
|
||||
DIType getBlockByrefType(DIType Ty, std::string Name);
|
||||
|
||||
public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -505,30 +511,30 @@ class DwarfDebug : public Dwarf {
|
||||
/// be emitted.
|
||||
bool ShouldEmitDwarfDebug() const { return shouldEmit; }
|
||||
|
||||
/// BeginModule - Emit all Dwarf sections that should come prior to the
|
||||
/// beginModule - Emit all Dwarf sections that should come prior to the
|
||||
/// content.
|
||||
void BeginModule(Module *M, MachineModuleInfo *MMI);
|
||||
void beginModule(Module *M, MachineModuleInfo *MMI);
|
||||
|
||||
/// EndModule - Emit all Dwarf sections that should come after the content.
|
||||
/// endModule - Emit all Dwarf sections that should come after the content.
|
||||
///
|
||||
void EndModule();
|
||||
void endModule();
|
||||
|
||||
/// BeginFunction - Gather pre-function debug information. Assumes being
|
||||
/// beginFunction - Gather pre-function debug information. Assumes being
|
||||
/// emitted immediately after the function entry point.
|
||||
void BeginFunction(MachineFunction *MF);
|
||||
void beginFunction(MachineFunction *MF);
|
||||
|
||||
/// EndFunction - Gather and emit post-function debug information.
|
||||
/// endFunction - Gather and emit post-function debug information.
|
||||
///
|
||||
void EndFunction(MachineFunction *MF);
|
||||
void endFunction(MachineFunction *MF);
|
||||
|
||||
/// RecordSourceLine - Records location information and associates it with a
|
||||
/// recordSourceLine - Records location information and associates it with a
|
||||
/// label. Returns a unique label ID used to generate a label and provide
|
||||
/// correspondence to the source line list.
|
||||
unsigned RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
|
||||
unsigned recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
|
||||
|
||||
/// getRecordSourceLineCount - Return the number of source lines in the debug
|
||||
/// getSourceLineCount - Return the number of source lines in the debug
|
||||
/// info.
|
||||
unsigned getRecordSourceLineCount() const {
|
||||
unsigned getSourceLineCount() const {
|
||||
return Lines.size();
|
||||
}
|
||||
|
||||
@ -540,22 +546,18 @@ class DwarfDebug : public Dwarf {
|
||||
unsigned getOrCreateSourceID(const std::string &DirName,
|
||||
const std::string &FileName);
|
||||
|
||||
/// ExtractScopeInformation - Scan machine instructions in this function
|
||||
/// extractScopeInformation - Scan machine instructions in this function
|
||||
/// and collect DbgScopes. Return true, if atleast one scope was found.
|
||||
bool ExtractScopeInformation(MachineFunction *MF);
|
||||
bool extractScopeInformation(MachineFunction *MF);
|
||||
|
||||
/// CollectVariableInfo - Populate DbgScope entries with variables' info.
|
||||
void CollectVariableInfo();
|
||||
/// collectVariableInfo - Populate DbgScope entries with variables' info.
|
||||
void collectVariableInfo();
|
||||
|
||||
/// SetDbgScopeEndLabels - Update DbgScope end labels for the scopes that
|
||||
/// end with this machine instruction.
|
||||
void SetDbgScopeEndLabels(const MachineInstr *MI, unsigned Label);
|
||||
/// beginScope - Process beginning of a scope starting at Label.
|
||||
void beginScope(const MachineInstr *MI, unsigned Label);
|
||||
|
||||
/// BeginScope - Process beginning of a scope starting at Label.
|
||||
void BeginScope(const MachineInstr *MI, unsigned Label);
|
||||
|
||||
/// EndScope - Prcess end of a scope.
|
||||
void EndScope(const MachineInstr *MI);
|
||||
/// endScope - Prcess end of a scope.
|
||||
void endScope(const MachineInstr *MI);
|
||||
};
|
||||
} // End of namespace llvm
|
||||
|
||||
|
@ -727,8 +727,7 @@ void DwarfException::EmitExceptionTable() {
|
||||
// somewhere. This predicate should be moved to a shared location that is
|
||||
// in target-independent code.
|
||||
//
|
||||
if ((LSDASection->getKind().isWriteable() &&
|
||||
!LSDASection->getKind().isReadOnlyWithRel()) ||
|
||||
if (LSDASection->getKind().isWriteable() ||
|
||||
Asm->TM.getRelocationModel() == Reloc::Static)
|
||||
TTypeFormat = dwarf::DW_EH_PE_absptr;
|
||||
else
|
||||
@ -918,36 +917,14 @@ void DwarfException::EmitExceptionTable() {
|
||||
}
|
||||
|
||||
// Emit the Catch TypeInfos.
|
||||
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
|
||||
unsigned Index = 1;
|
||||
|
||||
for (std::vector<GlobalVariable *>::const_reverse_iterator
|
||||
I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
|
||||
const GlobalVariable *TI = *I;
|
||||
const GlobalVariable *GV = *I;
|
||||
PrintRelDirective();
|
||||
|
||||
if (TI) {
|
||||
if (!LSDASection->getKind().isReadOnlyWithRel() &&
|
||||
(TTypeFormat == dwarf::DW_EH_PE_absptr ||
|
||||
TI->getLinkage() == GlobalValue::InternalLinkage)) {
|
||||
// Print out the unadorned name of the type info.
|
||||
PrintRelDirective();
|
||||
O << Asm->Mang->getMangledName(TI);
|
||||
} else {
|
||||
bool IsTypeInfoIndirect = false, IsTypeInfoPCRel = false;
|
||||
const MCExpr *TypeInfoRef =
|
||||
TLOF.getSymbolForDwarfGlobalReference(TI, Asm->Mang, Asm->MMI,
|
||||
IsTypeInfoIndirect,
|
||||
IsTypeInfoPCRel);
|
||||
|
||||
if (!IsTypeInfoPCRel)
|
||||
TypeInfoRef = CreateLabelDiff(TypeInfoRef, "typeinforef_addr",
|
||||
Index++);
|
||||
|
||||
O << MAI->getData32bitsDirective();
|
||||
TypeInfoRef->print(O, MAI);
|
||||
}
|
||||
if (GV) {
|
||||
O << Asm->Mang->getMangledName(GV);
|
||||
} else {
|
||||
PrintRelDirective();
|
||||
O << "0x0";
|
||||
}
|
||||
|
||||
|
@ -43,14 +43,14 @@ void DwarfWriter::BeginModule(Module *M,
|
||||
DE = new DwarfException(OS, A, T);
|
||||
DD = new DwarfDebug(OS, A, T);
|
||||
DE->BeginModule(M, MMI);
|
||||
DD->BeginModule(M, MMI);
|
||||
DD->beginModule(M, MMI);
|
||||
}
|
||||
|
||||
/// EndModule - Emit all Dwarf sections that should come after the content.
|
||||
///
|
||||
void DwarfWriter::EndModule() {
|
||||
DE->EndModule();
|
||||
DD->EndModule();
|
||||
DD->endModule();
|
||||
delete DD; DD = 0;
|
||||
delete DE; DE = 0;
|
||||
}
|
||||
@ -59,13 +59,13 @@ void DwarfWriter::EndModule() {
|
||||
/// emitted immediately after the function entry point.
|
||||
void DwarfWriter::BeginFunction(MachineFunction *MF) {
|
||||
DE->BeginFunction(MF);
|
||||
DD->BeginFunction(MF);
|
||||
DD->beginFunction(MF);
|
||||
}
|
||||
|
||||
/// EndFunction - Gather and emit post-function debug information.
|
||||
///
|
||||
void DwarfWriter::EndFunction(MachineFunction *MF) {
|
||||
DD->EndFunction(MF);
|
||||
DD->endFunction(MF);
|
||||
DE->EndFunction();
|
||||
|
||||
if (MachineModuleInfo *MMI = DD->getMMI() ? DD->getMMI() : DE->getMMI())
|
||||
@ -78,12 +78,12 @@ void DwarfWriter::EndFunction(MachineFunction *MF) {
|
||||
/// correspondence to the source line list.
|
||||
unsigned DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
|
||||
MDNode *Scope) {
|
||||
return DD->RecordSourceLine(Line, Col, Scope);
|
||||
return DD->recordSourceLine(Line, Col, Scope);
|
||||
}
|
||||
|
||||
/// getRecordSourceLineCount - Count source lines.
|
||||
unsigned DwarfWriter::getRecordSourceLineCount() {
|
||||
return DD->getRecordSourceLineCount();
|
||||
return DD->getSourceLineCount();
|
||||
}
|
||||
|
||||
/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
|
||||
@ -93,8 +93,8 @@ bool DwarfWriter::ShouldEmitDwarfDebug() const {
|
||||
}
|
||||
|
||||
void DwarfWriter::BeginScope(const MachineInstr *MI, unsigned L) {
|
||||
DD->BeginScope(MI, L);
|
||||
DD->beginScope(MI, L);
|
||||
}
|
||||
void DwarfWriter::EndScope(const MachineInstr *MI) {
|
||||
DD->EndScope(MI);
|
||||
DD->endScope(MI);
|
||||
}
|
||||
|
@ -41,8 +41,6 @@ using namespace llvm;
|
||||
STATISTIC(NumDeadBlocks, "Number of dead blocks removed");
|
||||
STATISTIC(NumBranchOpts, "Number of branches optimized");
|
||||
STATISTIC(NumTailMerge , "Number of block tails merged");
|
||||
STATISTIC(NumTailDups , "Number of tail duplicated blocks");
|
||||
STATISTIC(NumInstrDups , "Additional instructions due to tail duplication");
|
||||
|
||||
static cl::opt<cl::boolOrDefault> FlagEnableTailMerge("enable-tail-merge",
|
||||
cl::init(cl::BOU_UNSET), cl::Hidden);
|
||||
@ -205,16 +203,6 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
|
||||
MadeChange |= MadeChangeThisIteration;
|
||||
}
|
||||
|
||||
// Do tail duplication after tail merging is done. Otherwise it is
|
||||
// tough to avoid situations where tail duplication and tail merging undo
|
||||
// each other's transformations ad infinitum.
|
||||
MadeChangeThisIteration = true;
|
||||
while (MadeChangeThisIteration) {
|
||||
MadeChangeThisIteration = false;
|
||||
MadeChangeThisIteration |= TailDuplicateBlocks(MF);
|
||||
MadeChange |= MadeChangeThisIteration;
|
||||
}
|
||||
|
||||
// See if any jump tables have become mergable or dead as the code generator
|
||||
// did its thing.
|
||||
MachineJumpTableInfo *JTI = MF.getJumpTableInfo();
|
||||
@ -918,71 +906,6 @@ bool BranchFolder::OptimizeBranches(MachineFunction &MF) {
|
||||
}
|
||||
|
||||
|
||||
/// CanFallThrough - Return true if the specified block (with the specified
|
||||
/// branch condition) can implicitly transfer control to the block after it by
|
||||
/// falling off the end of it. This should return false if it can reach the
|
||||
/// block after it, but it uses an explicit branch to do so (e.g. a table jump).
|
||||
///
|
||||
/// True is a conservative answer.
|
||||
///
|
||||
bool BranchFolder::CanFallThrough(MachineBasicBlock *CurBB,
|
||||
bool BranchUnAnalyzable,
|
||||
MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond) {
|
||||
MachineFunction::iterator Fallthrough = CurBB;
|
||||
++Fallthrough;
|
||||
// If FallthroughBlock is off the end of the function, it can't fall through.
|
||||
if (Fallthrough == CurBB->getParent()->end())
|
||||
return false;
|
||||
|
||||
// If FallthroughBlock isn't a successor of CurBB, no fallthrough is possible.
|
||||
if (!CurBB->isSuccessor(Fallthrough))
|
||||
return false;
|
||||
|
||||
// If we couldn't analyze the branch, examine the last instruction.
|
||||
// If the block doesn't end in a known control barrier, assume fallthrough
|
||||
// is possible. The isPredicable check is needed because this code can be
|
||||
// called during IfConversion, where an instruction which is normally a
|
||||
// Barrier is predicated and thus no longer an actual control barrier. This
|
||||
// is over-conservative though, because if an instruction isn't actually
|
||||
// predicated we could still treat it like a barrier.
|
||||
if (BranchUnAnalyzable)
|
||||
return CurBB->empty() || !CurBB->back().getDesc().isBarrier() ||
|
||||
CurBB->back().getDesc().isPredicable();
|
||||
|
||||
// If there is no branch, control always falls through.
|
||||
if (TBB == 0) return true;
|
||||
|
||||
// If there is some explicit branch to the fallthrough block, it can obviously
|
||||
// reach, even though the branch should get folded to fall through implicitly.
|
||||
if (MachineFunction::iterator(TBB) == Fallthrough ||
|
||||
MachineFunction::iterator(FBB) == Fallthrough)
|
||||
return true;
|
||||
|
||||
// If it's an unconditional branch to some block not the fall through, it
|
||||
// doesn't fall through.
|
||||
if (Cond.empty()) return false;
|
||||
|
||||
// Otherwise, if it is conditional and has no explicit false block, it falls
|
||||
// through.
|
||||
return FBB == 0;
|
||||
}
|
||||
|
||||
/// CanFallThrough - Return true if the specified can implicitly transfer
|
||||
/// control to the block after it by falling off the end of it. This should
|
||||
/// return false if it can reach the block after it, but it uses an explicit
|
||||
/// branch to do so (e.g. a table jump).
|
||||
///
|
||||
/// True is a conservative answer.
|
||||
///
|
||||
bool BranchFolder::CanFallThrough(MachineBasicBlock *CurBB) {
|
||||
MachineBasicBlock *TBB = 0, *FBB = 0;
|
||||
SmallVector<MachineOperand, 4> Cond;
|
||||
bool CurUnAnalyzable = TII->AnalyzeBranch(*CurBB, TBB, FBB, Cond, true);
|
||||
return CanFallThrough(CurBB, CurUnAnalyzable, TBB, FBB, Cond);
|
||||
}
|
||||
|
||||
/// IsBetterFallthrough - Return true if it would be clearly better to
|
||||
/// fall-through to MBB1 than to fall through into MBB2. This has to return
|
||||
/// a strict ordering, returning true for both (MBB1,MBB2) and (MBB2,MBB1) will
|
||||
@ -1005,143 +928,6 @@ static bool IsBetterFallthrough(MachineBasicBlock *MBB1,
|
||||
return MBB2I->getDesc().isCall() && !MBB1I->getDesc().isCall();
|
||||
}
|
||||
|
||||
/// TailDuplicateBlocks - Look for small blocks that are unconditionally
|
||||
/// branched to and do not fall through. Tail-duplicate their instructions
|
||||
/// into their predecessors to eliminate (dynamic) branches.
|
||||
bool BranchFolder::TailDuplicateBlocks(MachineFunction &MF) {
|
||||
bool MadeChange = false;
|
||||
|
||||
for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) {
|
||||
MachineBasicBlock *MBB = I++;
|
||||
|
||||
// Only duplicate blocks that end with unconditional branches.
|
||||
if (CanFallThrough(MBB))
|
||||
continue;
|
||||
|
||||
MadeChange |= TailDuplicate(MBB, MF);
|
||||
|
||||
// If it is dead, remove it.
|
||||
if (MBB->pred_empty()) {
|
||||
NumInstrDups -= MBB->size();
|
||||
RemoveDeadBlock(MBB);
|
||||
MadeChange = true;
|
||||
++NumDeadBlocks;
|
||||
}
|
||||
}
|
||||
return MadeChange;
|
||||
}
|
||||
|
||||
/// TailDuplicate - If it is profitable, duplicate TailBB's contents in each
|
||||
/// of its predecessors.
|
||||
bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB,
|
||||
MachineFunction &MF) {
|
||||
// Don't try to tail-duplicate single-block loops.
|
||||
if (TailBB->isSuccessor(TailBB))
|
||||
return false;
|
||||
|
||||
// Set the limit on the number of instructions to duplicate, with a default
|
||||
// of one less than the tail-merge threshold. When optimizing for size,
|
||||
// duplicate only one, because one branch instruction can be eliminated to
|
||||
// compensate for the duplication.
|
||||
unsigned MaxDuplicateCount =
|
||||
MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize) ?
|
||||
1 : TII->TailDuplicationLimit(*TailBB, TailMergeSize - 1);
|
||||
|
||||
// Check the instructions in the block to determine whether tail-duplication
|
||||
// is invalid or unlikely to be profitable.
|
||||
unsigned i = 0;
|
||||
bool HasCall = false;
|
||||
for (MachineBasicBlock::iterator I = TailBB->begin();
|
||||
I != TailBB->end(); ++I, ++i) {
|
||||
// Non-duplicable things shouldn't be tail-duplicated.
|
||||
if (I->getDesc().isNotDuplicable()) return false;
|
||||
// Don't duplicate more than the threshold.
|
||||
if (i == MaxDuplicateCount) return false;
|
||||
// Remember if we saw a call.
|
||||
if (I->getDesc().isCall()) HasCall = true;
|
||||
}
|
||||
// Heuristically, don't tail-duplicate calls if it would expand code size,
|
||||
// as it's less likely to be worth the extra cost.
|
||||
if (i > 1 && HasCall)
|
||||
return false;
|
||||
|
||||
// Iterate through all the unique predecessors and tail-duplicate this
|
||||
// block into them, if possible. Copying the list ahead of time also
|
||||
// avoids trouble with the predecessor list reallocating.
|
||||
bool Changed = false;
|
||||
SmallSetVector<MachineBasicBlock *, 8> Preds(TailBB->pred_begin(),
|
||||
TailBB->pred_end());
|
||||
for (SmallSetVector<MachineBasicBlock *, 8>::iterator PI = Preds.begin(),
|
||||
PE = Preds.end(); PI != PE; ++PI) {
|
||||
MachineBasicBlock *PredBB = *PI;
|
||||
|
||||
assert(TailBB != PredBB &&
|
||||
"Single-block loop should have been rejected earlier!");
|
||||
if (PredBB->succ_size() > 1) continue;
|
||||
|
||||
MachineBasicBlock *PredTBB, *PredFBB;
|
||||
SmallVector<MachineOperand, 4> PredCond;
|
||||
if (TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true))
|
||||
continue;
|
||||
if (!PredCond.empty())
|
||||
continue;
|
||||
// EH edges are ignored by AnalyzeBranch.
|
||||
if (PredBB->succ_size() != 1)
|
||||
continue;
|
||||
// Don't duplicate into a fall-through predecessor (at least for now).
|
||||
if (PredBB->isLayoutSuccessor(TailBB) && CanFallThrough(PredBB))
|
||||
continue;
|
||||
|
||||
DEBUG(errs() << "\nTail-duplicating into PredBB: " << *PredBB
|
||||
<< "From Succ: " << *TailBB);
|
||||
|
||||
// Remove PredBB's unconditional branch.
|
||||
TII->RemoveBranch(*PredBB);
|
||||
// Clone the contents of TailBB into PredBB.
|
||||
for (MachineBasicBlock::iterator I = TailBB->begin(), E = TailBB->end();
|
||||
I != E; ++I) {
|
||||
MachineInstr *NewMI = MF.CloneMachineInstr(I);
|
||||
PredBB->insert(PredBB->end(), NewMI);
|
||||
}
|
||||
NumInstrDups += TailBB->size() - 1; // subtract one for removed branch
|
||||
|
||||
// Update the CFG.
|
||||
PredBB->removeSuccessor(PredBB->succ_begin());
|
||||
assert(PredBB->succ_empty() &&
|
||||
"TailDuplicate called on block with multiple successors!");
|
||||
for (MachineBasicBlock::succ_iterator I = TailBB->succ_begin(),
|
||||
E = TailBB->succ_end(); I != E; ++I)
|
||||
PredBB->addSuccessor(*I);
|
||||
|
||||
Changed = true;
|
||||
++NumTailDups;
|
||||
}
|
||||
|
||||
// If TailBB was duplicated into all its predecessors except for the prior
|
||||
// block, which falls through unconditionally, move the contents of this
|
||||
// block into the prior block.
|
||||
MachineBasicBlock &PrevBB = *prior(MachineFunction::iterator(TailBB));
|
||||
MachineBasicBlock *PriorTBB = 0, *PriorFBB = 0;
|
||||
SmallVector<MachineOperand, 4> PriorCond;
|
||||
bool PriorUnAnalyzable =
|
||||
TII->AnalyzeBranch(PrevBB, PriorTBB, PriorFBB, PriorCond, true);
|
||||
// This has to check PrevBB->succ_size() because EH edges are ignored by
|
||||
// AnalyzeBranch.
|
||||
if (!PriorUnAnalyzable && PriorCond.empty() && !PriorTBB &&
|
||||
TailBB->pred_size() == 1 && PrevBB.succ_size() == 1 &&
|
||||
!TailBB->hasAddressTaken()) {
|
||||
DEBUG(errs() << "\nMerging into block: " << PrevBB
|
||||
<< "From MBB: " << *TailBB);
|
||||
PrevBB.splice(PrevBB.end(), TailBB, TailBB->begin(), TailBB->end());
|
||||
PrevBB.removeSuccessor(PrevBB.succ_begin());;
|
||||
assert(PrevBB.succ_empty());
|
||||
PrevBB.transferSuccessors(TailBB);
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
/// OptimizeBlock - Analyze and optimize control flow related to the specified
|
||||
/// block. This is never called on the entry block.
|
||||
bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
@ -1266,7 +1052,7 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
// the assert condition out of the loop body.
|
||||
if (MBB->succ_empty() && !PriorCond.empty() && PriorFBB == 0 &&
|
||||
MachineFunction::iterator(PriorTBB) == FallThrough &&
|
||||
!CanFallThrough(MBB)) {
|
||||
!MBB->canFallThrough()) {
|
||||
bool DoTransform = true;
|
||||
|
||||
// We have to be careful that the succs of PredBB aren't both no-successor
|
||||
@ -1290,7 +1076,7 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
// In this case, we could actually be moving the return block *into* a
|
||||
// loop!
|
||||
if (DoTransform && !MBB->succ_empty() &&
|
||||
(!CanFallThrough(PriorTBB) || PriorTBB->empty()))
|
||||
(!PriorTBB->canFallThrough() || PriorTBB->empty()))
|
||||
DoTransform = false;
|
||||
|
||||
|
||||
@ -1422,13 +1208,11 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
// If the prior block doesn't fall through into this block, and if this
|
||||
// block doesn't fall through into some other block, see if we can find a
|
||||
// place to move this block where a fall-through will happen.
|
||||
if (!CanFallThrough(&PrevBB, PriorUnAnalyzable,
|
||||
PriorTBB, PriorFBB, PriorCond)) {
|
||||
if (!PrevBB.canFallThrough()) {
|
||||
|
||||
// Now we know that there was no fall-through into this block, check to
|
||||
// see if it has a fall-through into its successor.
|
||||
bool CurFallsThru = CanFallThrough(MBB, CurUnAnalyzable, CurTBB, CurFBB,
|
||||
CurCond);
|
||||
bool CurFallsThru = MBB->canFallThrough();
|
||||
|
||||
if (!MBB->isLandingPad()) {
|
||||
// Check all the predecessors of this block. If one of them has no fall
|
||||
@ -1440,7 +1224,7 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
MachineFunction::iterator PredFallthrough = PredBB; ++PredFallthrough;
|
||||
MachineBasicBlock *PredTBB, *PredFBB;
|
||||
SmallVector<MachineOperand, 4> PredCond;
|
||||
if (PredBB != MBB && !CanFallThrough(PredBB) &&
|
||||
if (PredBB != MBB && !PredBB->canFallThrough() &&
|
||||
!TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true)
|
||||
&& (!CurFallsThru || !CurTBB || !CurFBB)
|
||||
&& (!CurFallsThru || MBB->getNumber() >= PredBB->getNumber())) {
|
||||
@ -1479,7 +1263,7 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
// and if the successor isn't an EH destination, we can arrange for the
|
||||
// fallthrough to happen.
|
||||
if (SuccBB != MBB && &*SuccPrev != MBB &&
|
||||
!CanFallThrough(SuccPrev) && !CurUnAnalyzable &&
|
||||
!SuccPrev->canFallThrough() && !CurUnAnalyzable &&
|
||||
!SuccBB->isLandingPad()) {
|
||||
MBB->moveBefore(SuccBB);
|
||||
MadeChange = true;
|
||||
|
@ -105,18 +105,10 @@ namespace llvm {
|
||||
unsigned CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,
|
||||
unsigned maxCommonTailLength);
|
||||
|
||||
bool TailDuplicateBlocks(MachineFunction &MF);
|
||||
bool TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF);
|
||||
|
||||
bool OptimizeBranches(MachineFunction &MF);
|
||||
bool OptimizeBlock(MachineBasicBlock *MBB);
|
||||
void RemoveDeadBlock(MachineBasicBlock *MBB);
|
||||
bool OptimizeImpDefsBlock(MachineBasicBlock *MBB);
|
||||
|
||||
bool CanFallThrough(MachineBasicBlock *CurBB);
|
||||
bool CanFallThrough(MachineBasicBlock *CurBB, bool BranchUnAnalyzable,
|
||||
MachineBasicBlock *TBB, MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ add_llvm_library(LLVMCodeGen
|
||||
StackProtector.cpp
|
||||
StackSlotColoring.cpp
|
||||
StrongPHIElimination.cpp
|
||||
TailDuplication.cpp
|
||||
TargetInstrInfoImpl.cpp
|
||||
TwoAddressInstructionPass.cpp
|
||||
UnreachableBlockElim.cpp
|
||||
|
@ -316,7 +316,6 @@ CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg,
|
||||
|
||||
unsigned CriticalAntiDepBreaker::
|
||||
BreakAntiDependencies(std::vector<SUnit>& SUnits,
|
||||
CandidateMap& Candidates,
|
||||
MachineBasicBlock::iterator& Begin,
|
||||
MachineBasicBlock::iterator& End,
|
||||
unsigned InsertPosIndex) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
class CriticalAntiDepBreaker : public AntiDepBreaker {
|
||||
@ -64,13 +65,6 @@ namespace llvm {
|
||||
CriticalAntiDepBreaker(MachineFunction& MFi);
|
||||
~CriticalAntiDepBreaker();
|
||||
|
||||
/// GetMaxTrials - Critical path anti-dependence breaking requires
|
||||
/// only a single pass
|
||||
unsigned GetMaxTrials() { return 1; }
|
||||
|
||||
/// NeedCandidates - Candidates not needed.
|
||||
bool NeedCandidates() { return false; }
|
||||
|
||||
/// Start - Initialize anti-dep breaking for a new basic block.
|
||||
void StartBlock(MachineBasicBlock *BB);
|
||||
|
||||
@ -78,7 +72,6 @@ namespace llvm {
|
||||
/// of the ScheduleDAG and break them by renaming registers.
|
||||
///
|
||||
unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits,
|
||||
CandidateMap& Candidates,
|
||||
MachineBasicBlock::iterator& Begin,
|
||||
MachineBasicBlock::iterator& End,
|
||||
unsigned InsertPosIndex);
|
||||
|
@ -332,7 +332,7 @@ bool DwarfEHPrepare::PromoteStackTemporaries() {
|
||||
if (ExceptionValueVar && DT && DF && isAllocaPromotable(ExceptionValueVar)) {
|
||||
// Turn the exception temporary into registers and phi nodes if possible.
|
||||
std::vector<AllocaInst*> Allocas(1, ExceptionValueVar);
|
||||
PromoteMemToReg(Allocas, *DT, *DF, ExceptionValueVar->getContext());
|
||||
PromoteMemToReg(Allocas, *DT, *DF);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -608,7 +608,7 @@ void IfConverter::ScanInstructions(BBInfo &BBI) {
|
||||
if (TII->DefinesPredicate(I, PredDefs))
|
||||
BBI.ClobbersPred = true;
|
||||
|
||||
if (!TID.isPredicable()) {
|
||||
if (!TII->isPredicable(I)) {
|
||||
BBI.IsUnpredicable = true;
|
||||
return;
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden,
|
||||
cl::desc("Disable Post Regalloc"));
|
||||
static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
|
||||
cl::desc("Disable branch folding"));
|
||||
static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
|
||||
cl::desc("Disable tail duplication"));
|
||||
static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden,
|
||||
cl::desc("Disable code placement"));
|
||||
static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
|
||||
@ -66,6 +68,11 @@ static cl::opt<cl::boolOrDefault>
|
||||
EnableFastISelOption("fast-isel", cl::Hidden,
|
||||
cl::desc("Enable the \"fast\" instruction selector"));
|
||||
|
||||
// Enable or disable an experimental optimization to split GEPs
|
||||
// and run a special GVN pass which does not examine loads, in
|
||||
// an effort to factor out redundancy implicit in complex GEPs.
|
||||
static cl::opt<bool> EnableSplitGEPGVN("split-gep-gvn", cl::Hidden,
|
||||
cl::desc("Split GEPs and run no-load GVN"));
|
||||
|
||||
LLVMTargetMachine::LLVMTargetMachine(const Target &T,
|
||||
const std::string &TargetTriple)
|
||||
@ -223,6 +230,12 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
// Standard LLVM-Level Passes.
|
||||
|
||||
// Optionally, tun split-GEPs and no-load GVN.
|
||||
if (EnableSplitGEPGVN) {
|
||||
PM.add(createGEPSplitterPass());
|
||||
PM.add(createGVNPass(/*NoPRE=*/false, /*NoLoads=*/true));
|
||||
}
|
||||
|
||||
// Run loop strength reduction before anything else.
|
||||
if (OptLevel != CodeGenOpt::None && !DisableLSR) {
|
||||
PM.add(createLoopStrengthReducePass(getTargetLowering()));
|
||||
@ -333,15 +346,17 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
|
||||
printAndVerify(PM, "After BranchFolding");
|
||||
}
|
||||
|
||||
// Tail duplication.
|
||||
if (OptLevel != CodeGenOpt::None && !DisableTailDuplicate) {
|
||||
PM.add(createTailDuplicatePass());
|
||||
printAndVerify(PM, "After TailDuplicate");
|
||||
}
|
||||
|
||||
PM.add(createGCMachineCodeAnalysisPass());
|
||||
|
||||
if (PrintGCInfo)
|
||||
PM.add(createGCInfoPrinter(errs()));
|
||||
|
||||
// Fold redundant debug labels.
|
||||
PM.add(createDebugLabelFoldingPass());
|
||||
printAndVerify(PM, "After DebugLabelFolding");
|
||||
|
||||
if (OptLevel != CodeGenOpt::None && !DisableCodePlace) {
|
||||
PM.add(createCodePlacementOptPass());
|
||||
printAndVerify(PM, "After CodePlacementOpt");
|
||||
|
@ -55,10 +55,6 @@ SUnit *LatencyPriorityQueue::getSingleUnscheduledPred(SUnit *SU) {
|
||||
SUnit *OnlyAvailablePred = 0;
|
||||
for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
|
||||
I != E; ++I) {
|
||||
if (IgnoreAntiDep &&
|
||||
((I->getKind() == SDep::Anti) || (I->getKind() == SDep::Output)))
|
||||
continue;
|
||||
|
||||
SUnit &Pred = *I->getSUnit();
|
||||
if (!Pred.isScheduled) {
|
||||
// We found an available, but not scheduled, predecessor. If it's the
|
||||
@ -78,10 +74,6 @@ void LatencyPriorityQueue::push_impl(SUnit *SU) {
|
||||
unsigned NumNodesBlocking = 0;
|
||||
for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
|
||||
I != E; ++I) {
|
||||
if (IgnoreAntiDep &&
|
||||
((I->getKind() == SDep::Anti) || (I->getKind() == SDep::Output)))
|
||||
continue;
|
||||
|
||||
if (getSingleUnscheduledPred(I->getSUnit()) == SU)
|
||||
++NumNodesBlocking;
|
||||
}
|
||||
@ -98,10 +90,6 @@ void LatencyPriorityQueue::push_impl(SUnit *SU) {
|
||||
void LatencyPriorityQueue::ScheduledNode(SUnit *SU) {
|
||||
for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
|
||||
I != E; ++I) {
|
||||
if (IgnoreAntiDep &&
|
||||
((I->getKind() == SDep::Anti) || (I->getKind() == SDep::Output)))
|
||||
continue;
|
||||
|
||||
AdjustPriorityOfUnscheduledPreds(I->getSUnit());
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +136,8 @@ void LiveIntervals::printInstrs(raw_ostream &OS) const {
|
||||
|
||||
for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
|
||||
mbbi != mbbe; ++mbbi) {
|
||||
OS << ((Value*)mbbi->getBasicBlock())->getName() << ":\n";
|
||||
OS << "BB#" << mbbi->getNumber()
|
||||
<< ":\t\t# derived from " << mbbi->getName() << "\n";
|
||||
for (MachineBasicBlock::iterator mii = mbbi->begin(),
|
||||
mie = mbbi->end(); mii != mie; ++mii) {
|
||||
OS << getInstructionIndex(mii) << '\t' << *mii;
|
||||
@ -658,7 +659,7 @@ void LiveIntervals::computeIntervals() {
|
||||
MachineBasicBlock *MBB = MBBI;
|
||||
// Track the index of the current machine instr.
|
||||
SlotIndex MIIndex = getMBBStartIdx(MBB);
|
||||
DEBUG(errs() << ((Value*)MBB->getBasicBlock())->getName() << ":\n");
|
||||
DEBUG(errs() << MBB->getName() << ":\n");
|
||||
|
||||
MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end();
|
||||
|
||||
@ -1094,6 +1095,12 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
|
||||
NewVReg = mri_->createVirtualRegister(rc);
|
||||
vrm.grow();
|
||||
CreatedNewVReg = true;
|
||||
|
||||
// The new virtual register should get the same allocation hints as the
|
||||
// old one.
|
||||
std::pair<unsigned, unsigned> Hint = mri_->getRegAllocationHint(Reg);
|
||||
if (Hint.first || Hint.second)
|
||||
mri_->setRegAllocationHint(NewVReg, Hint.first, Hint.second);
|
||||
}
|
||||
|
||||
if (!TryFold)
|
||||
|
@ -279,6 +279,43 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
|
||||
PhysRegUse[SubReg] = MI;
|
||||
}
|
||||
|
||||
/// FindLastRefOrPartRef - Return the last reference or partial reference of
|
||||
/// the specified register.
|
||||
MachineInstr *LiveVariables::FindLastRefOrPartRef(unsigned Reg) {
|
||||
MachineInstr *LastDef = PhysRegDef[Reg];
|
||||
MachineInstr *LastUse = PhysRegUse[Reg];
|
||||
if (!LastDef && !LastUse)
|
||||
return false;
|
||||
|
||||
MachineInstr *LastRefOrPartRef = LastUse ? LastUse : LastDef;
|
||||
unsigned LastRefOrPartRefDist = DistanceMap[LastRefOrPartRef];
|
||||
MachineInstr *LastPartDef = 0;
|
||||
unsigned LastPartDefDist = 0;
|
||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||
unsigned SubReg = *SubRegs; ++SubRegs) {
|
||||
MachineInstr *Def = PhysRegDef[SubReg];
|
||||
if (Def && Def != LastDef) {
|
||||
// There was a def of this sub-register in between. This is a partial
|
||||
// def, keep track of the last one.
|
||||
unsigned Dist = DistanceMap[Def];
|
||||
if (Dist > LastPartDefDist) {
|
||||
LastPartDefDist = Dist;
|
||||
LastPartDef = Def;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (MachineInstr *Use = PhysRegUse[SubReg]) {
|
||||
unsigned Dist = DistanceMap[Use];
|
||||
if (Dist > LastRefOrPartRefDist) {
|
||||
LastRefOrPartRefDist = Dist;
|
||||
LastRefOrPartRef = Use;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LastRefOrPartRef;
|
||||
}
|
||||
|
||||
bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
|
||||
MachineInstr *LastDef = PhysRegDef[Reg];
|
||||
MachineInstr *LastUse = PhysRegUse[Reg];
|
||||
@ -373,7 +410,16 @@ bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
|
||||
if (NeedDef)
|
||||
PhysRegDef[Reg]->addOperand(MachineOperand::CreateReg(SubReg,
|
||||
true/*IsDef*/, true/*IsImp*/));
|
||||
LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true);
|
||||
MachineInstr *LastSubRef = FindLastRefOrPartRef(SubReg);
|
||||
if (LastSubRef)
|
||||
LastSubRef->addRegisterKilled(SubReg, TRI, true);
|
||||
else {
|
||||
LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true);
|
||||
PhysRegUse[SubReg] = LastRefOrPartRef;
|
||||
for (const unsigned *SSRegs = TRI->getSubRegisters(SubReg);
|
||||
unsigned SSReg = *SSRegs; ++SSRegs)
|
||||
PhysRegUse[SSReg] = LastRefOrPartRef;
|
||||
}
|
||||
for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
|
||||
PartUses.erase(*SS);
|
||||
}
|
||||
@ -656,35 +702,45 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
|
||||
.push_back(BBI->getOperand(i).getReg());
|
||||
}
|
||||
|
||||
bool LiveVariables::VarInfo::isLiveIn(const MachineBasicBlock &MBB,
|
||||
unsigned Reg,
|
||||
MachineRegisterInfo &MRI) {
|
||||
unsigned Num = MBB.getNumber();
|
||||
|
||||
// Reg is live-through.
|
||||
if (AliveBlocks.test(Num))
|
||||
return true;
|
||||
|
||||
// Registers defined in MBB cannot be live in.
|
||||
const MachineInstr *Def = MRI.getVRegDef(Reg);
|
||||
if (Def && Def->getParent() == &MBB)
|
||||
return false;
|
||||
|
||||
// Reg was not defined in MBB, was it killed here?
|
||||
return findKill(&MBB);
|
||||
}
|
||||
|
||||
/// addNewBlock - Add a new basic block BB as an empty succcessor to DomBB. All
|
||||
/// variables that are live out of DomBB will be marked as passing live through
|
||||
/// BB.
|
||||
void LiveVariables::addNewBlock(MachineBasicBlock *BB,
|
||||
MachineBasicBlock *DomBB) {
|
||||
MachineBasicBlock *DomBB,
|
||||
MachineBasicBlock *SuccBB) {
|
||||
const unsigned NumNew = BB->getNumber();
|
||||
const unsigned NumDom = DomBB->getNumber();
|
||||
|
||||
// All registers used by PHI nodes in SuccBB must be live through BB.
|
||||
for (MachineBasicBlock::const_iterator BBI = SuccBB->begin(),
|
||||
BBE = SuccBB->end();
|
||||
BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
|
||||
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
|
||||
if (BBI->getOperand(i+1).getMBB() == BB)
|
||||
getVarInfo(BBI->getOperand(i).getReg()).AliveBlocks.set(NumNew);
|
||||
|
||||
// Update info for all live variables
|
||||
for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
|
||||
E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) {
|
||||
VarInfo &VI = getVarInfo(Reg);
|
||||
|
||||
// Anything live through DomBB is also live through BB.
|
||||
if (VI.AliveBlocks.test(NumDom)) {
|
||||
if (!VI.AliveBlocks.test(NumNew) && VI.isLiveIn(*SuccBB, Reg, *MRI))
|
||||
VI.AliveBlocks.set(NumNew);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Variables not defined in DomBB cannot be live out.
|
||||
const MachineInstr *Def = MRI->getVRegDef(Reg);
|
||||
if (!Def || Def->getParent() != DomBB)
|
||||
continue;
|
||||
|
||||
// Killed by DomBB?
|
||||
if (VI.findKill(DomBB))
|
||||
continue;
|
||||
|
||||
// This register is defined in DomBB and live out
|
||||
VI.AliveBlocks.set(NumNew);
|
||||
}
|
||||
}
|
||||
|
@ -172,6 +172,13 @@ static inline void OutputReg(raw_ostream &os, unsigned RegNo,
|
||||
os << " %reg" << RegNo;
|
||||
}
|
||||
|
||||
StringRef MachineBasicBlock::getName() const {
|
||||
if (const BasicBlock *LBB = getBasicBlock())
|
||||
return LBB->getName();
|
||||
else
|
||||
return "(null)";
|
||||
}
|
||||
|
||||
void MachineBasicBlock::print(raw_ostream &OS) const {
|
||||
const MachineFunction *MF = getParent();
|
||||
if (!MF) {
|
||||
@ -272,8 +279,9 @@ void MachineBasicBlock::updateTerminator() {
|
||||
// successors is its layout successor, rewrite it to a fallthrough
|
||||
// conditional branch.
|
||||
if (isLayoutSuccessor(TBB)) {
|
||||
if (TII->ReverseBranchCondition(Cond))
|
||||
return;
|
||||
TII->RemoveBranch(*this);
|
||||
TII->ReverseBranchCondition(Cond);
|
||||
TII->InsertBranch(*this, FBB, 0, Cond);
|
||||
} else if (isLayoutSuccessor(FBB)) {
|
||||
TII->RemoveBranch(*this);
|
||||
@ -285,8 +293,13 @@ void MachineBasicBlock::updateTerminator() {
|
||||
MachineBasicBlock *MBBB = *next(succ_begin());
|
||||
if (MBBA == TBB) std::swap(MBBB, MBBA);
|
||||
if (isLayoutSuccessor(TBB)) {
|
||||
if (TII->ReverseBranchCondition(Cond)) {
|
||||
// We can't reverse the condition, add an unconditional branch.
|
||||
Cond.clear();
|
||||
TII->InsertBranch(*this, MBBA, 0, Cond);
|
||||
return;
|
||||
}
|
||||
TII->RemoveBranch(*this);
|
||||
TII->ReverseBranchCondition(Cond);
|
||||
TII->InsertBranch(*this, MBBA, 0, Cond);
|
||||
} else if (!isLayoutSuccessor(MBBA)) {
|
||||
TII->RemoveBranch(*this);
|
||||
@ -349,6 +362,51 @@ bool MachineBasicBlock::isLayoutSuccessor(const MachineBasicBlock *MBB) const {
|
||||
return next(I) == MachineFunction::const_iterator(MBB);
|
||||
}
|
||||
|
||||
bool MachineBasicBlock::canFallThrough() {
|
||||
MachineBasicBlock *TBB = 0, *FBB = 0;
|
||||
SmallVector<MachineOperand, 4> Cond;
|
||||
const TargetInstrInfo *TII = getParent()->getTarget().getInstrInfo();
|
||||
bool BranchUnAnalyzable = TII->AnalyzeBranch(*this, TBB, FBB, Cond, true);
|
||||
|
||||
MachineFunction::iterator Fallthrough = this;
|
||||
++Fallthrough;
|
||||
// If FallthroughBlock is off the end of the function, it can't fall through.
|
||||
if (Fallthrough == getParent()->end())
|
||||
return false;
|
||||
|
||||
// If FallthroughBlock isn't a successor, no fallthrough is possible.
|
||||
if (!isSuccessor(Fallthrough))
|
||||
return false;
|
||||
|
||||
// If we couldn't analyze the branch, examine the last instruction.
|
||||
// If the block doesn't end in a known control barrier, assume fallthrough
|
||||
// is possible. The isPredicable check is needed because this code can be
|
||||
// called during IfConversion, where an instruction which is normally a
|
||||
// Barrier is predicated and thus no longer an actual control barrier. This
|
||||
// is over-conservative though, because if an instruction isn't actually
|
||||
// predicated we could still treat it like a barrier.
|
||||
if (BranchUnAnalyzable)
|
||||
return empty() || !back().getDesc().isBarrier() ||
|
||||
back().getDesc().isPredicable();
|
||||
|
||||
// If there is no branch, control always falls through.
|
||||
if (TBB == 0) return true;
|
||||
|
||||
// If there is some explicit branch to the fallthrough block, it can obviously
|
||||
// reach, even though the branch should get folded to fall through implicitly.
|
||||
if (MachineFunction::iterator(TBB) == Fallthrough ||
|
||||
MachineFunction::iterator(FBB) == Fallthrough)
|
||||
return true;
|
||||
|
||||
// If it's an unconditional branch to some block not the fall through, it
|
||||
// doesn't fall through.
|
||||
if (Cond.empty()) return false;
|
||||
|
||||
// Otherwise, if it is conditional and has no explicit false block, it falls
|
||||
// through.
|
||||
return FBB == 0;
|
||||
}
|
||||
|
||||
/// removeFromParent - This method unlinks 'this' from the containing function,
|
||||
/// and returns it, but does not delete it.
|
||||
MachineBasicBlock *MachineBasicBlock::removeFromParent() {
|
||||
|
@ -359,14 +359,16 @@ void MachineFunction::print(raw_ostream &OS) const {
|
||||
namespace llvm {
|
||||
template<>
|
||||
struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
|
||||
|
||||
DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
|
||||
|
||||
static std::string getGraphName(const MachineFunction *F) {
|
||||
return "CFG for '" + F->getFunction()->getNameStr() + "' function";
|
||||
}
|
||||
|
||||
static std::string getNodeLabel(const MachineBasicBlock *Node,
|
||||
const MachineFunction *Graph,
|
||||
bool ShortNames) {
|
||||
if (ShortNames && Node->getBasicBlock() &&
|
||||
std::string getNodeLabel(const MachineBasicBlock *Node,
|
||||
const MachineFunction *Graph) {
|
||||
if (isSimple () && Node->getBasicBlock() &&
|
||||
!Node->getBasicBlock()->getName().empty())
|
||||
return Node->getBasicBlock()->getNameStr() + ":";
|
||||
|
||||
@ -374,7 +376,7 @@ namespace llvm {
|
||||
{
|
||||
raw_string_ostream OSS(OutStr);
|
||||
|
||||
if (ShortNames)
|
||||
if (isSimple())
|
||||
OSS << Node->getNumber() << ':';
|
||||
else
|
||||
Node->print(OSS);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user