Update LLVM to r86025.
This commit is contained in:
parent
f9666f9b3a
commit
36bf506ad3
@ -319,16 +319,26 @@ if(LLVM_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif ()
|
||||
|
||||
install(DIRECTORY include
|
||||
DESTINATION .
|
||||
install(DIRECTORY include/
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*.def"
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.td"
|
||||
PATTERN "*.inc"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
PATTERN "*.cmake" EXCLUDE
|
||||
PATTERN "*.in" EXCLUDE
|
||||
PATTERN "*.tmp" EXCLUDE
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
DESTINATION .
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*.def"
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.gen"
|
||||
PATTERN "*.inc"
|
||||
# Exclude include/llvm/CMakeFiles/intrinsics_gen.dir, matched by "*.def"
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
# TODO: make and install documentation.
|
||||
|
10
Makefile
10
Makefile
@ -24,7 +24,8 @@ LEVEL := .
|
||||
# "llvmCore", then this is an "Apple-style" build; search for
|
||||
# "Apple-style" in the comments for more info. Anything else is a
|
||||
# normal build.
|
||||
ifneq ($(RC_ProjectName),llvmCore) # Normal build (not "Apple-style").
|
||||
ifneq ($(findstring llvmCore, $(RC_ProjectName)),llvmCore) # Normal build (not "Apple-style").
|
||||
|
||||
ifeq ($(BUILD_DIRS_ONLY),1)
|
||||
DIRS := lib/System lib/Support utils
|
||||
OPTIONAL_DIRS :=
|
||||
@ -94,6 +95,8 @@ cross-compile-build-tools:
|
||||
$(Verb) if [ ! -f BuildTools/Makefile ]; then \
|
||||
$(MKDIR) BuildTools; \
|
||||
cd BuildTools ; \
|
||||
unset CFLAGS ; \
|
||||
unset CXXFLAGS ; \
|
||||
$(PROJ_SRC_DIR)/configure --build=$(BUILD_TRIPLE) \
|
||||
--host=$(BUILD_TRIPLE) --target=$(BUILD_TRIPLE); \
|
||||
cd .. ; \
|
||||
@ -133,8 +136,7 @@ dist-hook::
|
||||
$(Echo) Eliminating files constructed by configure
|
||||
$(Verb) $(RM) -f \
|
||||
$(TopDistDir)/include/llvm/Config/config.h \
|
||||
$(TopDistDir)/include/llvm/Support/DataTypes.h \
|
||||
$(TopDistDir)/include/llvm/Support/ThreadSupport.h
|
||||
$(TopDistDir)/include/llvm/System/DataTypes.h
|
||||
|
||||
clang-only: all
|
||||
tools-only: all
|
||||
@ -150,7 +152,7 @@ FilesToConfig := \
|
||||
include/llvm/Config/config.h \
|
||||
include/llvm/Config/Targets.def \
|
||||
include/llvm/Config/AsmPrinters.def \
|
||||
include/llvm/Support/DataTypes.h \
|
||||
include/llvm/System/DataTypes.h \
|
||||
tools/llvmc/plugins/Base/Base.td
|
||||
FilesToConfigPATH := $(addprefix $(LLVM_OBJ_ROOT)/,$(FilesToConfig))
|
||||
|
||||
|
@ -250,6 +250,9 @@ RDYNAMIC := @RDYNAMIC@
|
||||
#DEBUG_SYMBOLS = 1
|
||||
@DEBUG_SYMBOLS@
|
||||
|
||||
# The compiler flags to use for optimized builds.
|
||||
OPTIMIZE_OPTION := @OPTIMIZE_OPTION@
|
||||
|
||||
# When ENABLE_PROFILING is enabled, the llvm source base is built with profile
|
||||
# information to allow gprof to be used to get execution frequencies.
|
||||
#ENABLE_PROFILING = 1
|
||||
@ -320,3 +323,9 @@ ENABLE_LLVMC_DYNAMIC = 0
|
||||
# support (via the -load option).
|
||||
ENABLE_LLVMC_DYNAMIC_PLUGINS = 1
|
||||
#@ENABLE_LLVMC_DYNAMIC_PLUGINS@
|
||||
|
||||
# Optional flags supported by the compiler
|
||||
# -Wno-missing-field-initializers
|
||||
NO_MISSING_FIELD_INITIALIZERS = @NO_MISSING_FIELD_INITIALIZERS@
|
||||
# -Wno-variadic-macros
|
||||
NO_VARIADIC_MACROS = @NO_VARIADIC_MACROS@
|
||||
|
@ -312,16 +312,6 @@ endif
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
CPP.Defines :=
|
||||
# OPTIMIZE_OPTION - The optimization level option we want to build LLVM with
|
||||
# this can be overridden on the make command line.
|
||||
ifndef OPTIMIZE_OPTION
|
||||
ifneq ($(HOST_OS),MingW)
|
||||
OPTIMIZE_OPTION := -O3
|
||||
else
|
||||
OPTIMIZE_OPTION := -O2
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_OPTIMIZED),1)
|
||||
BuildMode := Release
|
||||
# Don't use -fomit-frame-pointer on Darwin or FreeBSD.
|
||||
@ -566,6 +556,8 @@ endif
|
||||
ifeq ($(TARGET_OS),Darwin)
|
||||
ifneq ($(ARCH),ARM)
|
||||
TargetCommonOpts += -mmacosx-version-min=$(DARWIN_VERSION)
|
||||
else
|
||||
TargetCommonOpts += -marm
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1238,7 +1230,7 @@ endif
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux NetBSD FreeBSD))
|
||||
LD.Flags += -Wl,--version-script=$(LLVM_SRC_ROOT)/autoconf/ExportMap.map
|
||||
LD.Flags += -Wl,--version-script=$(LLVM_SRC_ROOT)/autoconf/ExportMap.map
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -607,6 +607,23 @@ if test -n "$LLVMGXX" && test -z "$LLVMGCC"; then
|
||||
AC_MSG_ERROR([Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used]);
|
||||
fi
|
||||
|
||||
dnl Override the option to use for optimized builds.
|
||||
AC_ARG_WITH(optimize-option,
|
||||
AS_HELP_STRING([--with-optimize-option],
|
||||
[Select the compiler options to use for optimized builds]),,
|
||||
withval=default)
|
||||
AC_MSG_CHECKING([optimization flags])
|
||||
case "$withval" in
|
||||
default)
|
||||
case "$llvm_cv_os_type" in
|
||||
MingW) optimize_option=-O3 ;;
|
||||
*) optimize_option=-O2 ;;
|
||||
esac ;;
|
||||
*) optimize_option="$withval" ;;
|
||||
esac
|
||||
AC_SUBST(OPTIMIZE_OPTION,$optimize_option)
|
||||
AC_MSG_RESULT([$optimize_option])
|
||||
|
||||
dnl Specify extra build options
|
||||
AC_ARG_WITH(extra-options,
|
||||
AS_HELP_STRING([--with-extra-options],
|
||||
@ -943,6 +960,12 @@ fi
|
||||
dnl Tool compatibility is okay if we make it here.
|
||||
AC_MSG_RESULT([ok])
|
||||
|
||||
dnl Check optional compiler flags.
|
||||
AC_MSG_CHECKING([optional compiler flags])
|
||||
CXX_FLAG_CHECK(NO_VARIADIC_MACROS, [-Wno-variadic-macros])
|
||||
CXX_FLAG_CHECK(NO_MISSING_FIELD_INITIALIZERS, [-Wno-missing-field-initializers])
|
||||
AC_MSG_RESULT([$NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS])
|
||||
|
||||
dnl===-----------------------------------------------------------------------===
|
||||
dnl===
|
||||
dnl=== SECTION 5: Check for libraries
|
||||
@ -1349,7 +1372,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_HEADERS([include/llvm/Support/DataTypes.h])
|
||||
AC_CONFIG_HEADERS([include/llvm/System/DataTypes.h])
|
||||
|
||||
dnl Configure the makefile's configuration data
|
||||
AC_CONFIG_FILES([Makefile.config])
|
||||
|
@ -83,9 +83,9 @@ check_symbol_exists(floorf math.h HAVE_FLOORF)
|
||||
check_symbol_exists(mallinfo malloc.h HAVE_MALLINFO)
|
||||
check_symbol_exists(malloc_zone_statistics malloc/malloc.h
|
||||
HAVE_MALLOC_ZONE_STATISTICS)
|
||||
check_symbol_exists(mkdtemp unistd.h HAVE_MKDTEMP)
|
||||
check_symbol_exists(mkstemp unistd.h HAVE_MKSTEMP)
|
||||
check_symbol_exists(mktemp unistd.h HAVE_MKTEMP)
|
||||
check_symbol_exists(mkdtemp "stdlib.h;unistd.h" HAVE_MKDTEMP)
|
||||
check_symbol_exists(mkstemp "stdlib.h;unistd.h" HAVE_MKSTEMP)
|
||||
check_symbol_exists(mktemp "stdlib.h;unistd.h" HAVE_MKTEMP)
|
||||
check_symbol_exists(pthread_mutex_lock pthread.h HAVE_PTHREAD_MUTEX_LOCK)
|
||||
check_symbol_exists(sbrk unistd.h HAVE_SBRK)
|
||||
check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL)
|
||||
@ -229,7 +229,7 @@ configure_file(
|
||||
)
|
||||
|
||||
configure_file(
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/Support/DataTypes.h.cmake
|
||||
${LLVM_BINARY_DIR}/include/llvm/Support/DataTypes.h
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/System/DataTypes.h.cmake
|
||||
${LLVM_BINARY_DIR}/include/llvm/System/DataTypes.h
|
||||
)
|
||||
|
||||
|
@ -23,7 +23,6 @@ set(MSVC_LIB_DEPS_LLVMCodeGen LLVMAnalysis LLVMCore LLVMMC LLVMScalarOpts LLVMSu
|
||||
set(MSVC_LIB_DEPS_LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMDebugger LLVMAnalysis LLVMBitReader LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMHello LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMScalarOpts LLVMSupport LLVMSystem LLVMTransformUtils)
|
||||
|
@ -22,6 +22,7 @@ endmacro(add_header_files)
|
||||
|
||||
function(llvm_process_sources OUT_VAR)
|
||||
set( sources ${ARGN} )
|
||||
llvm_check_source_file_list( ${sources} )
|
||||
# Create file dependencies on the tablegenned files, if any. Seems
|
||||
# that this is not strictly needed, as dependencies of the .cpp
|
||||
# sources on the tablegenned .inc files are detected and handled,
|
||||
@ -37,3 +38,17 @@ function(llvm_process_sources OUT_VAR)
|
||||
endif()
|
||||
set( ${OUT_VAR} ${sources} PARENT_SCOPE )
|
||||
endfunction(llvm_process_sources)
|
||||
|
||||
|
||||
function(llvm_check_source_file_list)
|
||||
set(listed ${ARGN})
|
||||
file(GLOB globbed *.cpp)
|
||||
foreach(g ${globbed})
|
||||
get_filename_component(fn ${g} NAME)
|
||||
list(FIND listed ${fn} idx)
|
||||
if( idx LESS 0 )
|
||||
message(SEND_ERROR "Found unknown source file ${g}
|
||||
Please update ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt\n")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction(llvm_check_source_file_list)
|
||||
|
96
configure
vendored
96
configure
vendored
@ -848,6 +848,7 @@ LLVM_ENUM_TARGETS
|
||||
LLVM_ENUM_ASM_PRINTERS
|
||||
LLVM_ENUM_ASM_PARSERS
|
||||
ENABLE_CBE_PRINTF_A
|
||||
OPTIMIZE_OPTION
|
||||
EXTRA_OPTIONS
|
||||
BINUTILS_INCDIR
|
||||
ENABLE_LLVMC_DYNAMIC
|
||||
@ -913,6 +914,8 @@ LLVMGCCCOMMAND
|
||||
LLVMGXXCOMMAND
|
||||
LLVMGCC
|
||||
LLVMGXX
|
||||
NO_VARIADIC_MACROS
|
||||
NO_MISSING_FIELD_INITIALIZERS
|
||||
USE_UDIS86
|
||||
USE_OPROFILE
|
||||
HAVE_PTHREAD
|
||||
@ -1595,6 +1598,8 @@ Optional Packages:
|
||||
searches PATH)
|
||||
--with-llvmgxx Specify location of llvm-g++ driver (default
|
||||
searches PATH)
|
||||
--with-optimize-option Select the compiler options to use for optimized
|
||||
builds
|
||||
--with-extra-options Specify additional options to compile LLVM with
|
||||
--with-ocaml-libdir Specify install location for ocaml bindings (default
|
||||
is stdlib)
|
||||
@ -5190,6 +5195,29 @@ echo "$as_me: error: Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --with-optimize-option was given.
|
||||
if test "${with_optimize_option+set}" = set; then
|
||||
withval=$with_optimize_option;
|
||||
else
|
||||
withval=default
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking optimization flags" >&5
|
||||
echo $ECHO_N "checking optimization flags... $ECHO_C" >&6; }
|
||||
case "$withval" in
|
||||
default)
|
||||
case "$llvm_cv_os_type" in
|
||||
MingW) optimize_option=-O3 ;;
|
||||
*) optimize_option=-O2 ;;
|
||||
esac ;;
|
||||
*) optimize_option="$withval" ;;
|
||||
esac
|
||||
OPTIMIZE_OPTION=$optimize_option
|
||||
|
||||
{ echo "$as_me:$LINENO: result: $optimize_option" >&5
|
||||
echo "${ECHO_T}$optimize_option" >&6; }
|
||||
|
||||
|
||||
# Check whether --with-extra-options was given.
|
||||
if test "${with_extra_options+set}" = set; then
|
||||
withval=$with_extra_options;
|
||||
@ -11008,7 +11036,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 11011 "configure"
|
||||
#line 11039 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -13152,7 +13180,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 13155 "configure"' > conftest.$ac_ext
|
||||
echo '#line 13183 "configure"' > conftest.$ac_ext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@ -14870,11 +14898,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:14873: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:14901: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:14877: \$? = $ac_status" >&5
|
||||
echo "$as_me:14905: \$? = $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.
|
||||
@ -15138,11 +15166,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:15141: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15169: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15145: \$? = $ac_status" >&5
|
||||
echo "$as_me:15173: \$? = $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.
|
||||
@ -15242,11 +15270,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:15245: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15273: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:15249: \$? = $ac_status" >&5
|
||||
echo "$as_me:15277: \$? = $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
|
||||
@ -17694,7 +17722,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17697 "configure"
|
||||
#line 17725 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -17794,7 +17822,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17797 "configure"
|
||||
#line 17825 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -20162,11 +20190,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:20165: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:20193: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:20169: \$? = $ac_status" >&5
|
||||
echo "$as_me:20197: \$? = $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.
|
||||
@ -20266,11 +20294,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:20269: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:20297: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:20273: \$? = $ac_status" >&5
|
||||
echo "$as_me:20301: \$? = $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
|
||||
@ -21836,11 +21864,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:21839: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:21867: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:21843: \$? = $ac_status" >&5
|
||||
echo "$as_me:21871: \$? = $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.
|
||||
@ -21940,11 +21968,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:21943: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:21971: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:21947: \$? = $ac_status" >&5
|
||||
echo "$as_me:21975: \$? = $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
|
||||
@ -24175,11 +24203,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:24178: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:24206: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:24182: \$? = $ac_status" >&5
|
||||
echo "$as_me:24210: \$? = $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.
|
||||
@ -24443,11 +24471,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:24446: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:24474: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:24450: \$? = $ac_status" >&5
|
||||
echo "$as_me:24478: \$? = $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.
|
||||
@ -24547,11 +24575,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:24550: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:24578: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:24554: \$? = $ac_status" >&5
|
||||
echo "$as_me:24582: \$? = $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
|
||||
@ -27459,6 +27487,15 @@ fi
|
||||
{ echo "$as_me:$LINENO: result: ok" >&5
|
||||
echo "${ECHO_T}ok" >&6; }
|
||||
|
||||
{ echo "$as_me:$LINENO: checking optional compiler flags" >&5
|
||||
echo $ECHO_N "checking optional compiler flags... $ECHO_C" >&6; }
|
||||
NO_VARIADIC_MACROS=`$CXX -Wno-variadic-macros -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-variadic-macros`
|
||||
|
||||
NO_MISSING_FIELD_INITIALIZERS=`$CXX -Wno-missing-field-initializers -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-missing-field-initializers`
|
||||
|
||||
{ echo "$as_me:$LINENO: result: $NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS" >&5
|
||||
echo "${ECHO_T}$NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS" >&6; }
|
||||
|
||||
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for sin in -lm" >&5
|
||||
@ -35260,7 +35297,7 @@ ac_config_files="$ac_config_files include/llvm/Config/AsmPrinters.def"
|
||||
|
||||
ac_config_files="$ac_config_files include/llvm/Config/AsmParsers.def"
|
||||
|
||||
ac_config_headers="$ac_config_headers include/llvm/Support/DataTypes.h"
|
||||
ac_config_headers="$ac_config_headers include/llvm/System/DataTypes.h"
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile.config"
|
||||
@ -35887,7 +35924,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/Support/DataTypes.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/Support/DataTypes.h" ;;
|
||||
"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" ;;
|
||||
"docs/doxygen.cfg") CONFIG_FILES="$CONFIG_FILES docs/doxygen.cfg" ;;
|
||||
@ -36061,11 +36098,11 @@ 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
|
||||
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
|
||||
CXX!$CXX$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
|
||||
@ -36107,6 +36144,7 @@ _ACEOF
|
||||
ac_delim='%!_!# '
|
||||
for ac_last_try in false false false false false :; do
|
||||
cat >conf$$subs.sed <<_ACEOF
|
||||
CXX!$CXX$ac_delim
|
||||
CXXFLAGS!$CXXFLAGS$ac_delim
|
||||
ac_ct_CXX!$ac_ct_CXX$ac_delim
|
||||
NM!$NM$ac_delim
|
||||
@ -36167,6 +36205,8 @@ LLVMGCCCOMMAND!$LLVMGCCCOMMAND$ac_delim
|
||||
LLVMGXXCOMMAND!$LLVMGXXCOMMAND$ac_delim
|
||||
LLVMGCC!$LLVMGCC$ac_delim
|
||||
LLVMGXX!$LLVMGXX$ac_delim
|
||||
NO_VARIADIC_MACROS!$NO_VARIADIC_MACROS$ac_delim
|
||||
NO_MISSING_FIELD_INITIALIZERS!$NO_MISSING_FIELD_INITIALIZERS$ac_delim
|
||||
USE_UDIS86!$USE_UDIS86$ac_delim
|
||||
USE_OPROFILE!$USE_OPROFILE$ac_delim
|
||||
HAVE_PTHREAD!$HAVE_PTHREAD$ac_delim
|
||||
@ -36201,7 +36241,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` = 92; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 95; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
@ -27,6 +27,15 @@
|
||||
<li><a href="#llvmir">LLVM IR Encoding</a>
|
||||
<ol>
|
||||
<li><a href="#basics">Basics</a></li>
|
||||
<li><a href="#MODULE_BLOCK">MODULE_BLOCK Contents</a></li>
|
||||
<li><a href="#PARAMATTR_BLOCK">PARAMATTR_BLOCK Contents</a></li>
|
||||
<li><a href="#TYPE_BLOCK">TYPE_BLOCK Contents</a></li>
|
||||
<li><a href="#CONSTANTS_BLOCK">CONSTANTS_BLOCK Contents</a></li>
|
||||
<li><a href="#FUNCTION_BLOCK">FUNCTION_BLOCK Contents</a></li>
|
||||
<li><a href="#TYPE_SYMTAB_BLOCK">TYPE_SYMTAB_BLOCK Contents</a></li>
|
||||
<li><a href="#VALUE_SYMTAB_BLOCK">VALUE_SYMTAB_BLOCK Contents</a></li>
|
||||
<li><a href="#METADATA_BLOCK">METADATA_BLOCK Contents</a></li>
|
||||
<li><a href="#METADATA_ATTACHMENT">METADATA_ATTACHMENT Contents</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
@ -220,7 +229,7 @@ A bitstream is a sequential series of <a href="#blocks">Blocks</a> and
|
||||
abbreviation ID encoded as a fixed-bitwidth field. The width is specified by
|
||||
the current block, as described below. The value of the abbreviation ID
|
||||
specifies either a builtin ID (which have special meanings, defined below) or
|
||||
one of the abbreviation IDs defined by the stream itself.
|
||||
one of the abbreviation IDs defined for the current block by the stream itself.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -258,7 +267,7 @@ application specific. Nested blocks capture the hierarchical structure of the da
|
||||
encoded in it, and various properties are associated with blocks as the file is
|
||||
parsed. Block definitions allow the reader to efficiently skip blocks
|
||||
in constant time if the reader wants a summary of blocks, or if it wants to
|
||||
efficiently skip data they do not understand. The LLVM IR reader uses this
|
||||
efficiently skip data it does not understand. The LLVM IR reader uses this
|
||||
mechanism to skip function bodies, lazily reading them on demand.
|
||||
</p>
|
||||
|
||||
@ -268,7 +277,8 @@ block. In particular, each block maintains:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>A current abbrev id width. This value starts at 2, and is set every time a
|
||||
<li>A current abbrev id width. This value starts at 2 at the beginning of
|
||||
the stream, and is set every time a
|
||||
block record is entered. The block entry specifies the abbrev id width for
|
||||
the body of the block.</li>
|
||||
|
||||
@ -335,13 +345,14 @@ an even multiple of 32-bits.
|
||||
|
||||
<div class="doc_text">
|
||||
<p>
|
||||
Data records consist of a record code and a number of (up to) 64-bit integer
|
||||
values. The interpretation of the code and values is application specific and
|
||||
there are multiple different ways to encode a record (with an unabbrev record or
|
||||
with an abbreviation). In the LLVM IR format, for example, there is a record
|
||||
Data records consist of a record code and a number of (up to) 64-bit
|
||||
integer values. The interpretation of the code and values is
|
||||
application specific and may vary between different block types.
|
||||
Records can be encoded either using an unabbrev record, or with an
|
||||
abbreviation. In the LLVM IR format, for example, there is a record
|
||||
which encodes the target triple of a module. The code is
|
||||
<tt>MODULE_CODE_TRIPLE</tt>, and the values of the record are the ASCII codes
|
||||
for the characters in the string.
|
||||
<tt>MODULE_CODE_TRIPLE</tt>, and the values of the record are the
|
||||
ASCII codes for the characters in the string.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@ -358,7 +369,7 @@ Encoding</a></div>
|
||||
<p>
|
||||
An <tt>UNABBREV_RECORD</tt> provides a default fallback encoding, which is both
|
||||
completely general and extremely inefficient. It can describe an arbitrary
|
||||
record by emitting the code and operands as vbrs.
|
||||
record by emitting the code and operands as VBRs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -391,6 +402,11 @@ allows the files to be completely self describing. The actual encoding of
|
||||
abbreviations is defined below.
|
||||
</p>
|
||||
|
||||
<p>The record code, which is the first field of an abbreviated record,
|
||||
may be encoded in the abbreviation definition (as a literal
|
||||
operand) or supplied in the abbreviated record (as a Fixed or VBR
|
||||
operand value).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
@ -409,8 +425,9 @@ emitted.
|
||||
<p>
|
||||
Abbreviations can be determined dynamically per client, per file. Because the
|
||||
abbreviations are stored in the bitstream itself, different streams of the same
|
||||
format can contain different sets of abbreviations if the specific stream does
|
||||
not need it. As a concrete example, LLVM IR files usually emit an abbreviation
|
||||
format can contain different sets of abbreviations according to the needs
|
||||
of the specific stream.
|
||||
As a concrete example, LLVM IR files usually emit an abbreviation
|
||||
for binary operators. If a specific LLVM module contained no or few binary
|
||||
operators, the abbreviation does not need to be emitted.
|
||||
</p>
|
||||
@ -431,7 +448,8 @@ defined abbreviations in the scope of this block. This definition only exists
|
||||
inside this immediate block — it is not visible in subblocks or enclosing
|
||||
blocks. Abbreviations are implicitly assigned IDs sequentially starting from 4
|
||||
(the first application-defined abbreviation ID). Any abbreviations defined in a
|
||||
<tt>BLOCKINFO</tt> record receive IDs first, in order, followed by any
|
||||
<tt>BLOCKINFO</tt> record for the particular block type
|
||||
receive IDs first, in order, followed by any
|
||||
abbreviations defined within the block itself. Abbreviated data records
|
||||
reference this ID to indicate what abbreviation they are invoking.
|
||||
</p>
|
||||
@ -461,31 +479,32 @@ emitted as their code, followed by the extra data.
|
||||
|
||||
<p>The possible operand encodings are:</p>
|
||||
|
||||
<ol>
|
||||
<li>Fixed: The field should be emitted as
|
||||
<ul>
|
||||
<li>Fixed (code 1): The field should be emitted as
|
||||
a <a href="#fixedwidth">fixed-width value</a>, whose width is specified by
|
||||
the operand's extra data.</li>
|
||||
<li>VBR: The field should be emitted as
|
||||
<li>VBR (code 2): The field should be emitted as
|
||||
a <a href="#variablewidth">variable-width value</a>, whose width is
|
||||
specified by the operand's extra data.</li>
|
||||
<li>Array: This field is an array of values. The array operand
|
||||
has no extra data, but expects another operand to follow it which indicates
|
||||
<li>Array (code 3): This field is an array of values. The array operand
|
||||
has no extra data, but expects another operand to follow it, indicating
|
||||
the element type of the array. When reading an array in an abbreviated
|
||||
record, the first integer is a vbr6 that indicates the array length,
|
||||
followed by the encoded elements of the array. An array may only occur as
|
||||
the last operand of an abbreviation (except for the one final operand that
|
||||
gives the array's type).</li>
|
||||
<li>Char6: This field should be emitted as
|
||||
<li>Char6 (code 4): This field should be emitted as
|
||||
a <a href="#char6">char6-encoded value</a>. This operand type takes no
|
||||
extra data.</li>
|
||||
<li>Blob: This field is emitted as a vbr6, followed by padding to a
|
||||
extra data. Char6 encoding is normally used as an array element type.
|
||||
</li>
|
||||
<li>Blob (code 5): This field is emitted as a vbr6, followed by padding to a
|
||||
32-bit boundary (for alignment) and an array of 8-bit objects. The array of
|
||||
bytes is further followed by tail padding to ensure that its total length is
|
||||
a multiple of 4 bytes. This makes it very efficient for the reader to
|
||||
decode the data without having to make a copy of it: it can use a pointer to
|
||||
the data in the mapped in file and poke directly at it. A blob may only
|
||||
occur as the last operand of an abbreviation.</li>
|
||||
</ol>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
For example, target triples in LLVM modules are encoded as a record of the
|
||||
@ -517,7 +536,7 @@ as:
|
||||
|
||||
<ol>
|
||||
<li>The first value, 4, is the abbreviation ID for this abbreviation.</li>
|
||||
<li>The second value, 2, is the code for <tt>TRIPLE</tt> in LLVM IR files.</li>
|
||||
<li>The second value, 2, is the record code for <tt>TRIPLE</tt> records within LLVM IR file <tt>MODULE_BLOCK</tt> blocks.</li>
|
||||
<li>The third value, 4, is the length of the array.</li>
|
||||
<li>The rest of the values are the char6 encoded values
|
||||
for <tt>"abcd"</tt>.</li>
|
||||
@ -541,7 +560,7 @@ used for any other string value.
|
||||
|
||||
<p>
|
||||
In addition to the basic block structure and record encodings, the bitstream
|
||||
also defines specific builtin block types. These block types specify how the
|
||||
also defines specific built-in block types. These block types specify how the
|
||||
stream is to be decoded or other metadata. In the future, new standard blocks
|
||||
may be added. Block IDs 0-7 are reserved for standard blocks.
|
||||
</p>
|
||||
@ -569,7 +588,7 @@ blocks. The currently specified records are:
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The <tt>SETBID</tt> record indicates which block ID is being
|
||||
The <tt>SETBID</tt> record (code 1) indicates which block ID is being
|
||||
described. <tt>SETBID</tt> records can occur multiple times throughout the
|
||||
block to change which block ID is being described. There must be
|
||||
a <tt>SETBID</tt> record prior to any other records.
|
||||
@ -584,13 +603,13 @@ in <tt>BLOCKINFO</tt> blocks receive abbreviation IDs as described
|
||||
in <tt><a href="#DEFINE_ABBREV">DEFINE_ABBREV</a></tt>.
|
||||
</p>
|
||||
|
||||
<p>The <tt>BLOCKNAME</tt> can optionally occur in this block. The elements of
|
||||
the record are the bytes for the string name of the block. llvm-bcanalyzer uses
|
||||
<p>The <tt>BLOCKNAME</tt> record (code 2) can optionally occur in this block. The elements of
|
||||
the record are the bytes of the string name of the block. llvm-bcanalyzer can use
|
||||
this to dump out bitcode files symbolically.</p>
|
||||
|
||||
<p>The <tt>SETRECORDNAME</tt> record can optionally occur in this block. The
|
||||
first entry is a record ID number and the rest of the elements of the record are
|
||||
the bytes for the string name of the record. llvm-bcanalyzer uses
|
||||
<p>The <tt>SETRECORDNAME</tt> record (code 3) can also optionally occur in this block. The
|
||||
first operand value is a record ID number, and the rest of the elements of the record are
|
||||
the bytes for the string name of the record. llvm-bcanalyzer can use
|
||||
this to dump out bitcode files symbolically.</p>
|
||||
|
||||
<p>
|
||||
@ -626,7 +645,7 @@ Each of the fields are 32-bit fields stored in little endian form (as with
|
||||
the rest of the bitcode file fields). The Magic number is always
|
||||
<tt>0x0B17C0DE</tt> and the version is currently always <tt>0</tt>. The Offset
|
||||
field is the offset in bytes to the start of the bitcode stream in the file, and
|
||||
the Size field is a size in bytes of the stream. CPUType is a target-specific
|
||||
the Size field is the size in bytes of the stream. CPUType is a target-specific
|
||||
value that can be used to encode the CPU of the target.
|
||||
</p>
|
||||
|
||||
@ -681,26 +700,28 @@ When combined with the bitcode magic number and viewed as bytes, this is
|
||||
<div class="doc_text">
|
||||
|
||||
<p>
|
||||
<a href="#variablewidth">Variable Width Integers</a> are an efficient way to
|
||||
encode arbitrary sized unsigned values, but is an extremely inefficient way to
|
||||
encode signed values (as signed values are otherwise treated as maximally large
|
||||
unsigned values).
|
||||
<a href="#variablewidth">Variable Width Integer</a> encoding is an efficient way to
|
||||
encode arbitrary sized unsigned values, but is an extremely inefficient for
|
||||
encoding signed values, as signed values are otherwise treated as maximally large
|
||||
unsigned values.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As such, signed vbr values of a specific width are emitted as follows:
|
||||
As such, signed VBR values of a specific width are emitted as follows:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Positive values are emitted as vbrs of the specified width, but with their
|
||||
<li>Positive values are emitted as VBRs of the specified width, but with their
|
||||
value shifted left by one.</li>
|
||||
<li>Negative values are emitted as vbrs of the specified width, but the negated
|
||||
<li>Negative values are emitted as VBRs of the specified width, but the negated
|
||||
value is shifted left by one, and the low bit is set.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
With this encoding, small positive and small negative values can both be emitted
|
||||
efficiently.
|
||||
With this encoding, small positive and small negative values can both
|
||||
be emitted efficiently. Signed VBR encoding is used in
|
||||
<tt>CST_CODE_INTEGER</tt> and <tt>CST_CODE_WIDE_INTEGER</tt> records
|
||||
within <tt>CONSTANTS_BLOCK</tt> blocks.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@ -716,21 +737,23 @@ LLVM IR is defined with the following blocks:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>8 — <tt>MODULE_BLOCK</tt> — This is the top-level block that
|
||||
<li>8 — <a href="#MODULE_BLOCK"><tt>MODULE_BLOCK</tt></a> — This is the top-level block that
|
||||
contains the entire module, and describes a variety of per-module
|
||||
information.</li>
|
||||
<li>9 — <tt>PARAMATTR_BLOCK</tt> — This enumerates the parameter
|
||||
<li>9 — <a href="#PARAMATTR_BLOCK"><tt>PARAMATTR_BLOCK</tt></a> — This enumerates the parameter
|
||||
attributes.</li>
|
||||
<li>10 — <tt>TYPE_BLOCK</tt> — This describes all of the types in
|
||||
<li>10 — <a href="#TYPE_BLOCK"><tt>TYPE_BLOCK</tt></a> — This describes all of the types in
|
||||
the module.</li>
|
||||
<li>11 — <tt>CONSTANTS_BLOCK</tt> — This describes constants for a
|
||||
<li>11 — <a href="#CONSTANTS_BLOCK"><tt>CONSTANTS_BLOCK</tt></a> — This describes constants for a
|
||||
module or function.</li>
|
||||
<li>12 — <tt>FUNCTION_BLOCK</tt> — This describes a function
|
||||
<li>12 — <a href="#FUNCTION_BLOCK"><tt>FUNCTION_BLOCK</tt></a> — This describes a function
|
||||
body.</li>
|
||||
<li>13 — <tt>TYPE_SYMTAB_BLOCK</tt> — This describes the type symbol
|
||||
<li>13 — <a href="#TYPE_SYMTAB_BLOCK"><tt>TYPE_SYMTAB_BLOCK</tt></a> — This describes the type symbol
|
||||
table.</li>
|
||||
<li>14 — <tt>VALUE_SYMTAB_BLOCK</tt> — This describes a value symbol
|
||||
<li>14 — <a href="#VALUE_SYMTAB_BLOCK"><tt>VALUE_SYMTAB_BLOCK</tt></a> — This describes a value symbol
|
||||
table.</li>
|
||||
<li>15 — <a href="#METADATA_BLOCK"><tt>METADATA_BLOCK</tt></a> — This describes metadata items.</li>
|
||||
<li>16 — <a href="#METADATA_ATTACHMENT"><tt>METADATA_ATTACHMENT</tt></a> — This contains records associating metadata with function instruction values.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -741,7 +764,387 @@ LLVM IR is defined with the following blocks:
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>
|
||||
<p>The <tt>MODULE_BLOCK</tt> block (id 8) is the top-level block for LLVM
|
||||
bitcode files, and each bitcode file must contain exactly one. In
|
||||
addition to records (described below) containing information
|
||||
about the module, a <tt>MODULE_BLOCK</tt> block may contain the
|
||||
following sub-blocks:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="#BLOCKINFO"><tt>BLOCKINFO</tt></a></li>
|
||||
<li><a href="#PARAMATTR_BLOCK"><tt>PARAMATTR_BLOCK</tt></a></li>
|
||||
<li><a href="#TYPE_BLOCK"><tt>TYPE_BLOCK</tt></a></li>
|
||||
<li><a href="#TYPE_SYMTAB_BLOCK"><tt>TYPE_SYMTAB_BLOCK</tt></a></li>
|
||||
<li><a href="#VALUE_SYMTAB_BLOCK"><tt>VALUE_SYMTAB_BLOCK</tt></a></li>
|
||||
<li><a href="#CONSTANTS_BLOCK"><tt>CONSTANTS_BLOCK</tt></a></li>
|
||||
<li><a href="#FUNCTION_BLOCK"><tt>FUNCTION_BLOCK</tt></a></li>
|
||||
<li><a href="#METADATA_BLOCK"><tt>METADATA_BLOCK</tt></a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_VERSION">MODULE_CODE_VERSION Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p><tt>[VERSION, version#]</tt></p>
|
||||
|
||||
<p>The <tt>VERSION</tt> record (code 1) contains a single value
|
||||
indicating the format version. Only version 0 is supported at this
|
||||
time.</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_TRIPLE">MODULE_CODE_TRIPLE Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>[TRIPLE, ...string...]</tt></p>
|
||||
|
||||
<p>The <tt>TRIPLE</tt> record (code 2) contains a variable number of
|
||||
values representing the bytes of the <tt>target triple</tt>
|
||||
specification string.</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_DATALAYOUT">MODULE_CODE_DATALAYOUT Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>[DATALAYOUT, ...string...]</tt></p>
|
||||
|
||||
<p>The <tt>DATALAYOUT</tt> record (code 3) contains a variable number of
|
||||
values representing the bytes of the <tt>target datalayout</tt>
|
||||
specification string.</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_ASM">MODULE_CODE_ASM Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>[ASM, ...string...]</tt></p>
|
||||
|
||||
<p>The <tt>ASM</tt> record (code 4) contains a variable number of
|
||||
values representing the bytes of <tt>module asm</tt> strings, with
|
||||
individual assembly blocks separated by newline (ASCII 10) characters.</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_SECTIONNAME">MODULE_CODE_SECTIONNAME Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>[SECTIONNAME, ...string...]</tt></p>
|
||||
|
||||
<p>The <tt>SECTIONNAME</tt> record (code 5) contains a variable number
|
||||
of values representing the bytes of a single section name
|
||||
string. There should be one <tt>SECTIONNAME</tt> record for each
|
||||
section name referenced (e.g., in global variable or function
|
||||
<tt>section</tt> attributes) within the module. These records can be
|
||||
referenced by the 1-based index in the <i>section</i> fields of
|
||||
<tt>GLOBALVAR</tt> or <tt>FUNCTION</tt> records.</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_DEPLIB">MODULE_CODE_DEPLIB Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>[DEPLIB, ...string...]</tt></p>
|
||||
|
||||
<p>The <tt>DEPLIB</tt> record (code 6) contains a variable number of
|
||||
values representing the bytes of a single dependent library name
|
||||
string, one of the libraries mentioned in a <tt>deplibs</tt>
|
||||
declaration. There should be one <tt>DEPLIB</tt> record for each
|
||||
library name referenced.</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_GLOBALVAR">MODULE_CODE_GLOBALVAR Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>[GLOBALVAR, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal]</tt></p>
|
||||
|
||||
<p>The <tt>GLOBALVAR</tt> record (code 7) marks the declaration or
|
||||
definition of a global variable. The operand fields are:</p>
|
||||
|
||||
<ul>
|
||||
<li><i>pointer type</i>: The type index of the pointer type used to point to
|
||||
this global variable</li>
|
||||
|
||||
<li><i>isconst</i>: Non-zero if the variable is treated as constant within
|
||||
the module, or zero if it is not</li>
|
||||
|
||||
<li><i>initid</i>: If non-zero, the value index of the initializer for this
|
||||
variable, plus 1.</li>
|
||||
|
||||
<li><a name="linkage"><i>linkage</i></a>: An encoding of the linkage
|
||||
type for this variable:
|
||||
<ul>
|
||||
<li><tt>external</tt>: code 0</li>
|
||||
<li><tt>weak</tt>: code 1</li>
|
||||
<li><tt>appending</tt>: code 2</li>
|
||||
<li><tt>internal</tt>: code 3</li>
|
||||
<li><tt>linkonce</tt>: code 4</li>
|
||||
<li><tt>dllimport</tt>: code 5</li>
|
||||
<li><tt>dllexport</tt>: code 6</li>
|
||||
<li><tt>extern_weak</tt>: code 7</li>
|
||||
<li><tt>common</tt>: code 8</li>
|
||||
<li><tt>private</tt>: code 9</li>
|
||||
<li><tt>weak_odr</tt>: code 10</li>
|
||||
<li><tt>linkonce_odr</tt>: code 11</li>
|
||||
<li><tt>available_externally</tt>: code 12</li>
|
||||
<li><tt>linker_private</tt>: code 13</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li><i>alignment</i>: The logarithm base 2 of the variable's requested
|
||||
alignment, plus 1</li>
|
||||
|
||||
<li><i>section</i>: If non-zero, the 1-based section index in the
|
||||
table of <a href="#MODULE_CODE_SECTIONNAME">MODULE_CODE_SECTIONNAME</a>
|
||||
entries.</li>
|
||||
|
||||
<li><a name="visibility"><i>visibility</i></a>: If present, an
|
||||
encoding of the visibility of this variable:
|
||||
<ul>
|
||||
<li><tt>default</tt>: code 0</li>
|
||||
<li><tt>hidden</tt>: code 1</li>
|
||||
<li><tt>protected</tt>: code 2</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li><i>threadlocal</i>: If present and non-zero, indicates that the variable
|
||||
is <tt>thread_local</tt></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_FUNCTION">MODULE_CODE_FUNCTION Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p><tt>[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc]</tt></p>
|
||||
|
||||
<p>The <tt>FUNCTION</tt> record (code 8) marks the declaration or
|
||||
definition of a function. The operand fields are:</p>
|
||||
|
||||
<ul>
|
||||
<li><i>type</i>: The type index of the function type describing this function</li>
|
||||
|
||||
<li><i>callingconv</i>: The calling convention number:
|
||||
<ul>
|
||||
<li><tt>ccc</tt>: code 0</li>
|
||||
<li><tt>fastcc</tt>: code 8</li>
|
||||
<li><tt>coldcc</tt>: code 9</li>
|
||||
<li><tt>x86_stdcallcc</tt>: code 64</li>
|
||||
<li><tt>x86_fastcallcc</tt>: code 65</li>
|
||||
<li><tt>arm_apcscc</tt>: code 66</li>
|
||||
<li><tt>arm_aapcscc</tt>: code 67</li>
|
||||
<li><tt>arm_aapcs_vfpcc</tt>: code 68</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li><i>isproto</i>: Non-zero if this entry represents a declaration
|
||||
rather than a definition</li>
|
||||
|
||||
<li><i>linkage</i>: An encoding of the <a href="#linkage">linkage type</a>
|
||||
for this function</li>
|
||||
|
||||
<li><i>paramattr</i>: If nonzero, the 1-based parameter attribute index
|
||||
into the table of <a href="#PARAMATTR_CODE_ENTRY">PARAMATTR_CODE_ENTRY</a>
|
||||
entries.</li>
|
||||
|
||||
<li><i>alignment</i>: The logarithm base 2 of the function's requested
|
||||
alignment, plus 1</li>
|
||||
|
||||
<li><i>section</i>: If non-zero, the 1-based section index in the
|
||||
table of <a href="#MODULE_CODE_SECTIONNAME">MODULE_CODE_SECTIONNAME</a>
|
||||
entries.</li>
|
||||
|
||||
<li><i>visibility</i>: An encoding of the <a href="#visibility">visibility</a>
|
||||
of this function</li>
|
||||
|
||||
<li><i>gc</i>: If present and nonzero, the 1-based garbage collector
|
||||
index in the table of
|
||||
<a href="#MODULE_CODE_GCNAME">MODULE_CODE_GCNAME</a> entries.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_ALIAS">MODULE_CODE_ALIAS Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p><tt>[ALIAS, alias type, aliasee val#, linkage, visibility]</tt></p>
|
||||
|
||||
<p>The <tt>ALIAS</tt> record (code 9) marks the definition of an
|
||||
alias. The operand fields are</p>
|
||||
|
||||
<ul>
|
||||
<li><i>alias type</i>: The type index of the alias</li>
|
||||
|
||||
<li><i>aliasee val#</i>: The value index of the aliased value</li>
|
||||
|
||||
<li><i>linkage</i>: An encoding of the <a href="#linkage">linkage type</a>
|
||||
for this alias</li>
|
||||
|
||||
<li><i>visibility</i>: If present, an encoding of the
|
||||
<a href="#visibility">visibility</a> of the alias</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_PURGEVALS">MODULE_CODE_PURGEVALS Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>[PURGEVALS, numvals]</tt></p>
|
||||
|
||||
<p>The <tt>PURGEVALS</tt> record (code 10) resets the module-level
|
||||
value list to the size given by the single operand value. Module-level
|
||||
value list items are added by <tt>GLOBALVAR</tt>, <tt>FUNCTION</tt>,
|
||||
and <tt>ALIAS</tt> records. After a <tt>PURGEVALS</tt> record is seen,
|
||||
new value indices will start from the given <i>numvals</i> value.</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="MODULE_CODE_GCNAME">MODULE_CODE_GCNAME Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>[GCNAME, ...string...]</tt></p>
|
||||
|
||||
<p>The <tt>GCNAME</tt> record (code 11) contains a variable number of
|
||||
values representing the bytes of a single garbage collector name
|
||||
string. There should be one <tt>GCNAME</tt> record for each garbage
|
||||
collector name referenced in function <tt>gc</tt> attributes within
|
||||
the module. These records can be referenced by 1-based index in the <i>gc</i>
|
||||
fields of <tt>FUNCTION</tt> records.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="PARAMATTR_BLOCK">PARAMATTR_BLOCK Contents</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>PARAMATTR_BLOCK</tt> block (id 9) ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"><a name="PARAMATTR_CODE_ENTRY">PARAMATTR_CODE_ENTRY Record</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p><tt>[ENTRY, paramidx0, attr0, paramidx1, attr1...]</tt></p>
|
||||
|
||||
<p>The <tt>ENTRY</tt> record (code 1) ...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="TYPE_BLOCK">TYPE_BLOCK Contents</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>TYPE_BLOCK</tt> block (id 10) ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="CONSTANTS_BLOCK">CONSTANTS_BLOCK Contents</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>CONSTANTS_BLOCK</tt> block (id 11) ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="FUNCTION_BLOCK">FUNCTION_BLOCK Contents</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>FUNCTION_BLOCK</tt> block (id 12) ...
|
||||
</p>
|
||||
|
||||
<p>In addition to the record types described below, a
|
||||
<tt>FUNCTION_BLOCK</tt> block may contain the following sub-blocks:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="#CONSTANTS_BLOCK"><tt>CONSTANTS_BLOCK</tt></a></li>
|
||||
<li><a href="#VALUE_SYMTAB_BLOCK"><tt>VALUE_SYMTAB_BLOCK</tt></a></li>
|
||||
<li><a href="#METADATA_ATTACHMENT"><tt>METADATA_ATTACHMENT</tt></a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="TYPE_SYMTAB_BLOCK">TYPE_SYMTAB_BLOCK Contents</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>TYPE_SYMTAB_BLOCK</tt> block (id 13) ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="VALUE_SYMTAB_BLOCK">VALUE_SYMTAB_BLOCK Contents</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>VALUE_SYMTAB_BLOCK</tt> block (id 14) ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="METADATA_BLOCK">METADATA_BLOCK Contents</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>METADATA_BLOCK</tt> block (id 15) ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="METADATA_ATTACHMENT">METADATA_ATTACHMENT Contents</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>METADATA_ATTACHMENT</tt> block (id 16) ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@ -755,7 +1158,7 @@ LLVM IR is defined with the following blocks:
|
||||
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
||||
<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-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2009-10-29 05:25:46 +0100 (Thu, 29 Oct 2009) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -49,6 +49,11 @@ Show the B<lit> help message.
|
||||
Run I<N> tests in parallel. By default, this is automatically chose to match the
|
||||
number of detected available CPUs.
|
||||
|
||||
=item B<--config-prefix>=I<NAME>
|
||||
|
||||
Search for I<NAME.cfg> and I<NAME.site.cfg> when searching for test suites,
|
||||
instead I<lit.cfg> and I<lit.site.cfg>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 OUTPUT OPTIONS
|
||||
|
@ -33,11 +33,12 @@ The ReST source lives in the directory 'tools/llvmc/doc'. -->
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#language-map" id="id15">Language map</a></li>
|
||||
<li><a class="reference internal" href="#more-advanced-topics" id="id16">More advanced topics</a><ul>
|
||||
<li><a class="reference internal" href="#hooks-and-environment-variables" id="id17">Hooks and environment variables</a></li>
|
||||
<li><a class="reference internal" href="#how-plugins-are-loaded" id="id18">How plugins are loaded</a></li>
|
||||
<li><a class="reference internal" href="#debugging" id="id19">Debugging</a></li>
|
||||
<li><a class="reference internal" href="#conditioning-on-the-executable-name" id="id20">Conditioning on the executable name</a></li>
|
||||
<li><a class="reference internal" href="#option-preprocessor" id="id16">Option preprocessor</a></li>
|
||||
<li><a class="reference internal" href="#more-advanced-topics" id="id17">More advanced topics</a><ul>
|
||||
<li><a class="reference internal" href="#hooks-and-environment-variables" id="id18">Hooks and environment variables</a></li>
|
||||
<li><a class="reference internal" href="#how-plugins-are-loaded" id="id19">How plugins are loaded</a></li>
|
||||
<li><a class="reference internal" href="#debugging" id="id20">Debugging</a></li>
|
||||
<li><a class="reference internal" href="#conditioning-on-the-executable-name" id="id21">Conditioning on the executable name</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@ -307,13 +308,13 @@ separate option groups syntactically.</p>
|
||||
<tt class="docutils literal"><span class="pre">-std=c99</span></tt>. It is also allowed to use spaces instead of the equality
|
||||
sign: <tt class="docutils literal"><span class="pre">-std</span> <span class="pre">c99</span></tt>. At most one occurrence is allowed.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">parameter_list_option</span></tt> - same as the above, but more than one option
|
||||
occurrence is allowed.</li>
|
||||
occurence is allowed.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">prefix_option</span></tt> - same as the parameter_option, but the option name and
|
||||
argument do not have to be separated. Example: <tt class="docutils literal"><span class="pre">-ofile</span></tt>. This can be also
|
||||
specified as <tt class="docutils literal"><span class="pre">-o</span> <span class="pre">file</span></tt>; however, <tt class="docutils literal"><span class="pre">-o=file</span></tt> will be parsed incorrectly
|
||||
(<tt class="docutils literal"><span class="pre">=file</span></tt> will be interpreted as option value). At most one occurrence is
|
||||
allowed.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">prefix_list_option</span></tt> - same as the above, but more than one occurrence of
|
||||
<li><tt class="docutils literal"><span class="pre">prefix_list_option</span></tt> - same as the above, but more than one occurence of
|
||||
the option is allowed; example: <tt class="docutils literal"><span class="pre">-lm</span> <span class="pre">-lpthread</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">alias_option</span></tt> - a special option type for creating aliases. Unlike other
|
||||
option types, aliases are not allowed to have any properties besides the
|
||||
@ -343,8 +344,9 @@ output).</li>
|
||||
output.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">multi_val</span> <span class="pre">n</span></tt> - this option takes <em>n</em> arguments (can be useful in some
|
||||
special cases). Usage example: <tt class="docutils literal"><span class="pre">(parameter_list_option</span> <span class="pre">"foo",</span> <span class="pre">(multi_val</span>
|
||||
<span class="pre">3))</span></tt>. Only list options can have this attribute; you can, however, use
|
||||
the <tt class="docutils literal"><span class="pre">one_or_more</span></tt> and <tt class="docutils literal"><span class="pre">zero_or_one</span></tt> properties.</li>
|
||||
<span class="pre">3))</span></tt>; the command-line syntax is '-foo a b c'. Only list options can have
|
||||
this attribute; you can, however, use the <tt class="docutils literal"><span class="pre">one_or_more</span></tt>, <tt class="docutils literal"><span class="pre">zero_or_one</span></tt>
|
||||
and <tt class="docutils literal"><span class="pre">required</span></tt> properties.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">init</span></tt> - this option has a default value, either a string (if it is a
|
||||
parameter), or a boolean (if it is a switch; boolean constants are called
|
||||
<tt class="docutils literal"><span class="pre">true</span></tt> and <tt class="docutils literal"><span class="pre">false</span></tt>). List options can't have this attribute. Usage
|
||||
@ -417,8 +419,15 @@ readability. It is usually better to split tool descriptions and/or
|
||||
use TableGen inheritance instead.</p>
|
||||
<ul class="simple">
|
||||
<li>Possible tests are:<ul>
|
||||
<li><tt class="docutils literal"><span class="pre">switch_on</span></tt> - Returns true if a given command-line switch is
|
||||
provided by the user. Example: <tt class="docutils literal"><span class="pre">(switch_on</span> <span class="pre">"opt")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">switch_on</span></tt> - Returns true if a given command-line switch is provided by
|
||||
the user. Can be given a list as argument, in that case <tt class="docutils literal"><span class="pre">(switch_on</span> <span class="pre">["foo",</span>
|
||||
<span class="pre">"bar",</span> <span class="pre">"baz"])</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">(and</span> <span class="pre">(switch_on</span> <span class="pre">"foo"),</span> <span class="pre">(switch_on</span>
|
||||
<span class="pre">"bar"),</span> <span class="pre">(switch_on</span> <span class="pre">"baz"))</span></tt>.
|
||||
Example: <tt class="docutils literal"><span class="pre">(switch_on</span> <span class="pre">"opt")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">any_switch_on</span></tt> - Given a list of switch options, returns true if any of
|
||||
the switches is turned on.
|
||||
Example: <tt class="docutils literal"><span class="pre">(any_switch_on</span> <span class="pre">["foo",</span> <span class="pre">"bar",</span> <span class="pre">"baz"])</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">(or</span>
|
||||
<span class="pre">(switch_on</span> <span class="pre">"foo"),</span> <span class="pre">(switch_on</span> <span class="pre">"bar"),</span> <span class="pre">(switch_on</span> <span class="pre">"baz"))</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">parameter_equals</span></tt> - Returns true if a command-line parameter equals
|
||||
a given value.
|
||||
Example: <tt class="docutils literal"><span class="pre">(parameter_equals</span> <span class="pre">"W",</span> <span class="pre">"all")</span></tt>.</li>
|
||||
@ -428,16 +437,24 @@ Example: <tt class="docutils literal"><span class="pre">(parameter_in_list</span
|
||||
<li><tt class="docutils literal"><span class="pre">input_languages_contain</span></tt> - Returns true if a given language
|
||||
belongs to the current input language set.
|
||||
Example: <tt class="docutils literal"><span class="pre">(input_languages_contain</span> <span class="pre">"c++")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">in_language</span></tt> - Evaluates to true if the input file language
|
||||
equals to the argument. At the moment works only with <tt class="docutils literal"><span class="pre">cmd_line</span></tt>
|
||||
and <tt class="docutils literal"><span class="pre">actions</span></tt> (on non-join nodes).
|
||||
<li><tt class="docutils literal"><span class="pre">in_language</span></tt> - Evaluates to true if the input file language is equal to
|
||||
the argument. At the moment works only with <tt class="docutils literal"><span class="pre">cmd_line</span></tt> and <tt class="docutils literal"><span class="pre">actions</span></tt> (on
|
||||
non-join nodes).
|
||||
Example: <tt class="docutils literal"><span class="pre">(in_language</span> <span class="pre">"c++")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">not_empty</span></tt> - Returns true if a given option (which should be
|
||||
either a parameter or a parameter list) is set by the
|
||||
user.
|
||||
<li><tt class="docutils literal"><span class="pre">not_empty</span></tt> - Returns true if a given option (which should be either a
|
||||
parameter or a parameter list) is set by the user. Like <tt class="docutils literal"><span class="pre">switch_on</span></tt>, can
|
||||
be also given a list as argument.
|
||||
Example: <tt class="docutils literal"><span class="pre">(not_empty</span> <span class="pre">"o")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">any_not_empty</span></tt> - Returns true if <tt class="docutils literal"><span class="pre">not_empty</span></tt> returns true for any of
|
||||
the options in the list.
|
||||
Example: <tt class="docutils literal"><span class="pre">(any_not_empty</span> <span class="pre">["foo",</span> <span class="pre">"bar",</span> <span class="pre">"baz"])</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">(or</span>
|
||||
<span class="pre">(not_empty</span> <span class="pre">"foo"),</span> <span class="pre">(not_empty</span> <span class="pre">"bar"),</span> <span class="pre">(not_empty</span> <span class="pre">"baz"))</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">empty</span></tt> - The opposite of <tt class="docutils literal"><span class="pre">not_empty</span></tt>. Equivalent to <tt class="docutils literal"><span class="pre">(not</span> <span class="pre">(not_empty</span>
|
||||
<span class="pre">X))</span></tt>. Provided for convenience.</li>
|
||||
<span class="pre">X))</span></tt>. Provided for convenience. Can be given a list as argument.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">any_not_empty</span></tt> - Returns true if <tt class="docutils literal"><span class="pre">not_empty</span></tt> returns true for any of
|
||||
the options in the list.
|
||||
Example: <tt class="docutils literal"><span class="pre">(any_empty</span> <span class="pre">["foo",</span> <span class="pre">"bar",</span> <span class="pre">"baz"])</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">(not</span> <span class="pre">(and</span>
|
||||
<span class="pre">(not_empty</span> <span class="pre">"foo"),</span> <span class="pre">(not_empty</span> <span class="pre">"bar"),</span> <span class="pre">(not_empty</span> <span class="pre">"baz")))</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">single_input_file</span></tt> - Returns true if there was only one input file
|
||||
provided on the command-line. Used without arguments:
|
||||
<tt class="docutils literal"><span class="pre">(single_input_file)</span></tt>.</li>
|
||||
@ -481,8 +498,8 @@ options that aren't mentioned in the option list.</p>
|
||||
<li>Possible tool properties:<ul>
|
||||
<li><tt class="docutils literal"><span class="pre">in_language</span></tt> - input language name. Can be either a string or a
|
||||
list, in case the tool supports multiple input languages.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">out_language</span></tt> - output language name. Tools are not allowed to
|
||||
have multiple output languages.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">out_language</span></tt> - output language name. Multiple output languages are not
|
||||
allowed.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">output_suffix</span></tt> - output file suffix. Can also be changed
|
||||
dynamically, see documentation on actions.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">cmd_line</span></tt> - the actual command used to run the tool. You can
|
||||
@ -537,10 +554,11 @@ like a linker.</p>
|
||||
command.
|
||||
Example: <tt class="docutils literal"><span class="pre">(case</span> <span class="pre">(switch_on</span> <span class="pre">"pthread"),</span> <span class="pre">(append_cmd</span>
|
||||
<span class="pre">"-lpthread"))</span></tt></li>
|
||||
<li><tt class="docutils literal"><span class="pre">error`</span> <span class="pre">-</span> <span class="pre">exit</span> <span class="pre">with</span> <span class="pre">error.</span>
|
||||
<span class="pre">Example:</span> <span class="pre">``(error</span> <span class="pre">"Mixing</span> <span class="pre">-c</span> <span class="pre">and</span> <span class="pre">-S</span> <span class="pre">is</span> <span class="pre">not</span> <span class="pre">allowed!")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">forward</span></tt> - forward an option unchanged.
|
||||
Example: <tt class="docutils literal"><span class="pre">(forward</span> <span class="pre">"Wall")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">error</span></tt> - exit with error.
|
||||
Example: <tt class="docutils literal"><span class="pre">(error</span> <span class="pre">"Mixing</span> <span class="pre">-c</span> <span class="pre">and</span> <span class="pre">-S</span> <span class="pre">is</span> <span class="pre">not</span> <span class="pre">allowed!")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">warning</span></tt> - print a warning.
|
||||
Example: <tt class="docutils literal"><span class="pre">(warning</span> <span class="pre">"Specifying</span> <span class="pre">both</span> <span class="pre">-O1</span> <span class="pre">and</span> <span class="pre">-O2</span> <span class="pre">is</span> <span class="pre">meaningless!")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">forward</span></tt> - forward an option unchanged. Example: <tt class="docutils literal"><span class="pre">(forward</span> <span class="pre">"Wall")</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">forward_as</span></tt> - Change the name of an option, but forward the
|
||||
argument unchanged.
|
||||
Example: <tt class="docutils literal"><span class="pre">(forward_as</span> <span class="pre">"O0",</span> <span class="pre">"--disable-optimization")</span></tt>.</li>
|
||||
@ -583,10 +601,37 @@ linked with the root node. Since tools are not allowed to have
|
||||
multiple output languages, for nodes "inside" the graph the input and
|
||||
output languages should match. This is enforced at compile-time.</p>
|
||||
</div>
|
||||
<div class="section" id="option-preprocessor">
|
||||
<h1><a class="toc-backref" href="#id16">Option preprocessor</a></h1>
|
||||
<p>It is sometimes useful to run error-checking code before processing the
|
||||
compilation graph. For example, if optimization options "-O1" and "-O2" are
|
||||
implemented as switches, we might want to output a warning if the user invokes
|
||||
the driver with both of these options enabled.</p>
|
||||
<p>The <tt class="docutils literal"><span class="pre">OptionPreprocessor</span></tt> feature is reserved specially for these
|
||||
occasions. Example (adapted from the built-in Base plugin):</p>
|
||||
<pre class="literal-block">
|
||||
def Preprocess : OptionPreprocessor<
|
||||
(case (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
|
||||
[(unset_option ["O0", "O1", "O2"]),
|
||||
(warning "Multiple -O options specified, defaulted to -O3.")],
|
||||
(and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
|
||||
(unset_option ["O0", "O1"]),
|
||||
(and (switch_on "O1"), (switch_on "O0")),
|
||||
(unset_option "O0"))
|
||||
>;
|
||||
</pre>
|
||||
<p>Here, <tt class="docutils literal"><span class="pre">OptionPreprocessor</span></tt> is used to unset all spurious optimization options
|
||||
(so that they are not forwarded to the compiler).</p>
|
||||
<p><tt class="docutils literal"><span class="pre">OptionPreprocessor</span></tt> is basically a single big <tt class="docutils literal"><span class="pre">case</span></tt> expression, which is
|
||||
evaluated only once right after the plugin is loaded. The only allowed actions
|
||||
in <tt class="docutils literal"><span class="pre">OptionPreprocessor</span></tt> are <tt class="docutils literal"><span class="pre">error</span></tt>, <tt class="docutils literal"><span class="pre">warning</span></tt> and a special action
|
||||
<tt class="docutils literal"><span class="pre">unset_option</span></tt>, which, as the name suggests, unsets a given option. For
|
||||
convenience, <tt class="docutils literal"><span class="pre">unset_option</span></tt> also works on lists.</p>
|
||||
</div>
|
||||
<div class="section" id="more-advanced-topics">
|
||||
<h1><a class="toc-backref" href="#id16">More advanced topics</a></h1>
|
||||
<h1><a class="toc-backref" href="#id17">More advanced topics</a></h1>
|
||||
<div class="section" id="hooks-and-environment-variables">
|
||||
<span id="hooks"></span><h2><a class="toc-backref" href="#id17">Hooks and environment variables</a></h2>
|
||||
<span id="hooks"></span><h2><a class="toc-backref" href="#id18">Hooks and environment variables</a></h2>
|
||||
<p>Normally, LLVMC executes programs from the system <tt class="docutils literal"><span class="pre">PATH</span></tt>. Sometimes,
|
||||
this is not sufficient: for example, we may want to specify tool paths
|
||||
or names in the configuration file. This can be easily achieved via
|
||||
@ -619,7 +664,7 @@ the <tt class="docutils literal"><span class="pre">case</span></tt> expression (
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="how-plugins-are-loaded">
|
||||
<span id="priorities"></span><h2><a class="toc-backref" href="#id18">How plugins are loaded</a></h2>
|
||||
<span id="priorities"></span><h2><a class="toc-backref" href="#id19">How plugins are loaded</a></h2>
|
||||
<p>It is possible for LLVMC plugins to depend on each other. For example,
|
||||
one can create edges between nodes defined in some other plugin. To
|
||||
make this work, however, that plugin should be loaded first. To
|
||||
@ -635,7 +680,7 @@ with 0. Therefore, the plugin with the highest priority value will be
|
||||
loaded last.</p>
|
||||
</div>
|
||||
<div class="section" id="debugging">
|
||||
<h2><a class="toc-backref" href="#id19">Debugging</a></h2>
|
||||
<h2><a class="toc-backref" href="#id20">Debugging</a></h2>
|
||||
<p>When writing LLVMC plugins, it can be useful to get a visual view of
|
||||
the resulting compilation graph. This can be achieved via the command
|
||||
line option <tt class="docutils literal"><span class="pre">--view-graph</span></tt>. This command assumes that <a class="reference external" href="http://www.graphviz.org/">Graphviz</a> and
|
||||
@ -651,7 +696,7 @@ perform any compilation tasks and returns the number of encountered
|
||||
errors as its status code.</p>
|
||||
</div>
|
||||
<div class="section" id="conditioning-on-the-executable-name">
|
||||
<h2><a class="toc-backref" href="#id20">Conditioning on the executable name</a></h2>
|
||||
<h2><a class="toc-backref" href="#id21">Conditioning on the executable name</a></h2>
|
||||
<p>For now, the executable name (the value passed to the driver in <tt class="docutils literal"><span class="pre">argv[0]</span></tt>) is
|
||||
accessible only in the C++ code (i.e. hooks). Use the following code:</p>
|
||||
<pre class="literal-block">
|
||||
@ -682,7 +727,7 @@ the <tt class="docutils literal"><span class="pre">Base</span></tt> plugin behav
|
||||
<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
|
||||
|
||||
Last modified: $Date: 2009-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2009-10-26 02:35:46 +0100 (Mon, 26 Oct 2009) $
|
||||
</address></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1154,7 +1154,7 @@ first command may not be required if you are already using the module):</p>
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
$ mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
|
||||
$ echo ':llvm:M::llvm::/path/to/lli:' > /proc/sys/fs/binfmt_misc/register
|
||||
$ echo ':llvm:M::BC::/path/to/lli:' > /proc/sys/fs/binfmt_misc/register
|
||||
$ chmod u+x hello.bc (if needed)
|
||||
$ ./hello.bc
|
||||
</pre>
|
||||
@ -1636,7 +1636,7 @@ out:</p>
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.x10sys.com/rspencer/">Reid Spencer</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-10-23 08:20:06 +0200 (Fri, 23 Oct 2009) $
|
||||
Last modified: $Date: 2009-11-04 07:15:28 +0100 (Wed, 04 Nov 2009) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -83,6 +83,7 @@
|
||||
<li><a href="#complexconstants">Complex Constants</a></li>
|
||||
<li><a href="#globalconstants">Global Variable and Function Addresses</a></li>
|
||||
<li><a href="#undefvalues">Undefined Values</a></li>
|
||||
<li><a href="#blockaddress">Addresses of Basic Blocks</a></li>
|
||||
<li><a href="#constantexprs">Constant Expressions</a></li>
|
||||
<li><a href="#metadata">Embedded Metadata</a></li>
|
||||
</ol>
|
||||
@ -110,6 +111,7 @@
|
||||
<li><a href="#i_ret">'<tt>ret</tt>' Instruction</a></li>
|
||||
<li><a href="#i_br">'<tt>br</tt>' Instruction</a></li>
|
||||
<li><a href="#i_switch">'<tt>switch</tt>' Instruction</a></li>
|
||||
<li><a href="#i_indirectbr">'<tt>indirectbr</tt>' Instruction</a></li>
|
||||
<li><a href="#i_invoke">'<tt>invoke</tt>' Instruction</a></li>
|
||||
<li><a href="#i_unwind">'<tt>unwind</tt>' Instruction</a></li>
|
||||
<li><a href="#i_unreachable">'<tt>unreachable</tt>' Instruction</a></li>
|
||||
@ -156,8 +158,6 @@
|
||||
</li>
|
||||
<li><a href="#memoryops">Memory Access and Addressing Operations</a>
|
||||
<ol>
|
||||
<li><a href="#i_malloc">'<tt>malloc</tt>' Instruction</a></li>
|
||||
<li><a href="#i_free">'<tt>free</tt>' Instruction</a></li>
|
||||
<li><a href="#i_alloca">'<tt>alloca</tt>' Instruction</a></li>
|
||||
<li><a href="#i_load">'<tt>load</tt>' Instruction</a></li>
|
||||
<li><a href="#i_store">'<tt>store</tt>' Instruction</a></li>
|
||||
@ -338,7 +338,7 @@
|
||||
IR's", allowing many source languages to be mapped to them). By providing
|
||||
type information, LLVM can be used as the target of optimizations: for
|
||||
example, through pointer analysis, it can be proven that a C automatic
|
||||
variable is never accessed outside of the current function... allowing it to
|
||||
variable is never accessed outside of the current function, allowing it to
|
||||
be promoted to a simple SSA value instead of a memory location.</p>
|
||||
|
||||
</div>
|
||||
@ -359,12 +359,12 @@
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>...because the definition of <tt>%x</tt> does not dominate all of its
|
||||
uses. The LLVM infrastructure provides a verification pass that may be used
|
||||
to verify that an LLVM module is well formed. This pass is automatically run
|
||||
by the parser after parsing input assembly and by the optimizer before it
|
||||
outputs bitcode. The violations pointed out by the verifier pass indicate
|
||||
bugs in transformation passes or input to the parser.</p>
|
||||
<p>because the definition of <tt>%x</tt> does not dominate all of its uses. The
|
||||
LLVM infrastructure provides a verification pass that may be used to verify
|
||||
that an LLVM module is well formed. This pass is automatically run by the
|
||||
parser after parsing input assembly and by the optimizer before it outputs
|
||||
bitcode. The violations pointed out by the verifier pass indicate bugs in
|
||||
transformation passes or input to the parser.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -438,8 +438,8 @@
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<a href="#i_add">add</a> i32 %X, %X <i>; yields {i32}:%0</i>
|
||||
<a href="#i_add">add</a> i32 %0, %0 <i>; yields {i32}:%1</i>
|
||||
%0 = <a href="#i_add">add</a> i32 %X, %X <i>; yields {i32}:%0</i>
|
||||
%1 = <a href="#i_add">add</a> i32 %0, %0 <i>; yields {i32}:%1</i>
|
||||
%result = <a href="#i_add">add</a> i32 %1, %1
|
||||
</pre>
|
||||
</div>
|
||||
@ -457,7 +457,7 @@
|
||||
<li>Unnamed temporaries are numbered sequentially</li>
|
||||
</ol>
|
||||
|
||||
<p>...and it also shows a convention that we follow in this document. When
|
||||
<p>It also shows a convention that we follow in this document. When
|
||||
demonstrating instructions, we will follow an instruction with a comment that
|
||||
defines the type and name of value produced. Comments are shown in italic
|
||||
text.</p>
|
||||
@ -482,24 +482,21 @@
|
||||
the "hello world" module:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre><i>; Declare the string constant as a global constant...</i>
|
||||
<a href="#identifiers">@.LC0</a> = <a href="#linkage_internal">internal</a> <a
|
||||
href="#globalvars">constant</a> <a href="#t_array">[13 x i8]</a> c"hello world\0A\00" <i>; [13 x i8]*</i>
|
||||
<pre>
|
||||
<i>; Declare the string constant as a global constant.</i>
|
||||
<a href="#identifiers">@.LC0</a> = <a href="#linkage_internal">internal</a> <a href="#globalvars">constant</a> <a href="#t_array">[13 x i8]</a> c"hello world\0A\00" <i>; [13 x i8]*</i>
|
||||
|
||||
<i>; External declaration of the puts function</i>
|
||||
<a href="#functionstructure">declare</a> i32 @puts(i8 *) <i>; i32(i8 *)* </i>
|
||||
<a href="#functionstructure">declare</a> i32 @puts(i8 *) <i>; i32(i8 *)* </i>
|
||||
|
||||
<i>; Definition of main function</i>
|
||||
define i32 @main() { <i>; i32()* </i>
|
||||
<i>; Convert [13 x i8]* to i8 *...</i>
|
||||
%cast210 = <a
|
||||
href="#i_getelementptr">getelementptr</a> [13 x i8]* @.LC0, i64 0, i64 0 <i>; i8 *</i>
|
||||
define i32 @main() { <i>; i32()* </i>
|
||||
<i>; Convert [13 x i8]* to i8 *...</i>
|
||||
%cast210 = <a href="#i_getelementptr">getelementptr</a> [13 x i8]* @.LC0, i64 0, i64 0 <i>; i8 *</i>
|
||||
|
||||
<i>; Call puts function to write out the string to stdout...</i>
|
||||
<a
|
||||
href="#i_call">call</a> i32 @puts(i8 * %cast210) <i>; i32</i>
|
||||
<a
|
||||
href="#i_ret">ret</a> i32 0<br>}<br>
|
||||
<i>; Call puts function to write out the string to stdout.</i>
|
||||
<a href="#i_call">call</a> i32 @puts(i8 * %cast210) <i>; i32</i>
|
||||
<a href="#i_ret">ret</a> i32 0<br>}<br>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -527,7 +524,7 @@ define i32 @main() { <i>; i32()* </
|
||||
linkage:</p>
|
||||
|
||||
<dl>
|
||||
<dt><tt><b><a name="linkage_private">private</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_private">private</a></b></tt></dt>
|
||||
<dd>Global values with private linkage are only directly accessible by objects
|
||||
in the current module. In particular, linking code into a module with an
|
||||
private global value may cause the private to be renamed as necessary to
|
||||
@ -535,7 +532,7 @@ define i32 @main() { <i>; i32()* </
|
||||
references can be updated. This doesn't show up in any symbol table in the
|
||||
object file.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_linker_private">linker_private</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_linker_private">linker_private</a></b></tt></dt>
|
||||
<dd>Similar to private, but the symbol is passed through the assembler and
|
||||
removed by the linker after evaluation. Note that (unlike private
|
||||
symbols) linker_private symbols are subject to coalescing by the linker:
|
||||
@ -543,12 +540,12 @@ define i32 @main() { <i>; i32()* </
|
||||
normal strong symbols, they are removed by the linker from the final
|
||||
linked image (executable or dynamic library).</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_internal">internal</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_internal">internal</a></b></tt></dt>
|
||||
<dd>Similar to private, but the value shows as a local symbol
|
||||
(<tt>STB_LOCAL</tt> in the case of ELF) in the object file. This
|
||||
corresponds to the notion of the '<tt>static</tt>' keyword in C.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_available_externally">available_externally</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_available_externally">available_externally</a></b></tt></dt>
|
||||
<dd>Globals with "<tt>available_externally</tt>" linkage are never emitted
|
||||
into the object file corresponding to the LLVM module. They exist to
|
||||
allow inlining and other optimizations to take place given knowledge of
|
||||
@ -557,20 +554,20 @@ define i32 @main() { <i>; i32()* </
|
||||
be discarded at will, and are otherwise the same as <tt>linkonce_odr</tt>.
|
||||
This linkage type is only allowed on definitions, not declarations.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_linkonce">linkonce</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_linkonce">linkonce</a></b></tt></dt>
|
||||
<dd>Globals with "<tt>linkonce</tt>" linkage are merged with other globals of
|
||||
the same name when linkage occurs. This is typically used to implement
|
||||
inline functions, templates, or other code which must be generated in each
|
||||
translation unit that uses it. Unreferenced <tt>linkonce</tt> globals are
|
||||
allowed to be discarded.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_weak">weak</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_weak">weak</a></b></tt></dt>
|
||||
<dd>"<tt>weak</tt>" linkage has the same merging semantics as
|
||||
<tt>linkonce</tt> linkage, except that unreferenced globals with
|
||||
<tt>weak</tt> linkage may not be discarded. This is used for globals that
|
||||
are declared "weak" in C source code.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_common">common</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_common">common</a></b></tt></dt>
|
||||
<dd>"<tt>common</tt>" linkage is most similar to "<tt>weak</tt>" linkage, but
|
||||
they are used for tentative definitions in C, such as "<tt>int X;</tt>" at
|
||||
global scope.
|
||||
@ -582,20 +579,20 @@ define i32 @main() { <i>; i32()* </
|
||||
have common linkage.</dd>
|
||||
|
||||
|
||||
<dt><tt><b><a name="linkage_appending">appending</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_appending">appending</a></b></tt></dt>
|
||||
<dd>"<tt>appending</tt>" linkage may only be applied to global variables of
|
||||
pointer to array type. When two global variables with appending linkage
|
||||
are linked together, the two global arrays are appended together. This is
|
||||
the LLVM, typesafe, equivalent of having the system linker append together
|
||||
"sections" with identical names when .o files are linked.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_externweak">extern_weak</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_externweak">extern_weak</a></b></tt></dt>
|
||||
<dd>The semantics of this linkage follow the ELF object file model: the symbol
|
||||
is weak until linked, if not linked, the symbol becomes null instead of
|
||||
being an undefined reference.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_linkonce_odr">linkonce_odr</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_weak_odr">weak_odr</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_linkonce_odr">linkonce_odr</a></b></tt></dt>
|
||||
<dt><tt><b><a name="linkage_weak_odr">weak_odr</a></b></tt></dt>
|
||||
<dd>Some languages allow differing globals to be merged, such as two functions
|
||||
with different semantics. Other languages, such as <tt>C++</tt>, ensure
|
||||
that only equivalent globals are ever merged (the "one definition rule" -
|
||||
@ -615,14 +612,14 @@ define i32 @main() { <i>; i32()* </
|
||||
DLLs (Dynamic Link Libraries).</p>
|
||||
|
||||
<dl>
|
||||
<dt><tt><b><a name="linkage_dllimport">dllimport</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_dllimport">dllimport</a></b></tt></dt>
|
||||
<dd>"<tt>dllimport</tt>" linkage causes the compiler to reference a function
|
||||
or variable via a global pointer to a pointer that is set up by the DLL
|
||||
exporting the symbol. On Microsoft Windows targets, the pointer name is
|
||||
formed by combining <code>__imp_</code> and the function or variable
|
||||
name.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_dllexport">dllexport</a></b></tt>: </dt>
|
||||
<dt><tt><b><a name="linkage_dllexport">dllexport</a></b></tt></dt>
|
||||
<dd>"<tt>dllexport</tt>" linkage causes the compiler to provide a global
|
||||
pointer to a pointer in a DLL, so that it can be referenced with the
|
||||
<tt>dllimport</tt> attribute. On Microsoft Windows targets, the pointer
|
||||
@ -935,24 +932,24 @@ declare signext i8 @returns_signed_char()
|
||||
<p>Currently, only the following parameter attributes are defined:</p>
|
||||
|
||||
<dl>
|
||||
<dt><tt>zeroext</tt></dt>
|
||||
<dt><tt><b>zeroext</b></tt></dt>
|
||||
<dd>This indicates to the code generator that the parameter or return value
|
||||
should be zero-extended to a 32-bit value by the caller (for a parameter)
|
||||
or the callee (for a return value).</dd>
|
||||
|
||||
<dt><tt>signext</tt></dt>
|
||||
<dt><tt><b>signext</b></tt></dt>
|
||||
<dd>This indicates to the code generator that the parameter or return value
|
||||
should be sign-extended to a 32-bit value by the caller (for a parameter)
|
||||
or the callee (for a return value).</dd>
|
||||
|
||||
<dt><tt>inreg</tt></dt>
|
||||
<dt><tt><b>inreg</b></tt></dt>
|
||||
<dd>This indicates that this parameter or return value should be treated in a
|
||||
special target-dependent fashion during while emitting code for a function
|
||||
call or return (usually, by putting it in a register as opposed to memory,
|
||||
though some targets use it to distinguish between two different kinds of
|
||||
registers). Use of this attribute is target-specific.</dd>
|
||||
|
||||
<dt><tt><a name="byval">byval</a></tt></dt>
|
||||
<dt><tt><b><a name="byval">byval</a></b></tt></dt>
|
||||
<dd>This indicates that the pointer parameter should really be passed by value
|
||||
to the function. The attribute implies that a hidden copy of the pointee
|
||||
is made between the caller and the callee, so the callee is unable to
|
||||
@ -967,7 +964,7 @@ declare signext i8 @returns_signed_char()
|
||||
generator that usually indicates a desired alignment for the synthesized
|
||||
stack slot.</dd>
|
||||
|
||||
<dt><tt>sret</tt></dt>
|
||||
<dt><tt><b>sret</b></tt></dt>
|
||||
<dd>This indicates that the pointer parameter specifies the address of a
|
||||
structure that is the return value of the function in the source program.
|
||||
This pointer must be guaranteed by the caller to be valid: loads and
|
||||
@ -975,7 +972,7 @@ declare signext i8 @returns_signed_char()
|
||||
may only be applied to the first parameter. This is not a valid attribute
|
||||
for return values. </dd>
|
||||
|
||||
<dt><tt>noalias</tt></dt>
|
||||
<dt><tt><b>noalias</b></tt></dt>
|
||||
<dd>This indicates that the pointer does not alias any global or any other
|
||||
parameter. The caller is responsible for ensuring that this is the
|
||||
case. On a function return value, <tt>noalias</tt> additionally indicates
|
||||
@ -985,12 +982,12 @@ declare signext i8 @returns_signed_char()
|
||||
<a href="http://llvm.org/docs/AliasAnalysis.html#MustMayNo">alias
|
||||
analysis</a>.</dd>
|
||||
|
||||
<dt><tt>nocapture</tt></dt>
|
||||
<dt><tt><b>nocapture</b></tt></dt>
|
||||
<dd>This indicates that the callee does not make any copies of the pointer
|
||||
that outlive the callee itself. This is not a valid attribute for return
|
||||
values.</dd>
|
||||
|
||||
<dt><tt>nest</tt></dt>
|
||||
<dt><tt><b>nest</b></tt></dt>
|
||||
<dd>This indicates that the pointer parameter can be excised using the
|
||||
<a href="#int_trampoline">trampoline intrinsics</a>. This is not a valid
|
||||
attribute for return values.</dd>
|
||||
@ -1010,7 +1007,7 @@ declare signext i8 @returns_signed_char()
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
define void @f() gc "name" { ...
|
||||
define void @f() gc "name" { ... }
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -1040,42 +1037,42 @@ define void @f() gc "name" { ...
|
||||
define void @f() noinline { ... }
|
||||
define void @f() alwaysinline { ... }
|
||||
define void @f() alwaysinline optsize { ... }
|
||||
define void @f() optsize
|
||||
define void @f() optsize { ... }
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<dl>
|
||||
<dt><tt>alwaysinline</tt></dt>
|
||||
<dt><tt><b>alwaysinline</b></tt></dt>
|
||||
<dd>This attribute indicates that the inliner should attempt to inline this
|
||||
function into callers whenever possible, ignoring any active inlining size
|
||||
threshold for this caller.</dd>
|
||||
|
||||
<dt><tt>inlinehint</tt></dt>
|
||||
<dt><tt><b>inlinehint</b></tt></dt>
|
||||
<dd>This attribute indicates that the source code contained a hint that inlining
|
||||
this function is desirable (such as the "inline" keyword in C/C++). It
|
||||
is just a hint; it imposes no requirements on the inliner.</dd>
|
||||
|
||||
<dt><tt>noinline</tt></dt>
|
||||
<dt><tt><b>noinline</b></tt></dt>
|
||||
<dd>This attribute indicates that the inliner should never inline this
|
||||
function in any situation. This attribute may not be used together with
|
||||
the <tt>alwaysinline</tt> attribute.</dd>
|
||||
|
||||
<dt><tt>optsize</tt></dt>
|
||||
<dt><tt><b>optsize</b></tt></dt>
|
||||
<dd>This attribute suggests that optimization passes and code generator passes
|
||||
make choices that keep the code size of this function low, and otherwise
|
||||
do optimizations specifically to reduce code size.</dd>
|
||||
|
||||
<dt><tt>noreturn</tt></dt>
|
||||
<dt><tt><b>noreturn</b></tt></dt>
|
||||
<dd>This function attribute indicates that the function never returns
|
||||
normally. This produces undefined behavior at runtime if the function
|
||||
ever does dynamically return.</dd>
|
||||
|
||||
<dt><tt>nounwind</tt></dt>
|
||||
<dt><tt><b>nounwind</b></tt></dt>
|
||||
<dd>This function attribute indicates that the function never returns with an
|
||||
unwind or exceptional control flow. If the function does unwind, its
|
||||
runtime behavior is undefined.</dd>
|
||||
|
||||
<dt><tt>readnone</tt></dt>
|
||||
<dt><tt><b>readnone</b></tt></dt>
|
||||
<dd>This attribute indicates that the function computes its result (or decides
|
||||
to unwind an exception) based strictly on its arguments, without
|
||||
dereferencing any pointer arguments or otherwise accessing any mutable
|
||||
@ -1086,7 +1083,7 @@ define void @f() optsize
|
||||
exceptions by calling the <tt>C++</tt> exception throwing methods, but
|
||||
could use the <tt>unwind</tt> instruction.</dd>
|
||||
|
||||
<dt><tt><a name="readonly">readonly</a></tt></dt>
|
||||
<dt><tt><b><a name="readonly">readonly</a></b></tt></dt>
|
||||
<dd>This attribute indicates that the function does not write through any
|
||||
pointer arguments (including <tt><a href="#byval">byval</a></tt>
|
||||
arguments) or otherwise modify any state (e.g. memory, control registers,
|
||||
@ -1097,7 +1094,7 @@ define void @f() optsize
|
||||
exception by calling the <tt>C++</tt> exception throwing methods, but may
|
||||
use the <tt>unwind</tt> instruction.</dd>
|
||||
|
||||
<dt><tt><a name="ssp">ssp</a></tt></dt>
|
||||
<dt><tt><b><a name="ssp">ssp</a></b></tt></dt>
|
||||
<dd>This attribute indicates that the function should emit a stack smashing
|
||||
protector. It is in the form of a "canary"—a random value placed on
|
||||
the stack before the local variables that's checked upon return from the
|
||||
@ -1108,7 +1105,7 @@ define void @f() optsize
|
||||
function that doesn't have an <tt>ssp</tt> attribute, then the resulting
|
||||
function will have an <tt>ssp</tt> attribute.</dd>
|
||||
|
||||
<dt><tt>sspreq</tt></dt>
|
||||
<dt><tt><b>sspreq</b></tt></dt>
|
||||
<dd>This attribute indicates that the function should <em>always</em> emit a
|
||||
stack smashing protector. This overrides
|
||||
the <tt><a href="#ssp">ssp</a></tt> function attribute.<br>
|
||||
@ -1118,14 +1115,14 @@ define void @f() optsize
|
||||
an <tt>ssp</tt> attribute, then the resulting function will have
|
||||
an <tt>sspreq</tt> attribute.</dd>
|
||||
|
||||
<dt><tt>noredzone</tt></dt>
|
||||
<dt><tt><b>noredzone</b></tt></dt>
|
||||
<dd>This attribute indicates that the code generator should not use a red
|
||||
zone, even if the target-specific ABI normally permits it.</dd>
|
||||
|
||||
<dt><tt>noimplicitfloat</tt></dt>
|
||||
<dt><tt><b>noimplicitfloat</b></tt></dt>
|
||||
<dd>This attributes disables implicit floating point instructions.</dd>
|
||||
|
||||
<dt><tt>naked</tt></dt>
|
||||
<dt><tt><b>naked</b></tt></dt>
|
||||
<dd>This attribute disables prologue / epilogue emission for the function.
|
||||
This can have very system-specific consequences.</dd>
|
||||
</dl>
|
||||
@ -2171,6 +2168,34 @@ has undefined behavior.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="blockaddress">Addresses of Basic
|
||||
Blocks</a></div>
|
||||
<div class="doc_text">
|
||||
|
||||
<p><b><tt>blockaddress(@function, %block)</tt></b></p>
|
||||
|
||||
<p>The '<tt>blockaddress</tt>' constant computes the address of the specified
|
||||
basic block in the specified function, and always has an i8* type. Taking
|
||||
the address of the entry block is illegal.</p>
|
||||
|
||||
<p>This value only has defined behavior when used as an operand to the
|
||||
'<a href="#i_indirectbr"><tt>indirectbr</tt></a>' instruction or for comparisons
|
||||
against null. Pointer equality tests between labels addresses is undefined
|
||||
behavior - though, again, comparison against null is ok, and no label is
|
||||
equal to the null pointer. This may also be passed around as an opaque
|
||||
pointer sized value as long as the bits are not inspected. This allows
|
||||
<tt>ptrtoint</tt> and arithmetic to be performed on these values so long as
|
||||
the original value is reconstituted before the <tt>indirectbr</tt>.</p>
|
||||
|
||||
<p>Finally, some targets may provide defined semantics when
|
||||
using the value as the operand to an inline assembly, but that is target
|
||||
specific.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="constantexprs">Constant Expressions</a>
|
||||
</div>
|
||||
@ -2513,6 +2538,7 @@ Instructions</a> </div>
|
||||
'<a href="#i_ret"><tt>ret</tt></a>' instruction, the
|
||||
'<a href="#i_br"><tt>br</tt></a>' instruction, the
|
||||
'<a href="#i_switch"><tt>switch</tt></a>' instruction, the
|
||||
'<a href="#i_indirectbr">'<tt>indirectbr</tt></a>' Instruction, the
|
||||
'<a href="#i_invoke"><tt>invoke</tt></a>' instruction, the
|
||||
'<a href="#i_unwind"><tt>unwind</tt></a>' instruction, and the
|
||||
'<a href="#i_unreachable"><tt>unreachable</tt></a>' instruction.</p>
|
||||
@ -2671,6 +2697,55 @@ IfUnequal:
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="i_indirectbr">'<tt>indirectbr</tt>' Instruction</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
indirectbr <somety>* <address>, [ label <dest1>, label <dest2>, ... ]
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
|
||||
<p>The '<tt>indirectbr</tt>' instruction implements an indirect branch to a label
|
||||
within the current function, whose address is specified by
|
||||
"<tt>address</tt>". Address must be derived from a <a
|
||||
href="#blockaddress">blockaddress</a> constant.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
|
||||
<p>The '<tt>address</tt>' argument is the address of the label to jump to. The
|
||||
rest of the arguments indicate the full set of possible destinations that the
|
||||
address may point to. Blocks are allowed to occur multiple times in the
|
||||
destination list, though this isn't particularly useful.</p>
|
||||
|
||||
<p>This destination list is required so that dataflow analysis has an accurate
|
||||
understanding of the CFG.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
|
||||
<p>Control transfers to the block specified in the address argument. All
|
||||
possible destination blocks must be listed in the label list, otherwise this
|
||||
instruction has undefined behavior. This implies that jumps to labels
|
||||
defined in other functions have undefined behavior as well.</p>
|
||||
|
||||
<h5>Implementation:</h5>
|
||||
|
||||
<p>This is typically implemented with a jump through a register.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
indirectbr i8* %Addr, [ label %bb1, label %bb2, label %bb3 ]
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="i_invoke">'<tt>invoke</tt>' Instruction</a>
|
||||
@ -3650,7 +3725,7 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%result = extractelement <4 x i32> %vec, i32 0 <i>; yields i32</i>
|
||||
<result> = extractelement <4 x i32> %vec, i32 0 <i>; yields i32</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -3686,7 +3761,7 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%result = insertelement <4 x i32> %vec, i32 1, i32 0 <i>; yields <4 x i32></i>
|
||||
<result> = insertelement <4 x i32> %vec, i32 1, i32 0 <i>; yields <4 x i32></i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -3727,13 +3802,13 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%result = shufflevector <4 x i32> %v1, <4 x i32> %v2,
|
||||
<result> = shufflevector <4 x i32> %v1, <4 x i32> %v2,
|
||||
<4 x i32> <i32 0, i32 4, i32 1, i32 5> <i>; yields <4 x i32></i>
|
||||
%result = shufflevector <4 x i32> %v1, <4 x i32> undef,
|
||||
<result> = shufflevector <4 x i32> %v1, <4 x i32> undef,
|
||||
<4 x i32> <i32 0, i32 1, i32 2, i32 3> <i>; yields <4 x i32></i> - Identity shuffle.
|
||||
%result = shufflevector <8 x i32> %v1, <8 x i32> undef,
|
||||
<result> = shufflevector <8 x i32> %v1, <8 x i32> undef,
|
||||
<4 x i32> <i32 0, i32 1, i32 2, i32 3> <i>; yields <4 x i32></i>
|
||||
%result = shufflevector <4 x i32> %v1, <4 x i32> %v2,
|
||||
<result> = shufflevector <4 x i32> %v1, <4 x i32> %v2,
|
||||
<8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 > <i>; yields <8 x i32></i>
|
||||
</pre>
|
||||
|
||||
@ -3779,7 +3854,7 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%result = extractvalue {i32, float} %agg, 0 <i>; yields i32</i>
|
||||
<result> = extractvalue {i32, float} %agg, 0 <i>; yields i32</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -3818,7 +3893,7 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%result = insertvalue {i32, float} %agg, i32 1, 0 <i>; yields {i32, float}</i>
|
||||
<result> = insertvalue {i32, float} %agg, i32 1, 0 <i>; yields {i32, float}</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -3833,93 +3908,11 @@ Instruction</a> </div>
|
||||
|
||||
<p>A key design point of an SSA-based representation is how it represents
|
||||
memory. In LLVM, no memory locations are in SSA form, which makes things
|
||||
very simple. This section describes how to read, write, allocate, and free
|
||||
very simple. This section describes how to read, write, and allocate
|
||||
memory in LLVM.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="i_malloc">'<tt>malloc</tt>' Instruction</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
<result> = malloc <type>[, i32 <NumElements>][, align <alignment>] <i>; yields {type*}:result</i>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>malloc</tt>' instruction allocates memory from the system heap and
|
||||
returns a pointer to it. The object is always allocated in the generic
|
||||
address space (address space zero).</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The '<tt>malloc</tt>' instruction allocates
|
||||
<tt>sizeof(<type>)*NumElements</tt> bytes of memory from the operating
|
||||
system and returns a pointer of the appropriate type to the program. If
|
||||
"NumElements" is specified, it is the number of elements allocated, otherwise
|
||||
"NumElements" is defaulted to be one. If a constant alignment is specified,
|
||||
the value result of the allocation is guaranteed to be aligned to at least
|
||||
that boundary. If not specified, or if zero, the target can choose to align
|
||||
the allocation on any convenient boundary compatible with the type.</p>
|
||||
|
||||
<p>'<tt>type</tt>' must be a sized type.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>Memory is allocated using the system "<tt>malloc</tt>" function, and a
|
||||
pointer is returned. The result of a zero byte allocation is undefined. The
|
||||
result is null if there is insufficient memory available.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%array = malloc [4 x i8] <i>; yields {[%4 x i8]*}:array</i>
|
||||
|
||||
%size = <a href="#i_add">add</a> i32 2, 2 <i>; yields {i32}:size = i32 4</i>
|
||||
%array1 = malloc i8, i32 4 <i>; yields {i8*}:array1</i>
|
||||
%array2 = malloc [12 x i8], i32 %size <i>; yields {[12 x i8]*}:array2</i>
|
||||
%array3 = malloc i32, i32 4, align 1024 <i>; yields {i32*}:array3</i>
|
||||
%array4 = malloc i32, align 1024 <i>; yields {i32*}:array4</i>
|
||||
</pre>
|
||||
|
||||
<p>Note that the code generator does not yet respect the alignment value.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="i_free">'<tt>free</tt>' Instruction</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
free <type> <value> <i>; yields {void}</i>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>free</tt>' instruction returns memory back to the unused memory heap
|
||||
to be reallocated in the future.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>'<tt>value</tt>' shall be a pointer value that points to a value that was
|
||||
allocated with the '<tt><a href="#i_malloc">malloc</a></tt>' instruction.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>Access to the memory pointed to by the pointer is no longer defined after
|
||||
this instruction executes. If the pointer is null, the operation is a
|
||||
noop.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%array = <a href="#i_malloc">malloc</a> [4 x i8] <i>; yields {[4 x i8]*}:array</i>
|
||||
free [4 x i8]* %array
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="i_alloca">'<tt>alloca</tt>' Instruction</a>
|
||||
@ -4253,7 +4246,7 @@ entry:
|
||||
<pre>
|
||||
%X = trunc i32 257 to i8 <i>; yields i8:1</i>
|
||||
%Y = trunc i32 123 to i1 <i>; yields i1:true</i>
|
||||
%Y = trunc i32 122 to i1 <i>; yields i1:false</i>
|
||||
%Z = trunc i32 122 to i1 <i>; yields i1:false</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -4437,7 +4430,7 @@ entry:
|
||||
<pre>
|
||||
%X = fptoui double 123.0 to i32 <i>; yields i32:123</i>
|
||||
%Y = fptoui float 1.0E+300 to i1 <i>; yields undefined:1</i>
|
||||
%X = fptoui float 1.04E+17 to i8 <i>; yields undefined:1</i>
|
||||
%Z = fptoui float 1.04E+17 to i8 <i>; yields undefined:1</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -4475,7 +4468,7 @@ entry:
|
||||
<pre>
|
||||
%X = fptosi double -123.0 to i32 <i>; yields i32:-123</i>
|
||||
%Y = fptosi float 1.0E-247 to i1 <i>; yields undefined:1</i>
|
||||
%X = fptosi float 1.04E+17 to i8 <i>; yields undefined:1</i>
|
||||
%Z = fptosi float 1.04E+17 to i8 <i>; yields undefined:1</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -4619,8 +4612,8 @@ entry:
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%X = inttoptr i32 255 to i32* <i>; yields zero extension on 64-bit architecture</i>
|
||||
%X = inttoptr i32 255 to i32* <i>; yields no-op on 32-bit architecture</i>
|
||||
%Y = inttoptr i64 0 to i32* <i>; yields truncation on 32-bit architecture</i>
|
||||
%Y = inttoptr i32 255 to i32* <i>; yields no-op on 32-bit architecture</i>
|
||||
%Z = inttoptr i64 0 to i32* <i>; yields truncation on 32-bit architecture</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -6624,7 +6617,8 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%ptr = malloc i32
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 4, %ptr
|
||||
|
||||
%result1 = load i32* %ptr <i>; yields {i32}:result1 = 4</i>
|
||||
@ -6675,7 +6669,8 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%ptr = malloc i32
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 4, %ptr
|
||||
|
||||
%val1 = add i32 4, 4
|
||||
@ -6730,7 +6725,8 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%ptr = malloc i32
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 4, %ptr
|
||||
|
||||
%val1 = add i32 4, 4
|
||||
@ -6785,8 +6781,9 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%ptr = malloc i32
|
||||
store i32 4, %ptr
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 4, %ptr
|
||||
%result1 = call i32 @llvm.atomic.load.add.i32.p0i32( i32* %ptr, i32 4 )
|
||||
<i>; yields {i32}:result1 = 4</i>
|
||||
%result2 = call i32 @llvm.atomic.load.add.i32.p0i32( i32* %ptr, i32 2 )
|
||||
@ -6836,8 +6833,9 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%ptr = malloc i32
|
||||
store i32 8, %ptr
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 8, %ptr
|
||||
%result1 = call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %ptr, i32 4 )
|
||||
<i>; yields {i32}:result1 = 8</i>
|
||||
%result2 = call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %ptr, i32 2 )
|
||||
@ -6913,8 +6911,9 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%ptr = malloc i32
|
||||
store i32 0x0F0F, %ptr
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 0x0F0F, %ptr
|
||||
%result0 = call i32 @llvm.atomic.load.nand.i32.p0i32( i32* %ptr, i32 0xFF )
|
||||
<i>; yields {i32}:result0 = 0x0F0F</i>
|
||||
%result1 = call i32 @llvm.atomic.load.and.i32.p0i32( i32* %ptr, i32 0xFF )
|
||||
@ -6991,8 +6990,9 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%ptr = malloc i32
|
||||
store i32 7, %ptr
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 7, %ptr
|
||||
%result0 = call i32 @llvm.atomic.load.min.i32.p0i32( i32* %ptr, i32 -2 )
|
||||
<i>; yields {i32}:result0 = 7</i>
|
||||
%result1 = call i32 @llvm.atomic.load.max.i32.p0i32( i32* %ptr, i32 8 )
|
||||
@ -7043,8 +7043,8 @@ LLVM</a>.</p>
|
||||
<h5>Semantics:</h5>
|
||||
<p>This intrinsic indicates that before this point in the code, the value of the
|
||||
memory pointed to by <tt>ptr</tt> is dead. This means that it is known to
|
||||
never be used and has an undefined value. A load from the pointer that is
|
||||
preceded by this intrinsic can be replaced with
|
||||
never be used and has an undefined value. A load from the pointer that
|
||||
precedes this intrinsic can be replaced with
|
||||
<tt>'<a href="#undefvalues">undef</a>'</tt>.</p>
|
||||
|
||||
</div>
|
||||
@ -7278,7 +7278,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-10-22 01:28:00 +0200 (Thu, 22 Oct 2009) $
|
||||
Last modified: $Date: 2009-11-02 01:25:26 +0100 (Mon, 02 Nov 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -158,7 +158,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
|
||||
<tr><td><a href="#memcpyopt">-memcpyopt</a></td><td>Optimize use of memcpy and friends</td></tr>
|
||||
<tr><td><a href="#mergereturn">-mergereturn</a></td><td>Unify function exit nodes</td></tr>
|
||||
<tr><td><a href="#prune-eh">-prune-eh</a></td><td>Remove unused exception handling info</td></tr>
|
||||
<tr><td><a href="#raiseallocs">-raiseallocs</a></td><td>Raise allocations from calls to instructions</td></tr>
|
||||
<tr><td><a href="#reassociate">-reassociate</a></td><td>Reassociate expressions</td></tr>
|
||||
<tr><td><a href="#reg2mem">-reg2mem</a></td><td>Demote all values to stack slots</td></tr>
|
||||
<tr><td><a href="#scalarrepl">-scalarrepl</a></td><td>Scalar Replacement of Aggregates</td></tr>
|
||||
@ -1502,17 +1501,6 @@ if (X < 3) {</pre>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-------------------------------------------------------------------------- -->
|
||||
<div class="doc_subsection">
|
||||
<a name="raiseallocs">Raise allocations from calls to instructions</a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>
|
||||
Converts <tt>@malloc</tt> and <tt>@free</tt> calls to <tt>malloc</tt> and
|
||||
<tt>free</tt> instructions.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-------------------------------------------------------------------------- -->
|
||||
<div class="doc_subsection">
|
||||
<a name="reassociate">Reassociate expressions</a>
|
||||
@ -1799,8 +1787,8 @@ if (X < 3) {</pre>
|
||||
integrals f.e.</li>
|
||||
<li>All of the constants in a switch statement are of the correct type.</li>
|
||||
<li>The code is in valid SSA form.</li>
|
||||
<li>It should be illegal to put a label into any other type (like a
|
||||
structure) or to return one. [except constant arrays!]</li>
|
||||
<li>It is illegal to put a label into any other type (like a structure) or
|
||||
to return one.</li>
|
||||
<li>Only phi nodes can be self referential: <tt>%x = add i32 %x, %x</tt> is
|
||||
invalid.</li>
|
||||
<li>PHI nodes must have an entry for each predecessor, with no extras.</li>
|
||||
@ -1860,7 +1848,7 @@ if (X < 3) {</pre>
|
||||
|
||||
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2009-10-28 05:47:06 +0100 (Wed, 28 Oct 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -1058,7 +1058,7 @@ there isn't already one.</p>
|
||||
|
||||
<li>LLVM will not correctly compile on Solaris and/or OpenSolaris
|
||||
using the stock GCC 3.x.x series 'out the box',
|
||||
See: <a href="#brokengcc">Broken versions of GCC and other tools</a>.
|
||||
See: <a href="GettingStarted.html#brokengcc">Broken versions of GCC and other tools</a>.
|
||||
However, A <a href="http://pkg.auroraux.org/GCC">Modern GCC Build</a>
|
||||
for x86/x86-64 has been made available from the third party AuroraUX Project
|
||||
that has been meticulously tested for bootstrapping LLVM & Clang.</li>
|
||||
@ -1348,7 +1348,7 @@ lists</a>.</p>
|
||||
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
||||
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-10-16 18:30:58 +0200 (Fri, 16 Oct 2009) $
|
||||
Last modified: $Date: 2009-11-03 22:50:09 +0100 (Tue, 03 Nov 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -151,7 +151,7 @@ file prints this (at the time of this writing):</p>
|
||||
<b>bit</b> isReMaterializable = 0;
|
||||
<b>bit</b> isPredicable = 0;
|
||||
<b>bit</b> hasDelaySlot = 0;
|
||||
<b>bit</b> usesCustomDAGSchedInserter = 0;
|
||||
<b>bit</b> usesCustomInserter = 0;
|
||||
<b>bit</b> hasCtrlDep = 0;
|
||||
<b>bit</b> isNotDuplicable = 0;
|
||||
<b>bit</b> hasSideEffects = 0;
|
||||
@ -794,7 +794,7 @@ This should highlight the APIs in <tt>TableGen/Record.h</tt>.</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-10-05 04:51:06 +0200 (Mon, 05 Oct 2009) $
|
||||
Last modified: $Date: 2009-10-29 19:10:34 +0100 (Thu, 29 Oct 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -388,24 +388,19 @@ entry:
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This illustrates that we can now call user code, but there is something a bit subtle
|
||||
going on here. Note that we only invoke the JIT on the anonymous functions
|
||||
that <em>call testfunc</em>, but we never invoked it on <em>testfunc
|
||||
</em>itself.</p>
|
||||
<p>This illustrates that we can now call user code, but there is something a bit
|
||||
subtle going on here. Note that we only invoke the JIT on the anonymous
|
||||
functions that <em>call testfunc</em>, but we never invoked it
|
||||
on <em>testfunc</em> itself. What actually happened here is that the JIT
|
||||
scanned for all non-JIT'd functions transitively called from the anonymous
|
||||
function and compiled all of them before returning
|
||||
from <tt>getPointerToFunction()</tt>.</p>
|
||||
|
||||
<p>What actually happened here is that the anonymous function was
|
||||
JIT'd when requested. When the Kaleidoscope app calls through the function
|
||||
pointer that is returned, the anonymous function starts executing. It ends up
|
||||
making the call to the "testfunc" function, and ends up in a stub that invokes
|
||||
the JIT, lazily, on testfunc. Once the JIT finishes lazily compiling testfunc,
|
||||
it returns and the code re-executes the call.</p>
|
||||
|
||||
<p>In summary, the JIT will lazily JIT code, on the fly, as it is needed. The
|
||||
JIT provides a number of other more advanced interfaces for things like freeing
|
||||
allocated machine code, rejit'ing functions to update them, etc. However, even
|
||||
with this simple code, we get some surprisingly powerful capabilities - check
|
||||
this out (I removed the dump of the anonymous functions, you should get the idea
|
||||
by now :) :</p>
|
||||
<p>The JIT provides a number of other more advanced interfaces for things like
|
||||
freeing allocated machine code, rejit'ing functions to update them, etc.
|
||||
However, even with this simple code, we get some surprisingly powerful
|
||||
capabilities - check this out (I removed the dump of the anonymous functions,
|
||||
you should get the idea by now :) :</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
@ -453,8 +448,8 @@ directly.</p>
|
||||
resolved. It allows you to establish explicit mappings between IR objects and
|
||||
addresses (useful for LLVM global variables that you want to map to static
|
||||
tables, for example), allows you to dynamically decide on the fly based on the
|
||||
function name, and even allows you to have the JIT abort itself if any lazy
|
||||
compilation is attempted.</p>
|
||||
function name, and even allows you to have the JIT compile functions lazily the
|
||||
first time they're called.</p>
|
||||
|
||||
<p>One interesting application of this is that we can now extend the language
|
||||
by writing arbitrary C++ code to implement operations. For example, if we add:
|
||||
|
@ -406,22 +406,17 @@ entry:
|
||||
|
||||
<p>This illustrates that we can now call user code, but there is something a bit
|
||||
subtle going on here. Note that we only invoke the JIT on the anonymous
|
||||
functions that <em>call testfunc</em>, but we never invoked it on <em>testfunc
|
||||
</em>itself.</p>
|
||||
functions that <em>call testfunc</em>, but we never invoked it
|
||||
on <em>testfunc</em> itself. What actually happened here is that the JIT
|
||||
scanned for all non-JIT'd functions transitively called from the anonymous
|
||||
function and compiled all of them before returning
|
||||
from <tt>run_function</tt>.</p>
|
||||
|
||||
<p>What actually happened here is that the anonymous function was JIT'd when
|
||||
requested. When the Kaleidoscope app calls through the function pointer that is
|
||||
returned, the anonymous function starts executing. It ends up making the call
|
||||
to the "testfunc" function, and ends up in a stub that invokes the JIT, lazily,
|
||||
on testfunc. Once the JIT finishes lazily compiling testfunc,
|
||||
it returns and the code re-executes the call.</p>
|
||||
|
||||
<p>In summary, the JIT will lazily JIT code, on the fly, as it is needed. The
|
||||
JIT provides a number of other more advanced interfaces for things like freeing
|
||||
allocated machine code, rejit'ing functions to update them, etc. However, even
|
||||
with this simple code, we get some surprisingly powerful capabilities - check
|
||||
this out (I removed the dump of the anonymous functions, you should get the idea
|
||||
by now :) :</p>
|
||||
<p>The JIT provides a number of other more advanced interfaces for things like
|
||||
freeing allocated machine code, rejit'ing functions to update them, etc.
|
||||
However, even with this simple code, we get some surprisingly powerful
|
||||
capabilities - check this out (I removed the dump of the anonymous functions,
|
||||
you should get the idea by now :) :</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
@ -467,8 +462,8 @@ calls in the module to call the libm version of <tt>sin</tt> directly.</p>
|
||||
get resolved. It allows you to establish explicit mappings between IR objects
|
||||
and addresses (useful for LLVM global variables that you want to map to static
|
||||
tables, for example), allows you to dynamically decide on the fly based on the
|
||||
function name, and even allows you to have the JIT abort itself if any lazy
|
||||
compilation is attempted.</p>
|
||||
function name, and even allows you to have the JIT compile functions lazily the
|
||||
first time they're called.</p>
|
||||
|
||||
<p>One interesting application of this is that we can now extend the language
|
||||
by writing arbitrary C code to implement operations. For example, if we add:
|
||||
|
@ -117,8 +117,8 @@ void BrainF::header(LLVMContext& C) {
|
||||
//brainf.end:
|
||||
endbb = BasicBlock::Create(C, label, brainf_func);
|
||||
|
||||
//free i8 *%arr
|
||||
new FreeInst(ptr_arr, endbb);
|
||||
//call free(i8 *%arr)
|
||||
endbb->getInstList().push_back(CallInst::CreateFree(ptr_arr, endbb));
|
||||
|
||||
//ret void
|
||||
ReturnInst::Create(C, endbb);
|
||||
|
@ -33,7 +33,7 @@
|
||||
#ifndef LLVM_C_CORE_H
|
||||
#define LLVM_C_CORE_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -455,8 +455,7 @@ void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle);
|
||||
macro(UnreachableInst) \
|
||||
macro(UnwindInst) \
|
||||
macro(UnaryInstruction) \
|
||||
macro(AllocationInst) \
|
||||
macro(AllocaInst) \
|
||||
macro(AllocaInst) \
|
||||
macro(CastInst) \
|
||||
macro(BitCastInst) \
|
||||
macro(FPExtInst) \
|
||||
@ -471,7 +470,6 @@ void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle);
|
||||
macro(UIToFPInst) \
|
||||
macro(ZExtInst) \
|
||||
macro(ExtractValueInst) \
|
||||
macro(FreeInst) \
|
||||
macro(LoadInst) \
|
||||
macro(VAArgInst)
|
||||
|
||||
|
@ -54,7 +54,7 @@ void LLVMAddLowerSetJmpPass(LLVMPassManagerRef PM);
|
||||
/** See llvm::createPruneEHPass function. */
|
||||
void LLVMAddPruneEHPass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createRaiseAllocationsPass function. */
|
||||
// FIXME: Remove in LLVM 3.0.
|
||||
void LLVMAddRaiseAllocationsPass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createStripDeadPrototypesPass function. */
|
||||
|
@ -454,12 +454,12 @@ class DenseMapIterator :
|
||||
return Ptr != RHS.Ptr;
|
||||
}
|
||||
|
||||
inline DenseMapIterator& operator++() { // Preincrement
|
||||
inline DenseMapIterator& operator++() { // Preincrement
|
||||
++Ptr;
|
||||
AdvancePastEmptyBuckets();
|
||||
return *this;
|
||||
}
|
||||
DenseMapIterator operator++(int) { // Postincrement
|
||||
DenseMapIterator operator++(int) { // Postincrement
|
||||
DenseMapIterator tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
|
||||
#define LLVM_ADT_EQUIVALENCECLASSES_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <set>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -16,7 +16,7 @@
|
||||
#ifndef LLVM_ADT_FOLDINGSET_H
|
||||
#define LLVM_ADT_FOLDINGSET_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/PointerLikeTypeTraits.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_ADT_STRINGEXTRAS_H
|
||||
#define LLVM_ADT_STRINGEXTRAS_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <cctype>
|
||||
|
83
include/llvm/ADT/StringSwitch.h
Normal file
83
include/llvm/ADT/StringSwitch.h
Normal file
@ -0,0 +1,83 @@
|
||||
//===--- StringSwitch.h - Switch-on-literal-string Construct --------------===/
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//===----------------------------------------------------------------------===/
|
||||
//
|
||||
// This file implements the StringSwitch template, which mimics a switch()
|
||||
// statements whose cases are string literals.
|
||||
//
|
||||
//===----------------------------------------------------------------------===/
|
||||
#ifndef LLVM_ADT_STRINGSWITCH_H
|
||||
#define LLVM_ADT_STRINGSWITCH_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// \brief A switch()-like statement whose cases are string literals.
|
||||
///
|
||||
/// The StringSwitch class is a simple form of a switch() statement that
|
||||
/// determines whether the given string matches one of the given string
|
||||
/// literals. The template type parameter \p T is the type of the value that
|
||||
/// will be returned from the string-switch expression. For example,
|
||||
/// the following code switches on the name of a color in \c argv[i]:
|
||||
///
|
||||
/// \code
|
||||
/// Color color = StringSwitch<Color>(argv[i])
|
||||
/// .Case("red", Red)
|
||||
/// .Case("orange", Orange)
|
||||
/// .Case("yellow", Yellow)
|
||||
/// .Case("green", Green)
|
||||
/// .Case("blue", Blue)
|
||||
/// .Case("indigo", Indigo)
|
||||
/// .Case("violet", Violet)
|
||||
/// .Default(UnknownColor);
|
||||
/// \endcode
|
||||
template<typename T>
|
||||
class StringSwitch {
|
||||
/// \brief The string we are matching.
|
||||
StringRef Str;
|
||||
|
||||
/// \brief The result of this switch statement, once known.
|
||||
T Result;
|
||||
|
||||
/// \brief Set true when the result of this switch is already known; in this
|
||||
/// case, Result is valid.
|
||||
bool ResultKnown;
|
||||
|
||||
public:
|
||||
explicit StringSwitch(StringRef Str)
|
||||
: Str(Str), ResultKnown(false) { }
|
||||
|
||||
template<unsigned N>
|
||||
StringSwitch& Case(const char (&S)[N], const T& Value) {
|
||||
if (!ResultKnown && N-1 == Str.size() &&
|
||||
(std::memcmp(S, Str.data(), N-1) == 0)) {
|
||||
Result = Value;
|
||||
ResultKnown = true;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
T Default(const T& Value) {
|
||||
if (ResultKnown)
|
||||
return Result;
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
operator T() {
|
||||
assert(ResultKnown && "Fell off the end of a string-switch");
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_ADT_STRINGSWITCH_H
|
@ -11,7 +11,7 @@
|
||||
#define LLVM_ADT_TWINE_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
|
@ -7,7 +7,19 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ValueMap class.
|
||||
// This file defines the ValueMap class. ValueMap maps Value* or any subclass
|
||||
// to an arbitrary other type. It provides the DenseMap interface but updates
|
||||
// itself to remain safe when keys are RAUWed or deleted. By default, when a
|
||||
// key is RAUWed from V1 to V2, the old mapping V1->target is removed, and a new
|
||||
// mapping V2->target is added. If V2 already existed, its old target is
|
||||
// overwritten. When a key is deleted, its mapping is removed.
|
||||
//
|
||||
// You can override a ValueMap's Config parameter to control exactly what
|
||||
// happens on RAUW and destruction and to get called back on each event. It's
|
||||
// legal to call back into the ValueMap from a Config's callbacks. Config
|
||||
// parameters should inherit from ValueMapConfig<KeyT> to get default
|
||||
// implementations of all the methods ValueMap uses. See ValueMapConfig for
|
||||
// documentation of the functions you can override.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -31,6 +43,9 @@ class ValueMapIterator;
|
||||
template<typename DenseMapT, typename KeyT>
|
||||
class ValueMapConstIterator;
|
||||
|
||||
/// This class defines the default behavior for configurable aspects of
|
||||
/// ValueMap<>. User Configs should inherit from this class to be as compatible
|
||||
/// as possible with future versions of ValueMap.
|
||||
template<typename KeyT>
|
||||
struct ValueMapConfig {
|
||||
/// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
|
||||
@ -46,27 +61,17 @@ struct ValueMapConfig {
|
||||
template<typename ExtraDataT>
|
||||
static void onRAUW(const ExtraDataT &Data, KeyT Old, KeyT New) {}
|
||||
template<typename ExtraDataT>
|
||||
static void onDeleted(const ExtraDataT &Data, KeyT Old) {}
|
||||
static void onDelete(const ExtraDataT &Data, KeyT Old) {}
|
||||
|
||||
/// Returns a mutex that should be acquired around any changes to the map.
|
||||
/// This is only acquired from the CallbackVH (and held around calls to onRAUW
|
||||
/// and onDeleted) and not inside other ValueMap methods. NULL means that no
|
||||
/// and onDelete) and not inside other ValueMap methods. NULL means that no
|
||||
/// mutex is necessary.
|
||||
template<typename ExtraDataT>
|
||||
static sys::Mutex *getMutex(const ExtraDataT &Data) { return NULL; }
|
||||
};
|
||||
|
||||
/// ValueMap maps Value* or any subclass to an arbitrary other
|
||||
/// type. It provides the DenseMap interface. When the key values are
|
||||
/// deleted or RAUWed, ValueMap relies on the Config to decide what to
|
||||
/// do. Config parameters should inherit from ValueMapConfig<KeyT> to
|
||||
/// get default implementations of all the methods ValueMap uses.
|
||||
///
|
||||
/// By default, when a key is RAUWed from V1 to V2, the old mapping
|
||||
/// V1->target is removed, and a new mapping V2->target is added. If
|
||||
/// V2 already existed, its old target is overwritten. When a key is
|
||||
/// deleted, its mapping is removed. You can override Config to get
|
||||
/// called back on each event.
|
||||
/// See the file comment.
|
||||
template<typename KeyT, typename ValueT, typename Config = ValueMapConfig<KeyT>,
|
||||
typename ValueInfoT = DenseMapInfo<ValueT> >
|
||||
class ValueMap {
|
||||
@ -177,6 +182,9 @@ class ValueMap {
|
||||
}
|
||||
|
||||
private:
|
||||
// Takes a key being looked up in the map and wraps it into a
|
||||
// ValueMapCallbackVH, the actual key type of the map. We use a helper
|
||||
// function because ValueMapCVH is constructed with a second parameter.
|
||||
ValueMapCVH Wrap(KeyT key) const {
|
||||
// The only way the resulting CallbackVH could try to modify *this (making
|
||||
// the const_cast incorrect) is if it gets inserted into the map. But then
|
||||
@ -186,10 +194,12 @@ class ValueMap {
|
||||
}
|
||||
};
|
||||
|
||||
// This CallbackVH updates its ValueMap when the contained Value changes,
|
||||
// according to the user's preferences expressed through the Config object.
|
||||
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
|
||||
class ValueMapCallbackVH : public CallbackVH {
|
||||
friend class ValueMap<KeyT, ValueT, Config, ValueInfoT>;
|
||||
friend class DenseMapInfo<ValueMapCallbackVH>;
|
||||
friend struct DenseMapInfo<ValueMapCallbackVH>;
|
||||
typedef ValueMap<KeyT, ValueT, Config, ValueInfoT> ValueMapT;
|
||||
typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT;
|
||||
|
||||
@ -208,7 +218,7 @@ class ValueMapCallbackVH : public CallbackVH {
|
||||
sys::Mutex *M = Config::getMutex(Copy.Map->Data);
|
||||
if (M)
|
||||
M->acquire();
|
||||
Config::onDeleted(Copy.Map->Data, Copy.Unwrap()); // May destroy *this.
|
||||
Config::onDelete(Copy.Map->Data, Copy.Unwrap()); // May destroy *this.
|
||||
Copy.Map->Map.erase(Copy); // Definitely destroys *this.
|
||||
if (M)
|
||||
M->release();
|
||||
@ -279,7 +289,7 @@ class ValueMapIterator :
|
||||
struct ValueTypeProxy {
|
||||
const KeyT first;
|
||||
ValueT& second;
|
||||
ValueTypeProxy *operator->() { return this; }
|
||||
ValueTypeProxy *operator->() { return this; }
|
||||
operator std::pair<KeyT, ValueT>() const {
|
||||
return std::make_pair(first, second);
|
||||
}
|
||||
@ -301,11 +311,11 @@ class ValueMapIterator :
|
||||
return I != RHS.I;
|
||||
}
|
||||
|
||||
inline ValueMapIterator& operator++() { // Preincrement
|
||||
inline ValueMapIterator& operator++() { // Preincrement
|
||||
++I;
|
||||
return *this;
|
||||
}
|
||||
ValueMapIterator operator++(int) { // Postincrement
|
||||
ValueMapIterator operator++(int) { // Postincrement
|
||||
ValueMapIterator tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
};
|
||||
@ -329,7 +339,7 @@ class ValueMapConstIterator :
|
||||
struct ValueTypeProxy {
|
||||
const KeyT first;
|
||||
const ValueT& second;
|
||||
ValueTypeProxy *operator->() { return this; }
|
||||
ValueTypeProxy *operator->() { return this; }
|
||||
operator std::pair<KeyT, ValueT>() const {
|
||||
return std::make_pair(first, second);
|
||||
}
|
||||
@ -351,11 +361,11 @@ class ValueMapConstIterator :
|
||||
return I != RHS.I;
|
||||
}
|
||||
|
||||
inline ValueMapConstIterator& operator++() { // Preincrement
|
||||
inline ValueMapConstIterator& operator++() { // Preincrement
|
||||
++I;
|
||||
return *this;
|
||||
}
|
||||
ValueMapConstIterator operator++(int) { // Postincrement
|
||||
ValueMapConstIterator operator++(int) { // Postincrement
|
||||
ValueMapConstIterator tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
};
|
||||
|
@ -29,7 +29,6 @@ namespace llvm {
|
||||
class AliasAnalysis;
|
||||
class LoadInst;
|
||||
class StoreInst;
|
||||
class FreeInst;
|
||||
class VAArgInst;
|
||||
class AliasSetTracker;
|
||||
class AliasSet;
|
||||
@ -298,7 +297,6 @@ class AliasSetTracker {
|
||||
bool add(Value *Ptr, unsigned Size); // Add a location
|
||||
bool add(LoadInst *LI);
|
||||
bool add(StoreInst *SI);
|
||||
bool add(FreeInst *FI);
|
||||
bool add(VAArgInst *VAAI);
|
||||
bool add(CallSite CS); // Call/Invoke instructions
|
||||
bool add(CallInst *CI) { return add(CallSite(CI)); }
|
||||
@ -313,7 +311,6 @@ class AliasSetTracker {
|
||||
bool remove(Value *Ptr, unsigned Size); // Remove a location
|
||||
bool remove(LoadInst *LI);
|
||||
bool remove(StoreInst *SI);
|
||||
bool remove(FreeInst *FI);
|
||||
bool remove(VAArgInst *VAAI);
|
||||
bool remove(CallSite CS);
|
||||
bool remove(CallInst *CI) { return remove(CallSite(CI)); }
|
||||
|
@ -514,6 +514,13 @@ namespace llvm {
|
||||
uint64_t OffsetInBits, unsigned Flags,
|
||||
unsigned Encoding);
|
||||
|
||||
/// CreateBasicType - Create a basic type like int, float, etc.
|
||||
DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
|
||||
DICompileUnit CompileUnit, unsigned LineNumber,
|
||||
Constant *SizeInBits, Constant *AlignInBits,
|
||||
Constant *OffsetInBits, unsigned Flags,
|
||||
unsigned Encoding);
|
||||
|
||||
/// CreateDerivedType - Create a derived type like const qualified type,
|
||||
/// pointer, typedef, etc.
|
||||
DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
|
||||
@ -524,6 +531,16 @@ namespace llvm {
|
||||
uint64_t OffsetInBits, unsigned Flags,
|
||||
DIType DerivedFrom);
|
||||
|
||||
/// CreateDerivedType - Create a derived type like const qualified type,
|
||||
/// pointer, typedef, etc.
|
||||
DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
Constant *SizeInBits, Constant *AlignInBits,
|
||||
Constant *OffsetInBits, unsigned Flags,
|
||||
DIType DerivedFrom);
|
||||
|
||||
/// CreateCompositeType - Create a composite type like array, struct, etc.
|
||||
DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
|
||||
StringRef Name,
|
||||
@ -536,6 +553,18 @@ namespace llvm {
|
||||
DIArray Elements,
|
||||
unsigned RunTimeLang = 0);
|
||||
|
||||
/// CreateCompositeType - Create a composite type like array, struct, etc.
|
||||
DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
|
||||
StringRef Name,
|
||||
DICompileUnit CompileUnit,
|
||||
unsigned LineNumber,
|
||||
Constant *SizeInBits,
|
||||
Constant *AlignInBits,
|
||||
Constant *OffsetInBits, unsigned Flags,
|
||||
DIType DerivedFrom,
|
||||
DIArray Elements,
|
||||
unsigned RunTimeLang = 0);
|
||||
|
||||
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
|
||||
/// See comments in DISubprogram for descriptions of these fields.
|
||||
DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
|
||||
|
@ -905,9 +905,9 @@ class DominanceFrontierBase : public FunctionPass {
|
||||
iterator find(BasicBlock *B) { return Frontiers.find(B); }
|
||||
const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
|
||||
|
||||
void addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
|
||||
iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
|
||||
assert(find(BB) == end() && "Block already in DominanceFrontier!");
|
||||
Frontiers.insert(std::make_pair(BB, frontier));
|
||||
return Frontiers.insert(std::make_pair(BB, frontier)).first;
|
||||
}
|
||||
|
||||
/// removeBlock - Remove basic block BB's frontier.
|
||||
|
@ -114,10 +114,10 @@ class LoopBase {
|
||||
block_iterator block_begin() const { return Blocks.begin(); }
|
||||
block_iterator block_end() const { return Blocks.end(); }
|
||||
|
||||
/// isLoopExit - True if terminator in the block can branch to another block
|
||||
/// isLoopExiting - True if terminator in the block can branch to another block
|
||||
/// that is outside of the current loop.
|
||||
///
|
||||
bool isLoopExit(const BlockT *BB) const {
|
||||
bool isLoopExiting(const BlockT *BB) const {
|
||||
typedef GraphTraits<BlockT*> BlockTraits;
|
||||
for (typename BlockTraits::ChildIteratorType SI =
|
||||
BlockTraits::child_begin(const_cast<BlockT*>(BB)),
|
||||
@ -465,7 +465,7 @@ class LoopBase {
|
||||
WriteAsOperand(OS, BB, false);
|
||||
if (BB == getHeader()) OS << "<header>";
|
||||
if (BB == getLoopLatch()) OS << "<latch>";
|
||||
if (isLoopExit(BB)) OS << "<exit>";
|
||||
if (isLoopExiting(BB)) OS << "<exiting>";
|
||||
}
|
||||
OS << "\n";
|
||||
|
||||
|
79
include/llvm/Analysis/MemoryBuiltins.h
Normal file
79
include/llvm/Analysis/MemoryBuiltins.h
Normal file
@ -0,0 +1,79 @@
|
||||
//===- llvm/Analysis/MemoryBuiltins.h- Calls to memory builtins -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This family of functions identifies calls to builtin functions that allocate
|
||||
// or free memory.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
|
||||
#define LLVM_ANALYSIS_MEMORYBUILTINS_H
|
||||
|
||||
namespace llvm {
|
||||
class CallInst;
|
||||
class LLVMContext;
|
||||
class PointerType;
|
||||
class TargetData;
|
||||
class Type;
|
||||
class Value;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// malloc Call Utility Functions.
|
||||
//
|
||||
|
||||
/// isMalloc - Returns true if the value is either a malloc call or a bitcast of
|
||||
/// the result of a malloc call
|
||||
bool isMalloc(const Value* I);
|
||||
|
||||
/// extractMallocCall - Returns the corresponding CallInst if the instruction
|
||||
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
|
||||
/// ignore InvokeInst here.
|
||||
const CallInst* extractMallocCall(const Value* I);
|
||||
CallInst* extractMallocCall(Value* I);
|
||||
|
||||
/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the
|
||||
/// instruction is a bitcast of the result of a malloc call.
|
||||
const CallInst* extractMallocCallFromBitCast(const Value* I);
|
||||
CallInst* extractMallocCallFromBitCast(Value* I);
|
||||
|
||||
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
|
||||
/// is a call to malloc whose array size can be determined and the array size
|
||||
/// is not constant 1. Otherwise, return NULL.
|
||||
CallInst* isArrayMalloc(Value* I, LLVMContext &Context, const TargetData* TD);
|
||||
const CallInst* isArrayMalloc(const Value* I, LLVMContext &Context,
|
||||
const TargetData* TD);
|
||||
|
||||
/// getMallocType - Returns the PointerType resulting from the malloc call.
|
||||
/// This PointerType is the result type of the call's only bitcast use.
|
||||
/// If there is no unique bitcast use, then return NULL.
|
||||
const PointerType* getMallocType(const CallInst* CI);
|
||||
|
||||
/// getMallocAllocatedType - Returns the Type allocated by malloc call. This
|
||||
/// Type is the result type of the call's only bitcast use. If there is no
|
||||
/// unique bitcast use, then return NULL.
|
||||
const Type* getMallocAllocatedType(const CallInst* CI);
|
||||
|
||||
/// getMallocArraySize - Returns the array size of a malloc call. If the
|
||||
/// argument passed to malloc is a multiple of the size of the malloced type,
|
||||
/// then return that multiple. For non-array mallocs, the multiple is
|
||||
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
|
||||
/// determined.
|
||||
Value* getMallocArraySize(CallInst* CI, LLVMContext &Context,
|
||||
const TargetData* TD);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// free Call Utility Functions.
|
||||
//
|
||||
|
||||
/// isFreeCall - Returns true if the the value is a call to the builtin free()
|
||||
bool isFreeCall(const Value* I);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -24,7 +24,7 @@
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/ConstantRange.h"
|
||||
@ -563,11 +563,10 @@ namespace llvm {
|
||||
/// has an analyzable loop-invariant backedge-taken count.
|
||||
bool hasLoopInvariantBackedgeTakenCount(const Loop *L);
|
||||
|
||||
/// forgetLoopBackedgeTakenCount - This method should be called by the
|
||||
/// client when it has changed a loop in a way that may effect
|
||||
/// ScalarEvolution's ability to compute a trip count, or if the loop
|
||||
/// is deleted.
|
||||
void forgetLoopBackedgeTakenCount(const Loop *L);
|
||||
/// forgetLoop - This method should be called by the client when it has
|
||||
/// changed a loop in a way that may effect ScalarEvolution's ability to
|
||||
/// compute a trip count, or if the loop is deleted.
|
||||
void forgetLoop(const Loop *L);
|
||||
|
||||
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S
|
||||
/// is guaranteed to end in (at every loop iteration). It is, at the same
|
||||
|
@ -15,7 +15,7 @@
|
||||
#ifndef LLVM_ANALYSIS_VALUETRACKING_H
|
||||
#define LLVM_ANALYSIS_VALUETRACKING_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -17,12 +17,13 @@
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/SymbolTableListTraits.h"
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TerminatorInst;
|
||||
class LLVMContext;
|
||||
class BlockAddress;
|
||||
|
||||
template<> struct ilist_traits<Instruction>
|
||||
: public SymbolTableListTraits<Instruction, BasicBlock> {
|
||||
@ -66,7 +67,7 @@ template<> struct ilist_traits<Instruction>
|
||||
/// @brief LLVM Basic Block Representation
|
||||
class BasicBlock : public Value, // Basic blocks are data objects also
|
||||
public ilist_node<BasicBlock> {
|
||||
|
||||
friend class BlockAddress;
|
||||
public:
|
||||
typedef iplist<Instruction> InstListType;
|
||||
private:
|
||||
@ -108,10 +109,10 @@ class BasicBlock : public Value, // Basic blocks are data objects also
|
||||
Function *getParent() { return Parent; }
|
||||
|
||||
/// use_back - Specialize the methods defined in Value, as we know that an
|
||||
/// BasicBlock can only be used by Instructions (specifically PHI nodes and
|
||||
/// terminators).
|
||||
Instruction *use_back() { return cast<Instruction>(*use_begin());}
|
||||
const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
|
||||
/// BasicBlock can only be used by Users (specifically PHI nodes, terminators,
|
||||
/// and BlockAddress's).
|
||||
User *use_back() { return cast<User>(*use_begin());}
|
||||
const User *use_back() const { return cast<User>(*use_begin());}
|
||||
|
||||
/// getTerminator() - If this is a well formed basic block, then this returns
|
||||
/// a pointer to the terminator instruction. If it is not, then you get a
|
||||
@ -235,6 +236,19 @@ class BasicBlock : public Value, // Basic blocks are data objects also
|
||||
/// keeping loop information consistent, use the SplitBlock utility function.
|
||||
///
|
||||
BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "");
|
||||
|
||||
/// hasAddressTaken - returns true if there are any uses of this basic block
|
||||
/// other than direct branches, switches, etc. to it.
|
||||
bool hasAddressTaken() const { return SubclassData != 0; }
|
||||
|
||||
private:
|
||||
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
|
||||
/// objects using it. This is almost always 0, sometimes one, possibly but
|
||||
/// almost never 2, and inconceivably 3 or more.
|
||||
void AdjustBlockAddressRefCount(int Amt) {
|
||||
SubclassData += Amt;
|
||||
assert((int)(char)SubclassData >= 0 && "Refcount wrap-around");
|
||||
}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define LLVM_BITCODE_BITCODES_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -138,7 +138,8 @@ namespace bitc {
|
||||
CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred]
|
||||
CST_CODE_INLINEASM = 18, // INLINEASM: [sideeffect,asmstr,conststr]
|
||||
CST_CODE_CE_SHUFVEC_EX = 19, // SHUFVEC_EX: [opty, opval, opval, opval]
|
||||
CST_CODE_CE_INBOUNDS_GEP = 20 // INBOUNDS_GEP: [n x operands]
|
||||
CST_CODE_CE_INBOUNDS_GEP = 20,// INBOUNDS_GEP: [n x operands]
|
||||
CST_CODE_BLOCKADDRESS = 21 // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#]
|
||||
};
|
||||
|
||||
/// CastOpcodes - These are values used in the bitcode files to encode which
|
||||
@ -209,7 +210,7 @@ namespace bitc {
|
||||
|
||||
FUNC_CODE_INST_RET = 10, // RET: [opty,opval<both optional>]
|
||||
FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#]
|
||||
FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, opval, n, n x ops]
|
||||
FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, op0, op1, ...]
|
||||
FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...]
|
||||
FUNC_CODE_INST_UNWIND = 14, // UNWIND
|
||||
FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
|
||||
@ -236,7 +237,8 @@ namespace bitc {
|
||||
FUNC_CODE_INST_CMP2 = 28, // CMP2: [opty, opval, opval, pred]
|
||||
// new select on i1 or [N x i1]
|
||||
FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred]
|
||||
FUNC_CODE_INST_INBOUNDS_GEP = 30 // INBOUNDS_GEP: [n x operands]
|
||||
FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands]
|
||||
FUNC_CODE_INST_INDIRECTBR = 31 // INDIRECTBR: [opty, op0, op1, ...]
|
||||
};
|
||||
} // End bitc namespace
|
||||
} // End llvm namespace
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace llvm {
|
||||
class BlockAddress;
|
||||
class GCStrategy;
|
||||
class Constant;
|
||||
class ConstantArray;
|
||||
@ -334,6 +335,12 @@ namespace llvm {
|
||||
/// block label.
|
||||
MCSymbol *GetMBBSymbol(unsigned MBBID) const;
|
||||
|
||||
/// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress
|
||||
/// uses of the specified basic block.
|
||||
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
|
||||
MCSymbol *GetBlockAddressSymbol(const Function *F,
|
||||
const BasicBlock *BB) const;
|
||||
|
||||
/// EmitBasicBlockStart - This method prints the label for the specified
|
||||
/// MachineBasicBlock, an alignment (if present) and a comment describing
|
||||
/// it if appropriate.
|
||||
|
@ -15,7 +15,7 @@
|
||||
#ifndef LLVM_CODEGEN_BINARYOBJECT_H
|
||||
#define LLVM_CODEGEN_BINARYOBJECT_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_CODEGEN_ELF_RELOCATION_H
|
||||
#define LLVM_CODEGEN_ELF_RELOCATION_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define LLVM_CODEGEN_JITCODEEMITTER_H
|
||||
|
||||
#include <string>
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/CodeGen/MachineCodeEmitter.h"
|
||||
|
||||
|
@ -39,12 +39,21 @@ namespace llvm {
|
||||
/// predecessor for. This is used as a tie-breaker heuristic for better
|
||||
/// mobility.
|
||||
std::vector<unsigned> NumNodesSolelyBlocking;
|
||||
|
||||
PriorityQueue<SUnit*, std::vector<SUnit*>, latency_sort> Queue;
|
||||
public:
|
||||
LatencyPriorityQueue() : Queue(latency_sort(this)) {
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
void initNodes(std::vector<SUnit> &sunits) {
|
||||
SUnits = &sunits;
|
||||
NumNodesSolelyBlocking.resize(SUnits->size(), 0);
|
||||
@ -63,7 +72,7 @@ namespace llvm {
|
||||
|
||||
unsigned getLatency(unsigned NodeNum) const {
|
||||
assert(NodeNum < (*SUnits).size());
|
||||
return (*SUnits)[NodeNum].getHeight();
|
||||
return (*SUnits)[NodeNum].getHeight(IgnoreAntiDep);
|
||||
}
|
||||
|
||||
unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
|
||||
|
@ -21,221 +21,19 @@
|
||||
#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
|
||||
#define LLVM_CODEGEN_LIVEINTERVAL_H
|
||||
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/CodeGen/SlotIndexes.h"
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
|
||||
namespace llvm {
|
||||
class LiveIntervals;
|
||||
class MachineInstr;
|
||||
class MachineRegisterInfo;
|
||||
class TargetRegisterInfo;
|
||||
class raw_ostream;
|
||||
|
||||
/// LiveIndex - An opaque wrapper around machine indexes.
|
||||
class LiveIndex {
|
||||
friend class VNInfo;
|
||||
friend class LiveInterval;
|
||||
friend class LiveIntervals;
|
||||
friend struct DenseMapInfo<LiveIndex>;
|
||||
|
||||
public:
|
||||
|
||||
enum Slot { LOAD, USE, DEF, STORE, NUM };
|
||||
|
||||
private:
|
||||
|
||||
unsigned index;
|
||||
|
||||
static const unsigned PHI_BIT = 1 << 31;
|
||||
|
||||
public:
|
||||
|
||||
/// Construct a default LiveIndex pointing to a reserved index.
|
||||
LiveIndex() : index(0) {}
|
||||
|
||||
/// Construct an index from the given index, pointing to the given slot.
|
||||
LiveIndex(LiveIndex m, Slot s)
|
||||
: index((m.index / NUM) * NUM + s) {}
|
||||
|
||||
/// Print this index to the given raw_ostream.
|
||||
void print(raw_ostream &os) const;
|
||||
|
||||
/// Compare two LiveIndex objects for equality.
|
||||
bool operator==(LiveIndex other) const {
|
||||
return ((index & ~PHI_BIT) == (other.index & ~PHI_BIT));
|
||||
}
|
||||
/// Compare two LiveIndex objects for inequality.
|
||||
bool operator!=(LiveIndex other) const {
|
||||
return ((index & ~PHI_BIT) != (other.index & ~PHI_BIT));
|
||||
}
|
||||
|
||||
/// Compare two LiveIndex objects. Return true if the first index
|
||||
/// is strictly lower than the second.
|
||||
bool operator<(LiveIndex other) const {
|
||||
return ((index & ~PHI_BIT) < (other.index & ~PHI_BIT));
|
||||
}
|
||||
/// Compare two LiveIndex objects. Return true if the first index
|
||||
/// is lower than, or equal to, the second.
|
||||
bool operator<=(LiveIndex other) const {
|
||||
return ((index & ~PHI_BIT) <= (other.index & ~PHI_BIT));
|
||||
}
|
||||
|
||||
/// Compare two LiveIndex objects. Return true if the first index
|
||||
/// is greater than the second.
|
||||
bool operator>(LiveIndex other) const {
|
||||
return ((index & ~PHI_BIT) > (other.index & ~PHI_BIT));
|
||||
}
|
||||
|
||||
/// Compare two LiveIndex objects. Return true if the first index
|
||||
/// is greater than, or equal to, the second.
|
||||
bool operator>=(LiveIndex other) const {
|
||||
return ((index & ~PHI_BIT) >= (other.index & ~PHI_BIT));
|
||||
}
|
||||
|
||||
/// Returns true if this index represents a load.
|
||||
bool isLoad() const {
|
||||
return ((index % NUM) == LOAD);
|
||||
}
|
||||
|
||||
/// Returns true if this index represents a use.
|
||||
bool isUse() const {
|
||||
return ((index % NUM) == USE);
|
||||
}
|
||||
|
||||
/// Returns true if this index represents a def.
|
||||
bool isDef() const {
|
||||
return ((index % NUM) == DEF);
|
||||
}
|
||||
|
||||
/// Returns true if this index represents a store.
|
||||
bool isStore() const {
|
||||
return ((index % NUM) == STORE);
|
||||
}
|
||||
|
||||
/// Returns the slot for this LiveIndex.
|
||||
Slot getSlot() const {
|
||||
return static_cast<Slot>(index % NUM);
|
||||
}
|
||||
|
||||
/// Returns true if this index represents a non-PHI use/def.
|
||||
bool isNonPHIIndex() const {
|
||||
return ((index & PHI_BIT) == 0);
|
||||
}
|
||||
|
||||
/// Returns true if this index represents a PHI use/def.
|
||||
bool isPHIIndex() const {
|
||||
return ((index & PHI_BIT) == PHI_BIT);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// Construct an index from the given index, with its PHI kill marker set.
|
||||
LiveIndex(bool phi, LiveIndex o) : index(o.index) {
|
||||
if (phi)
|
||||
index |= PHI_BIT;
|
||||
else
|
||||
index &= ~PHI_BIT;
|
||||
}
|
||||
|
||||
explicit LiveIndex(unsigned idx)
|
||||
: index(idx & ~PHI_BIT) {}
|
||||
|
||||
LiveIndex(bool phi, unsigned idx)
|
||||
: index(idx & ~PHI_BIT) {
|
||||
if (phi)
|
||||
index |= PHI_BIT;
|
||||
}
|
||||
|
||||
LiveIndex(bool phi, unsigned idx, Slot slot)
|
||||
: index(((idx / NUM) * NUM + slot) & ~PHI_BIT) {
|
||||
if (phi)
|
||||
index |= PHI_BIT;
|
||||
}
|
||||
|
||||
LiveIndex nextSlot_() const {
|
||||
assert((index & PHI_BIT) == ((index + 1) & PHI_BIT) &&
|
||||
"Index out of bounds.");
|
||||
return LiveIndex(index + 1);
|
||||
}
|
||||
|
||||
LiveIndex nextIndex_() const {
|
||||
assert((index & PHI_BIT) == ((index + NUM) & PHI_BIT) &&
|
||||
"Index out of bounds.");
|
||||
return LiveIndex(index + NUM);
|
||||
}
|
||||
|
||||
LiveIndex prevSlot_() const {
|
||||
assert((index & PHI_BIT) == ((index - 1) & PHI_BIT) &&
|
||||
"Index out of bounds.");
|
||||
return LiveIndex(index - 1);
|
||||
}
|
||||
|
||||
LiveIndex prevIndex_() const {
|
||||
assert((index & PHI_BIT) == ((index - NUM) & PHI_BIT) &&
|
||||
"Index out of bounds.");
|
||||
return LiveIndex(index - NUM);
|
||||
}
|
||||
|
||||
int distance(LiveIndex other) const {
|
||||
return (other.index & ~PHI_BIT) - (index & ~PHI_BIT);
|
||||
}
|
||||
|
||||
/// Returns an unsigned number suitable as an index into a
|
||||
/// vector over all instructions.
|
||||
unsigned getVecIndex() const {
|
||||
return (index & ~PHI_BIT) / NUM;
|
||||
}
|
||||
|
||||
/// Scale this index by the given factor.
|
||||
LiveIndex scale(unsigned factor) const {
|
||||
unsigned i = (index & ~PHI_BIT) / NUM,
|
||||
o = (index % ~PHI_BIT) % NUM;
|
||||
assert(index <= (~0U & ~PHI_BIT) / (factor * NUM) &&
|
||||
"Rescaled interval would overflow");
|
||||
return LiveIndex(i * NUM * factor, o);
|
||||
}
|
||||
|
||||
static LiveIndex emptyKey() {
|
||||
return LiveIndex(true, 0x7fffffff);
|
||||
}
|
||||
|
||||
static LiveIndex tombstoneKey() {
|
||||
return LiveIndex(true, 0x7ffffffe);
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const LiveIndex &v) {
|
||||
return v.index * 37;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline raw_ostream& operator<<(raw_ostream &os, LiveIndex mi) {
|
||||
mi.print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
/// Densemap specialization for LiveIndex.
|
||||
template <>
|
||||
struct DenseMapInfo<LiveIndex> {
|
||||
static inline LiveIndex getEmptyKey() {
|
||||
return LiveIndex::emptyKey();
|
||||
}
|
||||
static inline LiveIndex getTombstoneKey() {
|
||||
return LiveIndex::tombstoneKey();
|
||||
}
|
||||
static inline unsigned getHashValue(const LiveIndex &v) {
|
||||
return LiveIndex::getHashValue(v);
|
||||
}
|
||||
static inline bool isEqual(const LiveIndex &LHS,
|
||||
const LiveIndex &RHS) {
|
||||
return (LHS == RHS);
|
||||
}
|
||||
static inline bool isPod() { return true; }
|
||||
};
|
||||
|
||||
|
||||
/// VNInfo - Value Number Information.
|
||||
/// This class holds information about a machine level values, including
|
||||
@ -270,23 +68,25 @@ namespace llvm {
|
||||
|
||||
public:
|
||||
|
||||
typedef SmallVector<LiveIndex, 4> KillSet;
|
||||
typedef SmallVector<SlotIndex, 4> KillSet;
|
||||
|
||||
/// The ID number of this value.
|
||||
unsigned id;
|
||||
|
||||
/// The index of the defining instruction (if isDefAccurate() returns true).
|
||||
LiveIndex def;
|
||||
SlotIndex def;
|
||||
|
||||
KillSet kills;
|
||||
|
||||
VNInfo()
|
||||
: flags(IS_UNUSED), id(~1U) { cr.copy = 0; }
|
||||
/*
|
||||
VNInfo(LiveIntervals &li_)
|
||||
: defflags(IS_UNUSED), id(~1U) { cr.copy = 0; }
|
||||
*/
|
||||
|
||||
/// VNInfo constructor.
|
||||
/// d is presumed to point to the actual defining instr. If it doesn't
|
||||
/// setIsDefAccurate(false) should be called after construction.
|
||||
VNInfo(unsigned i, LiveIndex d, MachineInstr *c)
|
||||
VNInfo(unsigned i, SlotIndex d, MachineInstr *c)
|
||||
: flags(IS_DEF_ACCURATE), id(i), def(d) { cr.copy = c; }
|
||||
|
||||
/// VNInfo construtor, copies values from orig, except for the value number.
|
||||
@ -377,7 +177,7 @@ namespace llvm {
|
||||
}
|
||||
|
||||
/// Returns true if the given index is a kill of this value.
|
||||
bool isKill(LiveIndex k) const {
|
||||
bool isKill(SlotIndex k) const {
|
||||
KillSet::const_iterator
|
||||
i = std::lower_bound(kills.begin(), kills.end(), k);
|
||||
return (i != kills.end() && *i == k);
|
||||
@ -385,7 +185,7 @@ namespace llvm {
|
||||
|
||||
/// addKill - Add a kill instruction index to the specified value
|
||||
/// number.
|
||||
void addKill(LiveIndex k) {
|
||||
void addKill(SlotIndex k) {
|
||||
if (kills.empty()) {
|
||||
kills.push_back(k);
|
||||
} else {
|
||||
@ -397,7 +197,7 @@ namespace llvm {
|
||||
|
||||
/// Remove the specified kill index from this value's kills list.
|
||||
/// Returns true if the value was present, otherwise returns false.
|
||||
bool removeKill(LiveIndex k) {
|
||||
bool removeKill(SlotIndex k) {
|
||||
KillSet::iterator i = std::lower_bound(kills.begin(), kills.end(), k);
|
||||
if (i != kills.end() && *i == k) {
|
||||
kills.erase(i);
|
||||
@ -407,7 +207,7 @@ namespace llvm {
|
||||
}
|
||||
|
||||
/// Remove all kills in the range [s, e).
|
||||
void removeKills(LiveIndex s, LiveIndex e) {
|
||||
void removeKills(SlotIndex s, SlotIndex e) {
|
||||
KillSet::iterator
|
||||
si = std::lower_bound(kills.begin(), kills.end(), s),
|
||||
se = std::upper_bound(kills.begin(), kills.end(), e);
|
||||
@ -421,11 +221,11 @@ namespace llvm {
|
||||
/// program, with an inclusive start point and an exclusive end point.
|
||||
/// These ranges are rendered as [start,end).
|
||||
struct LiveRange {
|
||||
LiveIndex start; // Start point of the interval (inclusive)
|
||||
LiveIndex end; // End point of the interval (exclusive)
|
||||
SlotIndex start; // Start point of the interval (inclusive)
|
||||
SlotIndex end; // End point of the interval (exclusive)
|
||||
VNInfo *valno; // identifier for the value contained in this interval.
|
||||
|
||||
LiveRange(LiveIndex S, LiveIndex E, VNInfo *V)
|
||||
LiveRange(SlotIndex S, SlotIndex E, VNInfo *V)
|
||||
: start(S), end(E), valno(V) {
|
||||
|
||||
assert(S < E && "Cannot create empty or backwards range");
|
||||
@ -433,13 +233,13 @@ namespace llvm {
|
||||
|
||||
/// contains - Return true if the index is covered by this range.
|
||||
///
|
||||
bool contains(LiveIndex I) const {
|
||||
bool contains(SlotIndex I) const {
|
||||
return start <= I && I < end;
|
||||
}
|
||||
|
||||
/// containsRange - Return true if the given range, [S, E), is covered by
|
||||
/// this range.
|
||||
bool containsRange(LiveIndex S, LiveIndex E) const {
|
||||
bool containsRange(SlotIndex S, SlotIndex E) const {
|
||||
assert((S < E) && "Backwards interval?");
|
||||
return (start <= S && S < end) && (start < E && E <= end);
|
||||
}
|
||||
@ -461,11 +261,11 @@ namespace llvm {
|
||||
raw_ostream& operator<<(raw_ostream& os, const LiveRange &LR);
|
||||
|
||||
|
||||
inline bool operator<(LiveIndex V, const LiveRange &LR) {
|
||||
inline bool operator<(SlotIndex V, const LiveRange &LR) {
|
||||
return V < LR.start;
|
||||
}
|
||||
|
||||
inline bool operator<(const LiveRange &LR, LiveIndex V) {
|
||||
inline bool operator<(const LiveRange &LR, SlotIndex V) {
|
||||
return LR.start < V;
|
||||
}
|
||||
|
||||
@ -522,7 +322,7 @@ namespace llvm {
|
||||
/// end of the interval. If no LiveRange contains this position, but the
|
||||
/// position is in a hole, this method returns an iterator pointing the the
|
||||
/// LiveRange immediately after the hole.
|
||||
iterator advanceTo(iterator I, LiveIndex Pos) {
|
||||
iterator advanceTo(iterator I, SlotIndex Pos) {
|
||||
if (Pos >= endIndex())
|
||||
return end();
|
||||
while (I->end <= Pos) ++I;
|
||||
@ -569,7 +369,7 @@ namespace llvm {
|
||||
|
||||
/// getNextValue - Create a new value number and return it. MIIdx specifies
|
||||
/// the instruction that defines the value number.
|
||||
VNInfo *getNextValue(LiveIndex def, MachineInstr *CopyMI,
|
||||
VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI,
|
||||
bool isDefAccurate, BumpPtrAllocator &VNInfoAllocator){
|
||||
VNInfo *VNI =
|
||||
static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
|
||||
@ -625,13 +425,15 @@ namespace llvm {
|
||||
/// current interval, but are defined in the Clobbers interval, mark them
|
||||
/// used with an unknown definition value. Caller must pass in reference to
|
||||
/// VNInfoAllocator since it will create a new val#.
|
||||
void MergeInClobberRanges(const LiveInterval &Clobbers,
|
||||
void MergeInClobberRanges(LiveIntervals &li_,
|
||||
const LiveInterval &Clobbers,
|
||||
BumpPtrAllocator &VNInfoAllocator);
|
||||
|
||||
/// MergeInClobberRange - Same as MergeInClobberRanges except it merge in a
|
||||
/// single LiveRange only.
|
||||
void MergeInClobberRange(LiveIndex Start,
|
||||
LiveIndex End,
|
||||
void MergeInClobberRange(LiveIntervals &li_,
|
||||
SlotIndex Start,
|
||||
SlotIndex End,
|
||||
BumpPtrAllocator &VNInfoAllocator);
|
||||
|
||||
/// MergeValueInAsValue - Merge all of the live ranges of a specific val#
|
||||
@ -657,56 +459,54 @@ namespace llvm {
|
||||
bool empty() const { return ranges.empty(); }
|
||||
|
||||
/// beginIndex - Return the lowest numbered slot covered by interval.
|
||||
LiveIndex beginIndex() const {
|
||||
if (empty())
|
||||
return LiveIndex();
|
||||
SlotIndex beginIndex() const {
|
||||
assert(!empty() && "Call to beginIndex() on empty interval.");
|
||||
return ranges.front().start;
|
||||
}
|
||||
|
||||
/// endNumber - return the maximum point of the interval of the whole,
|
||||
/// exclusive.
|
||||
LiveIndex endIndex() const {
|
||||
if (empty())
|
||||
return LiveIndex();
|
||||
SlotIndex endIndex() const {
|
||||
assert(!empty() && "Call to endIndex() on empty interval.");
|
||||
return ranges.back().end;
|
||||
}
|
||||
|
||||
bool expiredAt(LiveIndex index) const {
|
||||
bool expiredAt(SlotIndex index) const {
|
||||
return index >= endIndex();
|
||||
}
|
||||
|
||||
bool liveAt(LiveIndex index) const;
|
||||
bool liveAt(SlotIndex index) const;
|
||||
|
||||
// liveBeforeAndAt - Check if the interval is live at the index and the
|
||||
// index just before it. If index is liveAt, check if it starts a new live
|
||||
// range.If it does, then check if the previous live range ends at index-1.
|
||||
bool liveBeforeAndAt(LiveIndex index) const;
|
||||
bool liveBeforeAndAt(SlotIndex index) const;
|
||||
|
||||
/// getLiveRangeContaining - Return the live range that contains the
|
||||
/// specified index, or null if there is none.
|
||||
const LiveRange *getLiveRangeContaining(LiveIndex Idx) const {
|
||||
const LiveRange *getLiveRangeContaining(SlotIndex Idx) const {
|
||||
const_iterator I = FindLiveRangeContaining(Idx);
|
||||
return I == end() ? 0 : &*I;
|
||||
}
|
||||
|
||||
/// getLiveRangeContaining - Return the live range that contains the
|
||||
/// specified index, or null if there is none.
|
||||
LiveRange *getLiveRangeContaining(LiveIndex Idx) {
|
||||
LiveRange *getLiveRangeContaining(SlotIndex Idx) {
|
||||
iterator I = FindLiveRangeContaining(Idx);
|
||||
return I == end() ? 0 : &*I;
|
||||
}
|
||||
|
||||
/// FindLiveRangeContaining - Return an iterator to the live range that
|
||||
/// contains the specified index, or end() if there is none.
|
||||
const_iterator FindLiveRangeContaining(LiveIndex Idx) const;
|
||||
const_iterator FindLiveRangeContaining(SlotIndex Idx) const;
|
||||
|
||||
/// FindLiveRangeContaining - Return an iterator to the live range that
|
||||
/// contains the specified index, or end() if there is none.
|
||||
iterator FindLiveRangeContaining(LiveIndex Idx);
|
||||
iterator FindLiveRangeContaining(SlotIndex Idx);
|
||||
|
||||
/// findDefinedVNInfo - Find the by the specified
|
||||
/// index (register interval) or defined
|
||||
VNInfo *findDefinedVNInfoForRegInt(LiveIndex Idx) const;
|
||||
VNInfo *findDefinedVNInfoForRegInt(SlotIndex Idx) const;
|
||||
|
||||
/// findDefinedVNInfo - Find the VNInfo that's defined by the specified
|
||||
/// register (stack inteval only).
|
||||
@ -721,7 +521,7 @@ namespace llvm {
|
||||
|
||||
/// overlaps - Return true if the live interval overlaps a range specified
|
||||
/// by [Start, End).
|
||||
bool overlaps(LiveIndex Start, LiveIndex End) const;
|
||||
bool overlaps(SlotIndex Start, SlotIndex End) const;
|
||||
|
||||
/// overlapsFrom - Return true if the intersection of the two live intervals
|
||||
/// is not empty. The specified iterator is a hint that we can begin
|
||||
@ -738,18 +538,19 @@ namespace llvm {
|
||||
/// join - Join two live intervals (this, and other) together. This applies
|
||||
/// mappings to the value numbers in the LHS/RHS intervals as specified. If
|
||||
/// the intervals are not joinable, this aborts.
|
||||
void join(LiveInterval &Other, const int *ValNoAssignments,
|
||||
void join(LiveInterval &Other,
|
||||
const int *ValNoAssignments,
|
||||
const int *RHSValNoAssignments,
|
||||
SmallVector<VNInfo*, 16> &NewVNInfo,
|
||||
MachineRegisterInfo *MRI);
|
||||
|
||||
/// isInOneLiveRange - Return true if the range specified is entirely in the
|
||||
/// a single LiveRange of the live interval.
|
||||
bool isInOneLiveRange(LiveIndex Start, LiveIndex End);
|
||||
bool isInOneLiveRange(SlotIndex Start, SlotIndex End);
|
||||
|
||||
/// removeRange - Remove the specified range from this interval. Note that
|
||||
/// the range must be a single LiveRange in its entirety.
|
||||
void removeRange(LiveIndex Start, LiveIndex End,
|
||||
void removeRange(SlotIndex Start, SlotIndex End,
|
||||
bool RemoveDeadValNo = false);
|
||||
|
||||
void removeRange(LiveRange LR, bool RemoveDeadValNo = false) {
|
||||
@ -773,8 +574,8 @@ namespace llvm {
|
||||
void ComputeJoinedWeight(const LiveInterval &Other);
|
||||
|
||||
bool operator<(const LiveInterval& other) const {
|
||||
const LiveIndex &thisIndex = beginIndex();
|
||||
const LiveIndex &otherIndex = other.beginIndex();
|
||||
const SlotIndex &thisIndex = beginIndex();
|
||||
const SlotIndex &otherIndex = other.beginIndex();
|
||||
return (thisIndex < otherIndex ||
|
||||
(thisIndex == otherIndex && reg < other.reg));
|
||||
}
|
||||
@ -785,8 +586,9 @@ namespace llvm {
|
||||
private:
|
||||
|
||||
Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
|
||||
void extendIntervalEndTo(Ranges::iterator I, LiveIndex NewEnd);
|
||||
Ranges::iterator extendIntervalStartTo(Ranges::iterator I, LiveIndex NewStr);
|
||||
void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd);
|
||||
Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr);
|
||||
|
||||
LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
|
||||
|
||||
};
|
||||
|
@ -23,12 +23,14 @@
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/LiveInterval.h"
|
||||
#include "llvm/CodeGen/SlotIndexes.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -40,21 +42,6 @@ namespace llvm {
|
||||
class TargetInstrInfo;
|
||||
class TargetRegisterClass;
|
||||
class VirtRegMap;
|
||||
typedef std::pair<LiveIndex, MachineBasicBlock*> IdxMBBPair;
|
||||
|
||||
inline bool operator<(LiveIndex V, const IdxMBBPair &IM) {
|
||||
return V < IM.first;
|
||||
}
|
||||
|
||||
inline bool operator<(const IdxMBBPair &IM, LiveIndex V) {
|
||||
return IM.first < V;
|
||||
}
|
||||
|
||||
struct Idx2MBBCompare {
|
||||
bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const {
|
||||
return LHS.first < RHS.first;
|
||||
}
|
||||
};
|
||||
|
||||
class LiveIntervals : public MachineFunctionPass {
|
||||
MachineFunction* mf_;
|
||||
@ -64,33 +51,15 @@ namespace llvm {
|
||||
const TargetInstrInfo* tii_;
|
||||
AliasAnalysis *aa_;
|
||||
LiveVariables* lv_;
|
||||
SlotIndexes* indexes_;
|
||||
|
||||
/// Special pool allocator for VNInfo's (LiveInterval val#).
|
||||
///
|
||||
BumpPtrAllocator VNInfoAllocator;
|
||||
|
||||
/// MBB2IdxMap - The indexes of the first and last instructions in the
|
||||
/// specified basic block.
|
||||
std::vector<std::pair<LiveIndex, LiveIndex> > MBB2IdxMap;
|
||||
|
||||
/// Idx2MBBMap - Sorted list of pairs of index of first instruction
|
||||
/// and MBB id.
|
||||
std::vector<IdxMBBPair> Idx2MBBMap;
|
||||
|
||||
/// FunctionSize - The number of instructions present in the function
|
||||
uint64_t FunctionSize;
|
||||
|
||||
typedef DenseMap<const MachineInstr*, LiveIndex> Mi2IndexMap;
|
||||
Mi2IndexMap mi2iMap_;
|
||||
|
||||
typedef std::vector<MachineInstr*> Index2MiMap;
|
||||
Index2MiMap i2miMap_;
|
||||
|
||||
typedef DenseMap<unsigned, LiveInterval*> Reg2IntervalMap;
|
||||
Reg2IntervalMap r2iMap_;
|
||||
|
||||
DenseMap<MachineBasicBlock*, LiveIndex> terminatorGaps;
|
||||
|
||||
/// phiJoinCopies - Copy instructions which are PHI joins.
|
||||
SmallVector<MachineInstr*, 16> phiJoinCopies;
|
||||
|
||||
@ -100,48 +69,10 @@ namespace llvm {
|
||||
/// CloneMIs - A list of clones as result of re-materialization.
|
||||
std::vector<MachineInstr*> CloneMIs;
|
||||
|
||||
typedef LiveInterval::InstrSlots InstrSlots;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
LiveIntervals() : MachineFunctionPass(&ID) {}
|
||||
|
||||
LiveIndex getBaseIndex(LiveIndex index) {
|
||||
return LiveIndex(index, LiveIndex::LOAD);
|
||||
}
|
||||
LiveIndex getBoundaryIndex(LiveIndex index) {
|
||||
return LiveIndex(index,
|
||||
(LiveIndex::Slot)(LiveIndex::NUM - 1));
|
||||
}
|
||||
LiveIndex getLoadIndex(LiveIndex index) {
|
||||
return LiveIndex(index, LiveIndex::LOAD);
|
||||
}
|
||||
LiveIndex getUseIndex(LiveIndex index) {
|
||||
return LiveIndex(index, LiveIndex::USE);
|
||||
}
|
||||
LiveIndex getDefIndex(LiveIndex index) {
|
||||
return LiveIndex(index, LiveIndex::DEF);
|
||||
}
|
||||
LiveIndex getStoreIndex(LiveIndex index) {
|
||||
return LiveIndex(index, LiveIndex::STORE);
|
||||
}
|
||||
|
||||
LiveIndex getNextSlot(LiveIndex m) const {
|
||||
return m.nextSlot_();
|
||||
}
|
||||
|
||||
LiveIndex getNextIndex(LiveIndex m) const {
|
||||
return m.nextIndex_();
|
||||
}
|
||||
|
||||
LiveIndex getPrevSlot(LiveIndex m) const {
|
||||
return m.prevSlot_();
|
||||
}
|
||||
|
||||
LiveIndex getPrevIndex(LiveIndex m) const {
|
||||
return m.prevIndex_();
|
||||
}
|
||||
|
||||
static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth) {
|
||||
return (isDef + isUse) * powf(10.0F, (float)loopDepth);
|
||||
}
|
||||
@ -170,111 +101,18 @@ namespace llvm {
|
||||
return r2iMap_.count(reg);
|
||||
}
|
||||
|
||||
/// getMBBStartIdx - Return the base index of the first instruction in the
|
||||
/// specified MachineBasicBlock.
|
||||
LiveIndex getMBBStartIdx(MachineBasicBlock *MBB) const {
|
||||
return getMBBStartIdx(MBB->getNumber());
|
||||
}
|
||||
LiveIndex getMBBStartIdx(unsigned MBBNo) const {
|
||||
assert(MBBNo < MBB2IdxMap.size() && "Invalid MBB number!");
|
||||
return MBB2IdxMap[MBBNo].first;
|
||||
}
|
||||
|
||||
/// getMBBEndIdx - Return the store index of the last instruction in the
|
||||
/// specified MachineBasicBlock.
|
||||
LiveIndex getMBBEndIdx(MachineBasicBlock *MBB) const {
|
||||
return getMBBEndIdx(MBB->getNumber());
|
||||
}
|
||||
LiveIndex getMBBEndIdx(unsigned MBBNo) const {
|
||||
assert(MBBNo < MBB2IdxMap.size() && "Invalid MBB number!");
|
||||
return MBB2IdxMap[MBBNo].second;
|
||||
}
|
||||
|
||||
/// getScaledIntervalSize - get the size of an interval in "units,"
|
||||
/// where every function is composed of one thousand units. This
|
||||
/// measure scales properly with empty index slots in the function.
|
||||
double getScaledIntervalSize(LiveInterval& I) {
|
||||
return (1000.0 / InstrSlots::NUM * I.getSize()) / i2miMap_.size();
|
||||
return (1000.0 * I.getSize()) / indexes_->getIndexesLength();
|
||||
}
|
||||
|
||||
/// getApproximateInstructionCount - computes an estimate of the number
|
||||
/// of instructions in a given LiveInterval.
|
||||
unsigned getApproximateInstructionCount(LiveInterval& I) {
|
||||
double IntervalPercentage = getScaledIntervalSize(I) / 1000.0;
|
||||
return (unsigned)(IntervalPercentage * FunctionSize);
|
||||
}
|
||||
|
||||
/// getMBBFromIndex - given an index in any instruction of an
|
||||
/// MBB return a pointer the MBB
|
||||
MachineBasicBlock* getMBBFromIndex(LiveIndex index) const {
|
||||
std::vector<IdxMBBPair>::const_iterator I =
|
||||
std::lower_bound(Idx2MBBMap.begin(), Idx2MBBMap.end(), index);
|
||||
// Take the pair containing the index
|
||||
std::vector<IdxMBBPair>::const_iterator J =
|
||||
((I != Idx2MBBMap.end() && I->first > index) ||
|
||||
(I == Idx2MBBMap.end() && Idx2MBBMap.size()>0)) ? (I-1): I;
|
||||
|
||||
assert(J != Idx2MBBMap.end() && J->first <= index &&
|
||||
index <= getMBBEndIdx(J->second) &&
|
||||
"index does not correspond to an MBB");
|
||||
return J->second;
|
||||
}
|
||||
|
||||
/// getInstructionIndex - returns the base index of instr
|
||||
LiveIndex getInstructionIndex(const MachineInstr* instr) const {
|
||||
Mi2IndexMap::const_iterator it = mi2iMap_.find(instr);
|
||||
assert(it != mi2iMap_.end() && "Invalid instruction!");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
/// getInstructionFromIndex - given an index in any slot of an
|
||||
/// instruction return a pointer the instruction
|
||||
MachineInstr* getInstructionFromIndex(LiveIndex index) const {
|
||||
// convert index to vector index
|
||||
unsigned i = index.getVecIndex();
|
||||
assert(i < i2miMap_.size() &&
|
||||
"index does not correspond to an instruction");
|
||||
return i2miMap_[i];
|
||||
}
|
||||
|
||||
/// hasGapBeforeInstr - Return true if the previous instruction slot,
|
||||
/// i.e. Index - InstrSlots::NUM, is not occupied.
|
||||
bool hasGapBeforeInstr(LiveIndex Index) {
|
||||
Index = getBaseIndex(getPrevIndex(Index));
|
||||
return getInstructionFromIndex(Index) == 0;
|
||||
}
|
||||
|
||||
/// hasGapAfterInstr - Return true if the successive instruction slot,
|
||||
/// i.e. Index + InstrSlots::Num, is not occupied.
|
||||
bool hasGapAfterInstr(LiveIndex Index) {
|
||||
Index = getBaseIndex(getNextIndex(Index));
|
||||
return getInstructionFromIndex(Index) == 0;
|
||||
}
|
||||
|
||||
/// findGapBeforeInstr - Find an empty instruction slot before the
|
||||
/// specified index. If "Furthest" is true, find one that's furthest
|
||||
/// away from the index (but before any index that's occupied).
|
||||
LiveIndex findGapBeforeInstr(LiveIndex Index, bool Furthest = false) {
|
||||
Index = getBaseIndex(getPrevIndex(Index));
|
||||
if (getInstructionFromIndex(Index))
|
||||
return LiveIndex(); // No gap!
|
||||
if (!Furthest)
|
||||
return Index;
|
||||
LiveIndex PrevIndex = getBaseIndex(getPrevIndex(Index));
|
||||
while (getInstructionFromIndex(Index)) {
|
||||
Index = PrevIndex;
|
||||
PrevIndex = getBaseIndex(getPrevIndex(Index));
|
||||
}
|
||||
return Index;
|
||||
}
|
||||
|
||||
/// InsertMachineInstrInMaps - Insert the specified machine instruction
|
||||
/// into the instruction index map at the given index.
|
||||
void InsertMachineInstrInMaps(MachineInstr *MI, LiveIndex Index) {
|
||||
i2miMap_[Index.getVecIndex()] = MI;
|
||||
Mi2IndexMap::iterator it = mi2iMap_.find(MI);
|
||||
assert(it == mi2iMap_.end() && "Already in map!");
|
||||
mi2iMap_[MI] = Index;
|
||||
return (unsigned)(IntervalPercentage * indexes_->getFunctionSize());
|
||||
}
|
||||
|
||||
/// conflictsWithPhysRegDef - Returns true if the specified register
|
||||
@ -288,19 +126,7 @@ namespace llvm {
|
||||
bool CheckUse,
|
||||
SmallPtrSet<MachineInstr*,32> &JoinedCopies);
|
||||
|
||||
/// findLiveInMBBs - Given a live range, if the value of the range
|
||||
/// is live in any MBB returns true as well as the list of basic blocks
|
||||
/// in which the value is live.
|
||||
bool findLiveInMBBs(LiveIndex Start, LiveIndex End,
|
||||
SmallVectorImpl<MachineBasicBlock*> &MBBs) const;
|
||||
|
||||
/// findReachableMBBs - Return a list MBB that can be reached via any
|
||||
/// branch or fallthroughs. Return true if the list is not empty.
|
||||
bool findReachableMBBs(LiveIndex Start, LiveIndex End,
|
||||
SmallVectorImpl<MachineBasicBlock*> &MBBs) const;
|
||||
|
||||
// Interval creation
|
||||
|
||||
LiveInterval &getOrCreateInterval(unsigned reg) {
|
||||
Reg2IntervalMap::iterator I = r2iMap_.find(reg);
|
||||
if (I == r2iMap_.end())
|
||||
@ -325,36 +151,75 @@ namespace llvm {
|
||||
r2iMap_.erase(I);
|
||||
}
|
||||
|
||||
SlotIndex getZeroIndex() const {
|
||||
return indexes_->getZeroIndex();
|
||||
}
|
||||
|
||||
SlotIndex getInvalidIndex() const {
|
||||
return indexes_->getInvalidIndex();
|
||||
}
|
||||
|
||||
/// isNotInMIMap - returns true if the specified machine instr has been
|
||||
/// removed or was never entered in the map.
|
||||
bool isNotInMIMap(MachineInstr* instr) const {
|
||||
return !mi2iMap_.count(instr);
|
||||
bool isNotInMIMap(const MachineInstr* Instr) const {
|
||||
return !indexes_->hasIndex(Instr);
|
||||
}
|
||||
|
||||
/// Returns the base index of the given instruction.
|
||||
SlotIndex getInstructionIndex(const MachineInstr *instr) const {
|
||||
return indexes_->getInstructionIndex(instr);
|
||||
}
|
||||
|
||||
/// Returns the instruction associated with the given index.
|
||||
MachineInstr* getInstructionFromIndex(SlotIndex index) const {
|
||||
return indexes_->getInstructionFromIndex(index);
|
||||
}
|
||||
|
||||
/// Return the first index in the given basic block.
|
||||
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
|
||||
return indexes_->getMBBStartIdx(mbb);
|
||||
}
|
||||
|
||||
/// Return the last index in the given basic block.
|
||||
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
|
||||
return indexes_->getMBBEndIdx(mbb);
|
||||
}
|
||||
|
||||
MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
|
||||
return indexes_->getMBBFromIndex(index);
|
||||
}
|
||||
|
||||
bool hasGapBeforeInstr(SlotIndex index) {
|
||||
return indexes_->hasGapBeforeInstr(index);
|
||||
}
|
||||
|
||||
bool hasGapAfterInstr(SlotIndex index) {
|
||||
return indexes_->hasGapAfterInstr(index);
|
||||
}
|
||||
|
||||
SlotIndex findGapBeforeInstr(SlotIndex index, bool furthest = false) {
|
||||
return indexes_->findGapBeforeInstr(index, furthest);
|
||||
}
|
||||
|
||||
void InsertMachineInstrInMaps(MachineInstr *MI, SlotIndex Index) {
|
||||
indexes_->insertMachineInstrInMaps(MI, Index);
|
||||
}
|
||||
|
||||
/// RemoveMachineInstrFromMaps - This marks the specified machine instr as
|
||||
/// deleted.
|
||||
void RemoveMachineInstrFromMaps(MachineInstr *MI) {
|
||||
// remove index -> MachineInstr and
|
||||
// MachineInstr -> index mappings
|
||||
Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI);
|
||||
if (mi2i != mi2iMap_.end()) {
|
||||
i2miMap_[mi2i->second.index/InstrSlots::NUM] = 0;
|
||||
mi2iMap_.erase(mi2i);
|
||||
}
|
||||
indexes_->removeMachineInstrFromMaps(MI);
|
||||
}
|
||||
|
||||
/// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
|
||||
/// maps used by register allocator.
|
||||
void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) {
|
||||
Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI);
|
||||
if (mi2i == mi2iMap_.end())
|
||||
return;
|
||||
i2miMap_[mi2i->second.index/InstrSlots::NUM] = NewMI;
|
||||
Mi2IndexMap::iterator it = mi2iMap_.find(MI);
|
||||
assert(it != mi2iMap_.end() && "Invalid instruction!");
|
||||
LiveIndex Index = it->second;
|
||||
mi2iMap_.erase(it);
|
||||
mi2iMap_[NewMI] = Index;
|
||||
indexes_->replaceMachineInstrInMaps(MI, NewMI);
|
||||
}
|
||||
|
||||
bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
|
||||
SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
|
||||
return indexes_->findLiveInMBBs(Start, End, MBBs);
|
||||
}
|
||||
|
||||
void renumber() {
|
||||
indexes_->renumber();
|
||||
}
|
||||
|
||||
BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }
|
||||
@ -417,13 +282,6 @@ namespace llvm {
|
||||
/// marker to implicit_def defs and their uses.
|
||||
void processImplicitDefs();
|
||||
|
||||
/// computeNumbering - Compute the index numbering.
|
||||
void computeNumbering();
|
||||
|
||||
/// scaleNumbering - Rescale interval numbers to introduce gaps for new
|
||||
/// instructions
|
||||
void scaleNumbering(int factor);
|
||||
|
||||
/// intervalIsInOneMBB - Returns true if the specified interval is entirely
|
||||
/// within a single basic block.
|
||||
bool intervalIsInOneMBB(const LiveInterval &li) const;
|
||||
@ -443,14 +301,14 @@ namespace llvm {
|
||||
/// handleVirtualRegisterDef)
|
||||
void handleRegisterDef(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
LiveIndex MIIdx,
|
||||
SlotIndex MIIdx,
|
||||
MachineOperand& MO, unsigned MOIdx);
|
||||
|
||||
/// handleVirtualRegisterDef - update intervals for a virtual
|
||||
/// register def
|
||||
void handleVirtualRegisterDef(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
LiveIndex MIIdx, MachineOperand& MO,
|
||||
SlotIndex MIIdx, MachineOperand& MO,
|
||||
unsigned MOIdx,
|
||||
LiveInterval& interval);
|
||||
|
||||
@ -458,13 +316,13 @@ namespace llvm {
|
||||
/// def.
|
||||
void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
|
||||
MachineBasicBlock::iterator mi,
|
||||
LiveIndex MIIdx, MachineOperand& MO,
|
||||
SlotIndex MIIdx, MachineOperand& MO,
|
||||
LiveInterval &interval,
|
||||
MachineInstr *CopyMI);
|
||||
|
||||
/// handleLiveInRegister - Create interval for a livein register.
|
||||
void handleLiveInRegister(MachineBasicBlock* mbb,
|
||||
LiveIndex MIIdx,
|
||||
SlotIndex MIIdx,
|
||||
LiveInterval &interval, bool isAlias = false);
|
||||
|
||||
/// getReMatImplicitUse - If the remat definition MI has one (for now, we
|
||||
@ -477,7 +335,7 @@ namespace llvm {
|
||||
/// which reaches the given instruction also reaches the specified use
|
||||
/// index.
|
||||
bool isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI,
|
||||
LiveIndex UseIdx) const;
|
||||
SlotIndex UseIdx) const;
|
||||
|
||||
/// isReMaterializable - Returns true if the definition MI of the specified
|
||||
/// val# of the specified interval is re-materializable. Also returns true
|
||||
@ -492,7 +350,7 @@ namespace llvm {
|
||||
/// MI. If it is successul, MI is updated with the newly created MI and
|
||||
/// returns true.
|
||||
bool tryFoldMemoryOperand(MachineInstr* &MI, VirtRegMap &vrm,
|
||||
MachineInstr *DefMI, LiveIndex InstrIdx,
|
||||
MachineInstr *DefMI, SlotIndex InstrIdx,
|
||||
SmallVector<unsigned, 2> &Ops,
|
||||
bool isSS, int FrameIndex, unsigned Reg);
|
||||
|
||||
@ -506,7 +364,7 @@ namespace llvm {
|
||||
/// VNInfo that's after the specified index but is within the basic block.
|
||||
bool anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI,
|
||||
MachineBasicBlock *MBB,
|
||||
LiveIndex Idx) const;
|
||||
SlotIndex Idx) const;
|
||||
|
||||
/// hasAllocatableSuperReg - Return true if the specified physical register
|
||||
/// has any super register that's allocatable.
|
||||
@ -514,17 +372,17 @@ namespace llvm {
|
||||
|
||||
/// SRInfo - Spill / restore info.
|
||||
struct SRInfo {
|
||||
LiveIndex index;
|
||||
SlotIndex index;
|
||||
unsigned vreg;
|
||||
bool canFold;
|
||||
SRInfo(LiveIndex i, unsigned vr, bool f)
|
||||
SRInfo(SlotIndex i, unsigned vr, bool f)
|
||||
: index(i), vreg(vr), canFold(f) {}
|
||||
};
|
||||
|
||||
bool alsoFoldARestore(int Id, LiveIndex index, unsigned vr,
|
||||
bool alsoFoldARestore(int Id, SlotIndex index, unsigned vr,
|
||||
BitVector &RestoreMBBs,
|
||||
DenseMap<unsigned,std::vector<SRInfo> >&RestoreIdxes);
|
||||
void eraseRestoreInfo(int Id, LiveIndex index, unsigned vr,
|
||||
void eraseRestoreInfo(int Id, SlotIndex index, unsigned vr,
|
||||
BitVector &RestoreMBBs,
|
||||
DenseMap<unsigned,std::vector<SRInfo> >&RestoreIdxes);
|
||||
|
||||
@ -543,7 +401,7 @@ namespace llvm {
|
||||
/// functions for addIntervalsForSpills to rewrite uses / defs for the given
|
||||
/// live range.
|
||||
bool rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
|
||||
bool TrySplit, LiveIndex index, LiveIndex end,
|
||||
bool TrySplit, SlotIndex index, SlotIndex end,
|
||||
MachineInstr *MI, MachineInstr *OrigDefMI, MachineInstr *DefMI,
|
||||
unsigned Slot, int LdSlot,
|
||||
bool isLoad, bool isLoadSS, bool DefIsReMat, bool CanDelete,
|
||||
|
@ -48,8 +48,6 @@ namespace llvm {
|
||||
iterator begin() { return S2IMap.begin(); }
|
||||
iterator end() { return S2IMap.end(); }
|
||||
|
||||
void scaleNumbering(int factor);
|
||||
|
||||
unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
|
||||
|
||||
LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
|
||||
|
@ -76,6 +76,10 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
/// exception handler.
|
||||
bool IsLandingPad;
|
||||
|
||||
/// AddressTaken - Indicate that this basic block is potentially the
|
||||
/// target of an indirect branch.
|
||||
bool AddressTaken;
|
||||
|
||||
// Intrusive list support
|
||||
MachineBasicBlock() {}
|
||||
|
||||
@ -92,6 +96,14 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
///
|
||||
const BasicBlock *getBasicBlock() const { return BB; }
|
||||
|
||||
/// hasAddressTaken - Test whether this block is potentially the target
|
||||
/// of an indirect branch.
|
||||
bool hasAddressTaken() const { return AddressTaken; }
|
||||
|
||||
/// setHasAddressTaken - Set this block to reflect that it potentially
|
||||
/// is the target of an indirect branch.
|
||||
void setHasAddressTaken() { AddressTaken = true; }
|
||||
|
||||
/// getParent - Return the MachineFunction containing this basic block.
|
||||
///
|
||||
const MachineFunction *getParent() const { return xParent; }
|
||||
|
@ -17,7 +17,7 @@
|
||||
#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
|
||||
#define LLVM_CODEGEN_MACHINECODEEMITTER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
|
@ -108,13 +108,6 @@ class MachineInstrBuilder {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addMetadata(MDNode *N,
|
||||
int64_t Offset = 0,
|
||||
unsigned char TargetFlags = 0) const {
|
||||
MI->addOperand(MachineOperand::CreateMDNode(N, Offset, TargetFlags));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addExternalSymbol(const char *FnName,
|
||||
unsigned char TargetFlags = 0) const {
|
||||
MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags));
|
||||
|
@ -32,7 +32,7 @@
|
||||
#define LLVM_CODEGEN_MACHINEMODULEINFO_H
|
||||
|
||||
#include "llvm/Support/Dwarf.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/UniqueVector.h"
|
||||
|
@ -14,15 +14,15 @@
|
||||
#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
|
||||
#define LLVM_CODEGEN_MACHINEOPERAND_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ConstantFP;
|
||||
class BlockAddress;
|
||||
class MachineBasicBlock;
|
||||
class GlobalValue;
|
||||
class MDNode;
|
||||
class MachineInstr;
|
||||
class TargetMachine;
|
||||
class MachineRegisterInfo;
|
||||
@ -42,7 +42,7 @@ class MachineOperand {
|
||||
MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
|
||||
MO_ExternalSymbol, ///< Name of external global symbol
|
||||
MO_GlobalAddress, ///< Address of a global value
|
||||
MO_Metadata ///< Metadata info
|
||||
MO_BlockAddress ///< Address of a basic block
|
||||
};
|
||||
|
||||
private:
|
||||
@ -108,7 +108,7 @@ class MachineOperand {
|
||||
int Index; // For MO_*Index - The index itself.
|
||||
const char *SymbolName; // For MO_ExternalSymbol.
|
||||
GlobalValue *GV; // For MO_GlobalAddress.
|
||||
MDNode *Node; // For MO_Metadata.
|
||||
BlockAddress *BA; // For MO_BlockAddress.
|
||||
} Val;
|
||||
int64_t Offset; // An offset from the object.
|
||||
} OffsetedInfo;
|
||||
@ -156,8 +156,8 @@ class MachineOperand {
|
||||
bool isGlobal() const { return OpKind == MO_GlobalAddress; }
|
||||
/// isSymbol - Tests if this is a MO_ExternalSymbol operand.
|
||||
bool isSymbol() const { return OpKind == MO_ExternalSymbol; }
|
||||
/// isMetadata - Tests if this is a MO_Metadata operand.
|
||||
bool isMetadata() const { return OpKind == MO_Metadata; }
|
||||
/// isBlockAddress - Tests if this is a MO_BlockAddress operand.
|
||||
bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Accessors for Register Operands
|
||||
@ -293,15 +293,16 @@ class MachineOperand {
|
||||
assert(isGlobal() && "Wrong MachineOperand accessor");
|
||||
return Contents.OffsetedInfo.Val.GV;
|
||||
}
|
||||
|
||||
MDNode *getMDNode() const {
|
||||
return Contents.OffsetedInfo.Val.Node;
|
||||
|
||||
BlockAddress *getBlockAddress() const {
|
||||
assert(isBlockAddress() && "Wrong MachineOperand accessor");
|
||||
return Contents.OffsetedInfo.Val.BA;
|
||||
}
|
||||
|
||||
/// getOffset - Return the offset from the symbol in this operand. This always
|
||||
/// returns 0 for ExternalSymbol operands.
|
||||
int64_t getOffset() const {
|
||||
assert((isGlobal() || isSymbol() || isCPI()) &&
|
||||
assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) &&
|
||||
"Wrong MachineOperand accessor");
|
||||
return Contents.OffsetedInfo.Offset;
|
||||
}
|
||||
@ -321,7 +322,7 @@ class MachineOperand {
|
||||
}
|
||||
|
||||
void setOffset(int64_t Offset) {
|
||||
assert((isGlobal() || isSymbol() || isCPI() || isMetadata()) &&
|
||||
assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) &&
|
||||
"Wrong MachineOperand accessor");
|
||||
Contents.OffsetedInfo.Offset = Offset;
|
||||
}
|
||||
@ -426,14 +427,6 @@ class MachineOperand {
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateMDNode(MDNode *N, int64_t Offset,
|
||||
unsigned char TargetFlags = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_Metadata);
|
||||
Op.Contents.OffsetedInfo.Val.Node = N;
|
||||
Op.setOffset(Offset);
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateES(const char *SymName,
|
||||
unsigned char TargetFlags = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_ExternalSymbol);
|
||||
@ -442,6 +435,12 @@ class MachineOperand {
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateBA(BlockAddress *BA) {
|
||||
MachineOperand Op(MachineOperand::MO_BlockAddress);
|
||||
Op.Contents.OffsetedInfo.Val.BA = BA;
|
||||
Op.setOffset(0); // Offset is always 0.
|
||||
return Op;
|
||||
}
|
||||
|
||||
friend class MachineInstr;
|
||||
friend class MachineRegisterInfo;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
|
||||
#define LLVM_CODEGEN_MACHINERELOCATION_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
41
include/llvm/CodeGen/ProcessImplicitDefs.h
Normal file
41
include/llvm/CodeGen/ProcessImplicitDefs.h
Normal file
@ -0,0 +1,41 @@
|
||||
//===-------------- llvm/CodeGen/ProcessImplicitDefs.h ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef LLVM_CODEGEN_PROCESSIMPLICITDEFS_H
|
||||
#define LLVM_CODEGEN_PROCESSIMPLICITDEFS_H
|
||||
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachineInstr;
|
||||
class TargetInstrInfo;
|
||||
|
||||
/// Process IMPLICIT_DEF instructions and make sure there is one implicit_def
|
||||
/// for each use. Add isUndef marker to implicit_def defs and their uses.
|
||||
class ProcessImplicitDefs : public MachineFunctionPass {
|
||||
private:
|
||||
|
||||
bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg,
|
||||
unsigned OpIdx, const TargetInstrInfo *tii_);
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
ProcessImplicitDefs() : MachineFunctionPass(&ID) {}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &au) const;
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &fn);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LLVM_CODEGEN_PROCESSIMPLICITDEFS_H
|
@ -43,6 +43,10 @@ namespace llvm {
|
||||
/// PseudoSourceValue may also be pointed to by an LLVM IR Value.
|
||||
virtual bool isAliased(const MachineFrameInfo *) const;
|
||||
|
||||
/// mayAlias - Return true if the memory pointed to by this
|
||||
/// PseudoSourceValue can ever alias a LLVM IR Value.
|
||||
virtual bool mayAlias(const MachineFrameInfo *) const;
|
||||
|
||||
/// classof - Methods for support type inquiry through isa, cast, and
|
||||
/// dyn_cast:
|
||||
///
|
||||
|
@ -340,28 +340,34 @@ 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.
|
||||
unsigned getDepth() const {
|
||||
if (!isDepthCurrent) const_cast<SUnit *>(this)->ComputeDepth();
|
||||
/// maximum path up to any node with has no predecessors. If IgnoreAntiDep
|
||||
/// is true, ignore anti-dependence edges.
|
||||
unsigned getDepth(bool IgnoreAntiDep=false) const {
|
||||
if (!isDepthCurrent)
|
||||
const_cast<SUnit *>(this)->ComputeDepth(IgnoreAntiDep);
|
||||
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.
|
||||
unsigned getHeight() const {
|
||||
if (!isHeightCurrent) const_cast<SUnit *>(this)->ComputeHeight();
|
||||
/// maximum path down to any node with has no successors. If IgnoreAntiDep
|
||||
/// is true, ignore anti-dependence edges.
|
||||
unsigned getHeight(bool IgnoreAntiDep=false) const {
|
||||
if (!isHeightCurrent)
|
||||
const_cast<SUnit *>(this)->ComputeHeight(IgnoreAntiDep);
|
||||
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.
|
||||
void setDepthToAtLeast(unsigned NewDepth);
|
||||
/// 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);
|
||||
|
||||
/// 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.
|
||||
void setHeightToAtLeast(unsigned NewHeight);
|
||||
/// 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);
|
||||
|
||||
/// setDepthDirty - Set a flag in this node to indicate that its
|
||||
/// stored Depth value will require recomputation the next time
|
||||
@ -394,8 +400,8 @@ namespace llvm {
|
||||
void print(raw_ostream &O, const ScheduleDAG *G) const;
|
||||
|
||||
private:
|
||||
void ComputeDepth();
|
||||
void ComputeHeight();
|
||||
void ComputeDepth(bool IgnoreAntiDep);
|
||||
void ComputeHeight(bool IgnoreAntiDep);
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -326,6 +326,8 @@ class SelectionDAG {
|
||||
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 getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
|
||||
return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
|
||||
|
@ -110,6 +110,14 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
|
||||
int64_t DesiredMaskS) const;
|
||||
|
||||
// Calls to these functions are generated by tblgen.
|
||||
SDNode *Select_INLINEASM(SDValue N);
|
||||
SDNode *Select_UNDEF(const SDValue &N);
|
||||
SDNode *Select_DBG_LABEL(const SDValue &N);
|
||||
SDNode *Select_EH_LABEL(const SDValue &N);
|
||||
void CannotYetSelect(SDValue N);
|
||||
void CannotYetSelectIntrinsic(SDValue N);
|
||||
|
||||
private:
|
||||
void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
|
||||
MachineModuleInfo *MMI,
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
#include <cassert>
|
||||
|
||||
@ -97,7 +97,7 @@ namespace ISD {
|
||||
BasicBlock, VALUETYPE, CONDCODE, Register,
|
||||
Constant, ConstantFP,
|
||||
GlobalAddress, GlobalTLSAddress, FrameIndex,
|
||||
JumpTable, ConstantPool, ExternalSymbol,
|
||||
JumpTable, ConstantPool, ExternalSymbol, BlockAddress,
|
||||
|
||||
// The address of the GOT
|
||||
GLOBAL_OFFSET_TABLE,
|
||||
@ -146,6 +146,7 @@ namespace ISD {
|
||||
TargetJumpTable,
|
||||
TargetConstantPool,
|
||||
TargetExternalSymbol,
|
||||
TargetBlockAddress,
|
||||
|
||||
/// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
|
||||
/// This node represents a target intrinsic function with no side effects.
|
||||
@ -2026,11 +2027,27 @@ class DbgStopPointSDNode : public SDNode {
|
||||
}
|
||||
};
|
||||
|
||||
class BlockAddressSDNode : public SDNode {
|
||||
BlockAddress *BA;
|
||||
friend class SelectionDAG;
|
||||
BlockAddressSDNode(unsigned NodeTy, DebugLoc dl, EVT VT, BlockAddress *ba)
|
||||
: SDNode(NodeTy, dl, getSDVTList(VT)), BA(ba) {
|
||||
}
|
||||
public:
|
||||
BlockAddress *getBlockAddress() const { return BA; }
|
||||
|
||||
static bool classof(const BlockAddressSDNode *) { return true; }
|
||||
static bool classof(const SDNode *N) {
|
||||
return N->getOpcode() == ISD::BlockAddress ||
|
||||
N->getOpcode() == ISD::TargetBlockAddress;
|
||||
}
|
||||
};
|
||||
|
||||
class LabelSDNode : public SDNode {
|
||||
SDUse Chain;
|
||||
unsigned LabelID;
|
||||
friend class SelectionDAG;
|
||||
LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
|
||||
LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
|
||||
: SDNode(NodeTy, dl, getSDVTList(MVT::Other)), LabelID(id) {
|
||||
InitOperands(&Chain, ch);
|
||||
}
|
||||
|
740
include/llvm/CodeGen/SlotIndexes.h
Normal file
740
include/llvm/CodeGen/SlotIndexes.h
Normal file
@ -0,0 +1,740 @@
|
||||
//===- llvm/CodeGen/SlotIndexes.h - Slot indexes representation -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements SlotIndex and related classes. The purpuse of SlotIndex
|
||||
// is to describe a position at which a register can become live, or cease to
|
||||
// be live.
|
||||
//
|
||||
// SlotIndex is mostly a proxy for entries of the SlotIndexList, a class which
|
||||
// is held is LiveIntervals and provides the real numbering. This allows
|
||||
// LiveIntervals to perform largely transparent renumbering. The SlotIndex
|
||||
// class does hold a PHI bit, which determines whether the index relates to a
|
||||
// PHI use or def point, or an actual instruction. See the SlotIndex class
|
||||
// description for futher information.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_SLOTINDEXES_H
|
||||
#define LLVM_CODEGEN_SLOTINDEXES_H
|
||||
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// This class represents an entry in the slot index list held in the
|
||||
/// SlotIndexes pass. It should not be used directly. See the
|
||||
/// SlotIndex & SlotIndexes classes for the public interface to this
|
||||
/// information.
|
||||
class IndexListEntry {
|
||||
private:
|
||||
|
||||
IndexListEntry *next, *prev;
|
||||
MachineInstr *mi;
|
||||
unsigned index;
|
||||
|
||||
public:
|
||||
|
||||
IndexListEntry(MachineInstr *mi, unsigned index)
|
||||
: mi(mi), index(index) {}
|
||||
|
||||
MachineInstr* getInstr() const { return mi; }
|
||||
void setInstr(MachineInstr *mi) { this->mi = mi; }
|
||||
|
||||
unsigned getIndex() const { return index; }
|
||||
void setIndex(unsigned index) { this->index = index; }
|
||||
|
||||
IndexListEntry* getNext() { return next; }
|
||||
const IndexListEntry* getNext() const { return next; }
|
||||
void setNext(IndexListEntry *next) { this->next = next; }
|
||||
|
||||
IndexListEntry* getPrev() { return prev; }
|
||||
const IndexListEntry* getPrev() const { return prev; }
|
||||
void setPrev(IndexListEntry *prev) { this->prev = prev; }
|
||||
};
|
||||
|
||||
// Specialize PointerLikeTypeTraits for IndexListEntry.
|
||||
template <>
|
||||
class PointerLikeTypeTraits<IndexListEntry*> {
|
||||
public:
|
||||
static inline void* getAsVoidPointer(IndexListEntry *p) {
|
||||
return p;
|
||||
}
|
||||
static inline IndexListEntry* getFromVoidPointer(void *p) {
|
||||
return static_cast<IndexListEntry*>(p);
|
||||
}
|
||||
enum { NumLowBitsAvailable = 3 };
|
||||
};
|
||||
|
||||
/// SlotIndex - An opaque wrapper around machine indexes.
|
||||
class SlotIndex {
|
||||
friend class SlotIndexes;
|
||||
friend class DenseMapInfo<SlotIndex>;
|
||||
|
||||
private:
|
||||
|
||||
// FIXME: Is there any way to statically allocate these things and have
|
||||
// them 8-byte aligned?
|
||||
static std::auto_ptr<IndexListEntry> emptyKeyPtr, tombstoneKeyPtr;
|
||||
static const unsigned PHI_BIT = 1 << 2;
|
||||
|
||||
PointerIntPair<IndexListEntry*, 3, unsigned> lie;
|
||||
|
||||
SlotIndex(IndexListEntry *entry, unsigned phiAndSlot)
|
||||
: lie(entry, phiAndSlot) {
|
||||
assert(entry != 0 && "Attempt to construct index with 0 pointer.");
|
||||
}
|
||||
|
||||
IndexListEntry& entry() const {
|
||||
assert(lie.getPointer() != 0 && "Use of invalid index.");
|
||||
return *lie.getPointer();
|
||||
}
|
||||
|
||||
int getIndex() const {
|
||||
return entry().getIndex() | getSlot();
|
||||
}
|
||||
|
||||
static inline unsigned getHashValue(const SlotIndex &v) {
|
||||
IndexListEntry *ptrVal = &v.entry();
|
||||
return (unsigned((intptr_t)ptrVal) >> 4) ^
|
||||
(unsigned((intptr_t)ptrVal) >> 9);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// FIXME: Ugh. This is public because LiveIntervalAnalysis is still using it
|
||||
// for some spill weight stuff. Fix that, then make this private.
|
||||
enum Slot { LOAD, USE, DEF, STORE, NUM };
|
||||
|
||||
static inline SlotIndex getEmptyKey() {
|
||||
// FIXME: How do we guarantee these numbers don't get allocated to
|
||||
// legit indexes?
|
||||
if (emptyKeyPtr.get() == 0)
|
||||
emptyKeyPtr.reset(new IndexListEntry(0, ~0U & ~3U));
|
||||
|
||||
return SlotIndex(emptyKeyPtr.get(), 0);
|
||||
}
|
||||
|
||||
static inline SlotIndex getTombstoneKey() {
|
||||
// FIXME: How do we guarantee these numbers don't get allocated to
|
||||
// legit indexes?
|
||||
if (tombstoneKeyPtr.get() == 0)
|
||||
tombstoneKeyPtr.reset(new IndexListEntry(0, ~0U & ~7U));
|
||||
|
||||
return SlotIndex(tombstoneKeyPtr.get(), 0);
|
||||
}
|
||||
|
||||
/// Construct an invalid index.
|
||||
SlotIndex() : lie(&getEmptyKey().entry(), 0) {}
|
||||
|
||||
// Construct a new slot index from the given one, set the phi flag on the
|
||||
// new index to the value of the phi parameter.
|
||||
SlotIndex(const SlotIndex &li, bool phi)
|
||||
: lie(&li.entry(), phi ? PHI_BIT & li.getSlot() : (unsigned)li.getSlot()){
|
||||
assert(lie.getPointer() != 0 &&
|
||||
"Attempt to construct index with 0 pointer.");
|
||||
}
|
||||
|
||||
// Construct a new slot index from the given one, set the phi flag on the
|
||||
// new index to the value of the phi parameter, and the slot to the new slot.
|
||||
SlotIndex(const SlotIndex &li, bool phi, Slot s)
|
||||
: lie(&li.entry(), phi ? PHI_BIT & s : (unsigned)s) {
|
||||
assert(lie.getPointer() != 0 &&
|
||||
"Attempt to construct index with 0 pointer.");
|
||||
}
|
||||
|
||||
/// Returns true if this is a valid index. Invalid indicies do
|
||||
/// not point into an index table, and cannot be compared.
|
||||
bool isValid() const {
|
||||
return (lie.getPointer() != 0) && (lie.getPointer()->getIndex() != 0);
|
||||
}
|
||||
|
||||
/// Print this index to the given raw_ostream.
|
||||
void print(raw_ostream &os) const;
|
||||
|
||||
/// Dump this index to stderr.
|
||||
void dump() const;
|
||||
|
||||
/// Compare two SlotIndex objects for equality.
|
||||
bool operator==(SlotIndex other) const {
|
||||
return getIndex() == other.getIndex();
|
||||
}
|
||||
/// Compare two SlotIndex objects for inequality.
|
||||
bool operator!=(SlotIndex other) const {
|
||||
return getIndex() != other.getIndex();
|
||||
}
|
||||
|
||||
/// Compare two SlotIndex objects. Return true if the first index
|
||||
/// is strictly lower than the second.
|
||||
bool operator<(SlotIndex other) const {
|
||||
return getIndex() < other.getIndex();
|
||||
}
|
||||
/// Compare two SlotIndex objects. Return true if the first index
|
||||
/// is lower than, or equal to, the second.
|
||||
bool operator<=(SlotIndex other) const {
|
||||
return getIndex() <= other.getIndex();
|
||||
}
|
||||
|
||||
/// Compare two SlotIndex objects. Return true if the first index
|
||||
/// is greater than the second.
|
||||
bool operator>(SlotIndex other) const {
|
||||
return getIndex() > other.getIndex();
|
||||
}
|
||||
|
||||
/// Compare two SlotIndex objects. Return true if the first index
|
||||
/// is greater than, or equal to, the second.
|
||||
bool operator>=(SlotIndex other) const {
|
||||
return getIndex() >= other.getIndex();
|
||||
}
|
||||
|
||||
/// Return the distance from this index to the given one.
|
||||
int distance(SlotIndex other) const {
|
||||
return other.getIndex() - getIndex();
|
||||
}
|
||||
|
||||
/// Returns the slot for this SlotIndex.
|
||||
Slot getSlot() const {
|
||||
return static_cast<Slot>(lie.getInt() & ~PHI_BIT);
|
||||
}
|
||||
|
||||
/// Returns the state of the PHI bit.
|
||||
bool isPHI() const {
|
||||
return lie.getInt() & PHI_BIT;
|
||||
}
|
||||
|
||||
/// Returns the base index for associated with this index. The base index
|
||||
/// is the one associated with the LOAD slot for the instruction pointed to
|
||||
/// by this index.
|
||||
SlotIndex getBaseIndex() const {
|
||||
return getLoadIndex();
|
||||
}
|
||||
|
||||
/// Returns the boundary index for associated with this index. The boundary
|
||||
/// index is the one associated with the LOAD slot for the instruction
|
||||
/// pointed to by this index.
|
||||
SlotIndex getBoundaryIndex() const {
|
||||
return getStoreIndex();
|
||||
}
|
||||
|
||||
/// Returns the index of the LOAD slot for the instruction pointed to by
|
||||
/// this index.
|
||||
SlotIndex getLoadIndex() const {
|
||||
return SlotIndex(&entry(), SlotIndex::LOAD);
|
||||
}
|
||||
|
||||
/// Returns the index of the USE slot for the instruction pointed to by
|
||||
/// this index.
|
||||
SlotIndex getUseIndex() const {
|
||||
return SlotIndex(&entry(), SlotIndex::USE);
|
||||
}
|
||||
|
||||
/// Returns the index of the DEF slot for the instruction pointed to by
|
||||
/// this index.
|
||||
SlotIndex getDefIndex() const {
|
||||
return SlotIndex(&entry(), SlotIndex::DEF);
|
||||
}
|
||||
|
||||
/// Returns the index of the STORE slot for the instruction pointed to by
|
||||
/// this index.
|
||||
SlotIndex getStoreIndex() const {
|
||||
return SlotIndex(&entry(), SlotIndex::STORE);
|
||||
}
|
||||
|
||||
/// Returns the next slot in the index list. This could be either the
|
||||
/// next slot for the instruction pointed to by this index or, if this
|
||||
/// index is a STORE, the first slot for the next instruction.
|
||||
/// WARNING: This method is considerably more expensive than the methods
|
||||
/// that return specific slots (getUseIndex(), etc). If you can - please
|
||||
/// use one of those methods.
|
||||
SlotIndex getNextSlot() const {
|
||||
Slot s = getSlot();
|
||||
if (s == SlotIndex::STORE) {
|
||||
return SlotIndex(entry().getNext(), SlotIndex::LOAD);
|
||||
}
|
||||
return SlotIndex(&entry(), s + 1);
|
||||
}
|
||||
|
||||
/// Returns the next index. This is the index corresponding to the this
|
||||
/// index's slot, but for the next instruction.
|
||||
SlotIndex getNextIndex() const {
|
||||
return SlotIndex(entry().getNext(), getSlot());
|
||||
}
|
||||
|
||||
/// Returns the previous slot in the index list. This could be either the
|
||||
/// previous slot for the instruction pointed to by this index or, if this
|
||||
/// index is a LOAD, the last slot for the previous instruction.
|
||||
/// WARNING: This method is considerably more expensive than the methods
|
||||
/// that return specific slots (getUseIndex(), etc). If you can - please
|
||||
/// use one of those methods.
|
||||
SlotIndex getPrevSlot() const {
|
||||
Slot s = getSlot();
|
||||
if (s == SlotIndex::LOAD) {
|
||||
return SlotIndex(entry().getPrev(), SlotIndex::STORE);
|
||||
}
|
||||
return SlotIndex(&entry(), s - 1);
|
||||
}
|
||||
|
||||
/// Returns the previous index. This is the index corresponding to this
|
||||
/// index's slot, but for the previous instruction.
|
||||
SlotIndex getPrevIndex() const {
|
||||
return SlotIndex(entry().getPrev(), getSlot());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// DenseMapInfo specialization for SlotIndex.
|
||||
template <>
|
||||
struct DenseMapInfo<SlotIndex> {
|
||||
static inline SlotIndex getEmptyKey() {
|
||||
return SlotIndex::getEmptyKey();
|
||||
}
|
||||
static inline SlotIndex getTombstoneKey() {
|
||||
return SlotIndex::getTombstoneKey();
|
||||
}
|
||||
static inline unsigned getHashValue(const SlotIndex &v) {
|
||||
return SlotIndex::getHashValue(v);
|
||||
}
|
||||
static inline bool isEqual(const SlotIndex &LHS, const SlotIndex &RHS) {
|
||||
return (LHS == RHS);
|
||||
}
|
||||
static inline bool isPod() { return false; }
|
||||
};
|
||||
|
||||
inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
|
||||
li.print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
typedef std::pair<SlotIndex, MachineBasicBlock*> IdxMBBPair;
|
||||
|
||||
inline bool operator<(SlotIndex V, const IdxMBBPair &IM) {
|
||||
return V < IM.first;
|
||||
}
|
||||
|
||||
inline bool operator<(const IdxMBBPair &IM, SlotIndex V) {
|
||||
return IM.first < V;
|
||||
}
|
||||
|
||||
struct Idx2MBBCompare {
|
||||
bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const {
|
||||
return LHS.first < RHS.first;
|
||||
}
|
||||
};
|
||||
|
||||
/// SlotIndexes pass.
|
||||
///
|
||||
/// This pass assigns indexes to each instruction.
|
||||
class SlotIndexes : public MachineFunctionPass {
|
||||
private:
|
||||
|
||||
MachineFunction *mf;
|
||||
IndexListEntry *indexListHead;
|
||||
unsigned functionSize;
|
||||
|
||||
typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap;
|
||||
Mi2IndexMap mi2iMap;
|
||||
|
||||
/// MBB2IdxMap - The indexes of the first and last instructions in the
|
||||
/// specified basic block.
|
||||
typedef DenseMap<const MachineBasicBlock*,
|
||||
std::pair<SlotIndex, SlotIndex> > MBB2IdxMap;
|
||||
MBB2IdxMap mbb2IdxMap;
|
||||
|
||||
/// Idx2MBBMap - Sorted list of pairs of index of first instruction
|
||||
/// and MBB id.
|
||||
std::vector<IdxMBBPair> idx2MBBMap;
|
||||
|
||||
typedef DenseMap<const MachineBasicBlock*, SlotIndex> TerminatorGapsMap;
|
||||
TerminatorGapsMap terminatorGaps;
|
||||
|
||||
// IndexListEntry allocator.
|
||||
BumpPtrAllocator ileAllocator;
|
||||
|
||||
IndexListEntry* createEntry(MachineInstr *mi, unsigned index) {
|
||||
IndexListEntry *entry =
|
||||
static_cast<IndexListEntry*>(
|
||||
ileAllocator.Allocate(sizeof(IndexListEntry),
|
||||
alignof<IndexListEntry>()));
|
||||
|
||||
new (entry) IndexListEntry(mi, index);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void initList() {
|
||||
assert(indexListHead == 0 && "Zero entry non-null at initialisation.");
|
||||
indexListHead = createEntry(0, ~0U);
|
||||
indexListHead->setNext(0);
|
||||
indexListHead->setPrev(indexListHead);
|
||||
}
|
||||
|
||||
void clearList() {
|
||||
indexListHead = 0;
|
||||
ileAllocator.Reset();
|
||||
}
|
||||
|
||||
IndexListEntry* getTail() {
|
||||
assert(indexListHead != 0 && "Call to getTail on uninitialized list.");
|
||||
return indexListHead->getPrev();
|
||||
}
|
||||
|
||||
const IndexListEntry* getTail() const {
|
||||
assert(indexListHead != 0 && "Call to getTail on uninitialized list.");
|
||||
return indexListHead->getPrev();
|
||||
}
|
||||
|
||||
// Returns true if the index list is empty.
|
||||
bool empty() const { return (indexListHead == getTail()); }
|
||||
|
||||
IndexListEntry* front() {
|
||||
assert(!empty() && "front() called on empty index list.");
|
||||
return indexListHead;
|
||||
}
|
||||
|
||||
const IndexListEntry* front() const {
|
||||
assert(!empty() && "front() called on empty index list.");
|
||||
return indexListHead;
|
||||
}
|
||||
|
||||
IndexListEntry* back() {
|
||||
assert(!empty() && "back() called on empty index list.");
|
||||
return getTail()->getPrev();
|
||||
}
|
||||
|
||||
const IndexListEntry* back() const {
|
||||
assert(!empty() && "back() called on empty index list.");
|
||||
return getTail()->getPrev();
|
||||
}
|
||||
|
||||
/// Insert a new entry before itr.
|
||||
void insert(IndexListEntry *itr, IndexListEntry *val) {
|
||||
assert(itr != 0 && "itr should not be null.");
|
||||
IndexListEntry *prev = itr->getPrev();
|
||||
val->setNext(itr);
|
||||
val->setPrev(prev);
|
||||
|
||||
if (itr != indexListHead) {
|
||||
prev->setNext(val);
|
||||
}
|
||||
else {
|
||||
indexListHead = val;
|
||||
}
|
||||
itr->setPrev(val);
|
||||
}
|
||||
|
||||
/// Push a new entry on to the end of the list.
|
||||
void push_back(IndexListEntry *val) {
|
||||
insert(getTail(), val);
|
||||
}
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
SlotIndexes() : MachineFunctionPass(&ID), indexListHead(0) {}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &au) const;
|
||||
virtual void releaseMemory();
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &fn);
|
||||
|
||||
/// Dump the indexes.
|
||||
void dump() const;
|
||||
|
||||
/// Renumber the index list, providing space for new instructions.
|
||||
void renumber();
|
||||
|
||||
/// Returns the zero index for this analysis.
|
||||
SlotIndex getZeroIndex() {
|
||||
assert(front()->getIndex() == 0 && "First index is not 0?");
|
||||
return SlotIndex(front(), 0);
|
||||
}
|
||||
|
||||
/// Returns the invalid index marker for this analysis.
|
||||
SlotIndex getInvalidIndex() {
|
||||
return getZeroIndex();
|
||||
}
|
||||
|
||||
/// Returns the distance between the highest and lowest indexes allocated
|
||||
/// so far.
|
||||
unsigned getIndexesLength() const {
|
||||
assert(front()->getIndex() == 0 &&
|
||||
"Initial index isn't zero?");
|
||||
|
||||
return back()->getIndex();
|
||||
}
|
||||
|
||||
/// Returns the number of instructions in the function.
|
||||
unsigned getFunctionSize() const {
|
||||
return functionSize;
|
||||
}
|
||||
|
||||
/// Returns true if the given machine instr is mapped to an index,
|
||||
/// otherwise returns false.
|
||||
bool hasIndex(const MachineInstr *instr) const {
|
||||
return (mi2iMap.find(instr) != mi2iMap.end());
|
||||
}
|
||||
|
||||
/// Returns the base index for the given instruction.
|
||||
SlotIndex getInstructionIndex(const MachineInstr *instr) const {
|
||||
Mi2IndexMap::const_iterator itr = mi2iMap.find(instr);
|
||||
assert(itr != mi2iMap.end() && "Instruction not found in maps.");
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
/// Returns the instruction for the given index, or null if the given
|
||||
/// index has no instruction associated with it.
|
||||
MachineInstr* getInstructionFromIndex(SlotIndex index) const {
|
||||
return index.entry().getInstr();
|
||||
}
|
||||
|
||||
/// Returns the next non-null index.
|
||||
SlotIndex getNextNonNullIndex(SlotIndex index) {
|
||||
SlotIndex nextNonNull = index.getNextIndex();
|
||||
|
||||
while (&nextNonNull.entry() != getTail() &&
|
||||
getInstructionFromIndex(nextNonNull) == 0) {
|
||||
nextNonNull = nextNonNull.getNextIndex();
|
||||
}
|
||||
|
||||
return nextNonNull;
|
||||
}
|
||||
|
||||
/// Returns the first index in the given basic block.
|
||||
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
|
||||
MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb);
|
||||
assert(itr != mbb2IdxMap.end() && "MBB not found in maps.");
|
||||
return itr->second.first;
|
||||
}
|
||||
|
||||
/// Returns the last index in the given basic block.
|
||||
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
|
||||
MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb);
|
||||
assert(itr != mbb2IdxMap.end() && "MBB not found in maps.");
|
||||
return itr->second.second;
|
||||
}
|
||||
|
||||
/// Returns the terminator gap for the given index.
|
||||
SlotIndex getTerminatorGap(const MachineBasicBlock *mbb) {
|
||||
TerminatorGapsMap::iterator itr = terminatorGaps.find(mbb);
|
||||
assert(itr != terminatorGaps.end() &&
|
||||
"All MBBs should have terminator gaps in their indexes.");
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
/// Returns the basic block which the given index falls in.
|
||||
MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
|
||||
std::vector<IdxMBBPair>::const_iterator I =
|
||||
std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index);
|
||||
// Take the pair containing the index
|
||||
std::vector<IdxMBBPair>::const_iterator J =
|
||||
((I != idx2MBBMap.end() && I->first > index) ||
|
||||
(I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I;
|
||||
|
||||
assert(J != idx2MBBMap.end() && J->first <= index &&
|
||||
index <= getMBBEndIdx(J->second) &&
|
||||
"index does not correspond to an MBB");
|
||||
return J->second;
|
||||
}
|
||||
|
||||
bool findLiveInMBBs(SlotIndex start, SlotIndex end,
|
||||
SmallVectorImpl<MachineBasicBlock*> &mbbs) const {
|
||||
std::vector<IdxMBBPair>::const_iterator itr =
|
||||
std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
|
||||
bool resVal = false;
|
||||
|
||||
while (itr != idx2MBBMap.end()) {
|
||||
if (itr->first >= end)
|
||||
break;
|
||||
mbbs.push_back(itr->second);
|
||||
resVal = true;
|
||||
++itr;
|
||||
}
|
||||
return resVal;
|
||||
}
|
||||
|
||||
/// Return a list of MBBs that can be reach via any branches or
|
||||
/// fall-throughs.
|
||||
bool findReachableMBBs(SlotIndex start, SlotIndex end,
|
||||
SmallVectorImpl<MachineBasicBlock*> &mbbs) const {
|
||||
std::vector<IdxMBBPair>::const_iterator itr =
|
||||
std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
|
||||
|
||||
bool resVal = false;
|
||||
while (itr != idx2MBBMap.end()) {
|
||||
if (itr->first > end)
|
||||
break;
|
||||
MachineBasicBlock *mbb = itr->second;
|
||||
if (getMBBEndIdx(mbb) > end)
|
||||
break;
|
||||
for (MachineBasicBlock::succ_iterator si = mbb->succ_begin(),
|
||||
se = mbb->succ_end(); si != se; ++si)
|
||||
mbbs.push_back(*si);
|
||||
resVal = true;
|
||||
++itr;
|
||||
}
|
||||
return resVal;
|
||||
}
|
||||
|
||||
/// Returns the MBB covering the given range, or null if the range covers
|
||||
/// more than one basic block.
|
||||
MachineBasicBlock* getMBBCoveringRange(SlotIndex start, SlotIndex end) const {
|
||||
|
||||
assert(start < end && "Backwards ranges not allowed.");
|
||||
|
||||
std::vector<IdxMBBPair>::const_iterator itr =
|
||||
std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
|
||||
|
||||
if (itr == idx2MBBMap.end()) {
|
||||
itr = prior(itr);
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
// Check that we don't cross the boundary into this block.
|
||||
if (itr->first < end)
|
||||
return 0;
|
||||
|
||||
itr = prior(itr);
|
||||
|
||||
if (itr->first <= start)
|
||||
return itr->second;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Returns true if there is a gap in the numbering before the given index.
|
||||
bool hasGapBeforeInstr(SlotIndex index) {
|
||||
index = index.getBaseIndex();
|
||||
SlotIndex prevIndex = index.getPrevIndex();
|
||||
|
||||
if (prevIndex == getZeroIndex())
|
||||
return false;
|
||||
|
||||
if (getInstructionFromIndex(prevIndex) == 0)
|
||||
return true;
|
||||
|
||||
if (prevIndex.distance(index) >= 2 * SlotIndex::NUM)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns true if there is a gap in the numbering after the given index.
|
||||
bool hasGapAfterInstr(SlotIndex index) const {
|
||||
// Not implemented yet.
|
||||
assert(false &&
|
||||
"SlotIndexes::hasGapAfterInstr(SlotIndex) not implemented yet.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// findGapBeforeInstr - Find an empty instruction slot before the
|
||||
/// specified index. If "Furthest" is true, find one that's furthest
|
||||
/// away from the index (but before any index that's occupied).
|
||||
// FIXME: This whole method should go away in future. It should
|
||||
// always be possible to insert code between existing indices.
|
||||
SlotIndex findGapBeforeInstr(SlotIndex index, bool furthest = false) {
|
||||
if (index == getZeroIndex())
|
||||
return getInvalidIndex();
|
||||
|
||||
index = index.getBaseIndex();
|
||||
SlotIndex prevIndex = index.getPrevIndex();
|
||||
|
||||
if (prevIndex == getZeroIndex())
|
||||
return getInvalidIndex();
|
||||
|
||||
// Try to reuse existing index objects with null-instrs.
|
||||
if (getInstructionFromIndex(prevIndex) == 0) {
|
||||
if (furthest) {
|
||||
while (getInstructionFromIndex(prevIndex) == 0 &&
|
||||
prevIndex != getZeroIndex()) {
|
||||
prevIndex = prevIndex.getPrevIndex();
|
||||
}
|
||||
|
||||
prevIndex = prevIndex.getNextIndex();
|
||||
}
|
||||
|
||||
assert(getInstructionFromIndex(prevIndex) == 0 && "Index list is broken.");
|
||||
|
||||
return prevIndex;
|
||||
}
|
||||
|
||||
int dist = prevIndex.distance(index);
|
||||
|
||||
// Double check that the spacing between this instruction and
|
||||
// the last is sane.
|
||||
assert(dist >= SlotIndex::NUM &&
|
||||
"Distance between indexes too small.");
|
||||
|
||||
// If there's no gap return an invalid index.
|
||||
if (dist < 2*SlotIndex::NUM) {
|
||||
return getInvalidIndex();
|
||||
}
|
||||
|
||||
// Otherwise insert new index entries into the list using the
|
||||
// gap in the numbering.
|
||||
IndexListEntry *newEntry =
|
||||
createEntry(0, prevIndex.entry().getIndex() + SlotIndex::NUM);
|
||||
|
||||
insert(&index.entry(), newEntry);
|
||||
|
||||
// And return a pointer to the entry at the start of the gap.
|
||||
return index.getPrevIndex();
|
||||
}
|
||||
|
||||
/// Insert the given machine instruction into the mapping at the given
|
||||
/// index.
|
||||
void insertMachineInstrInMaps(MachineInstr *mi, SlotIndex index) {
|
||||
index = index.getBaseIndex();
|
||||
IndexListEntry *miEntry = &index.entry();
|
||||
assert(miEntry->getInstr() == 0 && "Index already in use.");
|
||||
miEntry->setInstr(mi);
|
||||
|
||||
assert(mi2iMap.find(mi) == mi2iMap.end() &&
|
||||
"MachineInstr already has an index.");
|
||||
|
||||
mi2iMap.insert(std::make_pair(mi, index));
|
||||
}
|
||||
|
||||
/// Remove the given machine instruction from the mapping.
|
||||
void removeMachineInstrFromMaps(MachineInstr *mi) {
|
||||
// remove index -> MachineInstr and
|
||||
// MachineInstr -> index mappings
|
||||
Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi);
|
||||
if (mi2iItr != mi2iMap.end()) {
|
||||
IndexListEntry *miEntry(&mi2iItr->second.entry());
|
||||
assert(miEntry->getInstr() == mi && "Instruction indexes broken.");
|
||||
// FIXME: Eventually we want to actually delete these indexes.
|
||||
miEntry->setInstr(0);
|
||||
mi2iMap.erase(mi2iItr);
|
||||
}
|
||||
}
|
||||
|
||||
/// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
|
||||
/// maps used by register allocator.
|
||||
void replaceMachineInstrInMaps(MachineInstr *mi, MachineInstr *newMI) {
|
||||
Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi);
|
||||
if (mi2iItr == mi2iMap.end())
|
||||
return;
|
||||
SlotIndex replaceBaseIndex = mi2iItr->second;
|
||||
IndexListEntry *miEntry(&replaceBaseIndex.entry());
|
||||
assert(miEntry->getInstr() == mi &&
|
||||
"Mismatched instruction in index tables.");
|
||||
miEntry->setInstr(newMI);
|
||||
mi2iMap.erase(mi2iItr);
|
||||
mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // LLVM_CODEGEN_LIVEINDEX_H
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -48,6 +48,10 @@ class Constant : public User {
|
||||
: User(ty, vty, Ops, NumOps) {}
|
||||
|
||||
void destroyConstantImpl();
|
||||
|
||||
void setOperand(unsigned i, Value *V) {
|
||||
User::setOperand(i, V);
|
||||
}
|
||||
public:
|
||||
/// isNullValue - Return true if this is the value that would be returned by
|
||||
/// getNullValue.
|
||||
@ -61,6 +65,10 @@ class Constant : public User {
|
||||
/// true for things like constant expressions that could divide by zero.
|
||||
bool canTrap() const;
|
||||
|
||||
/// isConstantUsed - Return true if the constant has users other than constant
|
||||
/// exprs and other dangling things.
|
||||
bool isConstantUsed() const;
|
||||
|
||||
enum PossibleRelocationsTy {
|
||||
NoRelocation = 0,
|
||||
LocalRelocation = 1,
|
||||
@ -83,16 +91,13 @@ class Constant : public User {
|
||||
/// FIXME: This really should not be in VMCore.
|
||||
PossibleRelocationsTy getRelocationInfo() const;
|
||||
|
||||
// Specialize get/setOperand for Constants as their operands are always
|
||||
// constants as well.
|
||||
Constant *getOperand(unsigned i) {
|
||||
return static_cast<Constant*>(User::getOperand(i));
|
||||
// Specialize get/setOperand for Users as their operands are always
|
||||
// constants or BasicBlocks as well.
|
||||
User *getOperand(unsigned i) {
|
||||
return static_cast<User*>(User::getOperand(i));
|
||||
}
|
||||
const Constant *getOperand(unsigned i) const {
|
||||
return static_cast<const Constant*>(User::getOperand(i));
|
||||
}
|
||||
void setOperand(unsigned i, Constant *C) {
|
||||
User::setOperand(i, C);
|
||||
const User *getOperand(unsigned i) const {
|
||||
return static_cast<const User*>(User::getOperand(i));
|
||||
}
|
||||
|
||||
/// getVectorElements - This method, which is only valid on constant of vector
|
||||
|
@ -549,7 +549,47 @@ class ConstantPointerNull : public Constant {
|
||||
}
|
||||
};
|
||||
|
||||
/// BlockAddress - The address of a basic block.
|
||||
///
|
||||
class BlockAddress : public Constant {
|
||||
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
|
||||
void *operator new(size_t s) { return User::operator new(s, 2); }
|
||||
BlockAddress(Function *F, BasicBlock *BB);
|
||||
public:
|
||||
/// get - Return a BlockAddress for the specified function and basic block.
|
||||
static BlockAddress *get(Function *F, BasicBlock *BB);
|
||||
|
||||
/// get - Return a BlockAddress for the specified basic block. The basic
|
||||
/// block must be embedded into a function.
|
||||
static BlockAddress *get(BasicBlock *BB);
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
Function *getFunction() const { return (Function*)Op<0>().get(); }
|
||||
BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
|
||||
|
||||
/// isNullValue - Return true if this is the value that would be returned by
|
||||
/// getNullValue.
|
||||
virtual bool isNullValue() const { return false; }
|
||||
|
||||
virtual void destroyConstant();
|
||||
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const BlockAddress *) { return true; }
|
||||
static inline bool classof(const Value *V) {
|
||||
return V->getValueID() == BlockAddressVal;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperandTraits<BlockAddress> : public FixedNumOperandTraits<2> {
|
||||
};
|
||||
|
||||
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// ConstantExpr - a constant value that is initialized with an expression using
|
||||
/// other constant values.
|
||||
///
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/ValueMap.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/System/Mutex.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
@ -42,26 +43,23 @@ class Type;
|
||||
|
||||
class ExecutionEngineState {
|
||||
public:
|
||||
class MapUpdatingCVH : public CallbackVH {
|
||||
ExecutionEngineState &EES;
|
||||
|
||||
public:
|
||||
MapUpdatingCVH(ExecutionEngineState &EES, const GlobalValue *GV);
|
||||
|
||||
operator const GlobalValue*() const {
|
||||
return cast<GlobalValue>(getValPtr());
|
||||
}
|
||||
|
||||
virtual void deleted();
|
||||
virtual void allUsesReplacedWith(Value *new_value);
|
||||
struct AddressMapConfig : public ValueMapConfig<const GlobalValue*> {
|
||||
typedef ExecutionEngineState *ExtraData;
|
||||
static sys::Mutex *getMutex(ExecutionEngineState *EES);
|
||||
static void onDelete(ExecutionEngineState *EES, const GlobalValue *Old);
|
||||
static void onRAUW(ExecutionEngineState *, const GlobalValue *,
|
||||
const GlobalValue *);
|
||||
};
|
||||
|
||||
typedef ValueMap<const GlobalValue *, void *, AddressMapConfig>
|
||||
GlobalAddressMapTy;
|
||||
|
||||
private:
|
||||
ExecutionEngine &EE;
|
||||
|
||||
/// GlobalAddressMap - A mapping between LLVM global values and their
|
||||
/// actualized version...
|
||||
std::map<MapUpdatingCVH, void *> GlobalAddressMap;
|
||||
GlobalAddressMapTy GlobalAddressMap;
|
||||
|
||||
/// GlobalAddressReverseMap - This is the reverse mapping of GlobalAddressMap,
|
||||
/// used to convert raw addresses into the LLVM global value that is emitted
|
||||
@ -70,13 +68,9 @@ class ExecutionEngineState {
|
||||
std::map<void *, AssertingVH<const GlobalValue> > GlobalAddressReverseMap;
|
||||
|
||||
public:
|
||||
ExecutionEngineState(ExecutionEngine &EE) : EE(EE) {}
|
||||
ExecutionEngineState(ExecutionEngine &EE);
|
||||
|
||||
MapUpdatingCVH getVH(const GlobalValue *GV) {
|
||||
return MapUpdatingCVH(*this, GV);
|
||||
}
|
||||
|
||||
std::map<MapUpdatingCVH, void *> &
|
||||
GlobalAddressMapTy &
|
||||
getGlobalAddressMap(const MutexGuard &) {
|
||||
return GlobalAddressMap;
|
||||
}
|
||||
@ -94,7 +88,7 @@ class ExecutionEngineState {
|
||||
class ExecutionEngine {
|
||||
const TargetData *TD;
|
||||
ExecutionEngineState EEState;
|
||||
bool LazyCompilationDisabled;
|
||||
bool CompilingLazily;
|
||||
bool GVCompilationDisabled;
|
||||
bool SymbolSearchingDisabled;
|
||||
bool DlsymStubsEnabled;
|
||||
@ -269,12 +263,17 @@ class ExecutionEngine {
|
||||
/// getPointerToFunction - The different EE's represent function bodies in
|
||||
/// different ways. They should each implement this to say what a function
|
||||
/// pointer should look like. When F is destroyed, the ExecutionEngine will
|
||||
/// remove its global mapping but will not yet free its machine code. Call
|
||||
/// freeMachineCodeForFunction(F) explicitly to do that. Note that global
|
||||
/// optimizations can destroy Functions without notifying the ExecutionEngine.
|
||||
/// remove its global mapping and free any machine code. Be sure no threads
|
||||
/// are running inside F when that happens.
|
||||
///
|
||||
virtual void *getPointerToFunction(Function *F) = 0;
|
||||
|
||||
/// getPointerToBasicBlock - The different EE's represent basic blocks in
|
||||
/// different ways. Return the representation for a blockaddress of the
|
||||
/// specified block.
|
||||
///
|
||||
virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0;
|
||||
|
||||
/// getPointerToFunctionOrStub - If the specified function has been
|
||||
/// code-gen'd, return a pointer to the function. If not, compile it, or use
|
||||
/// a stub to implement lazy compilation if available. See
|
||||
@ -326,13 +325,29 @@ class ExecutionEngine {
|
||||
virtual void RegisterJITEventListener(JITEventListener *) {}
|
||||
virtual void UnregisterJITEventListener(JITEventListener *) {}
|
||||
|
||||
/// DisableLazyCompilation - If called, the JIT will abort if lazy compilation
|
||||
/// is ever attempted.
|
||||
/// DisableLazyCompilation - When lazy compilation is off (the default), the
|
||||
/// JIT will eagerly compile every function reachable from the argument to
|
||||
/// getPointerToFunction. If lazy compilation is turned on, the JIT will only
|
||||
/// compile the one function and emit stubs to compile the rest when they're
|
||||
/// first called. If lazy compilation is turned off again while some lazy
|
||||
/// stubs are still around, and one of those stubs is called, the program will
|
||||
/// abort.
|
||||
///
|
||||
/// In order to safely compile lazily in a threaded program, the user must
|
||||
/// ensure that 1) only one thread at a time can call any particular lazy
|
||||
/// stub, and 2) any thread modifying LLVM IR must hold the JIT's lock
|
||||
/// (ExecutionEngine::lock) or otherwise ensure that no other thread calls a
|
||||
/// lazy stub. See http://llvm.org/PR5184 for details.
|
||||
void DisableLazyCompilation(bool Disabled = true) {
|
||||
LazyCompilationDisabled = Disabled;
|
||||
CompilingLazily = !Disabled;
|
||||
}
|
||||
bool isCompilingLazily() const {
|
||||
return CompilingLazily;
|
||||
}
|
||||
// Deprecated in favor of isCompilingLazily (to reduce double-negatives).
|
||||
// Remove this in LLVM 2.8.
|
||||
bool isLazyCompilationDisabled() const {
|
||||
return LazyCompilationDisabled;
|
||||
return !CompilingLazily;
|
||||
}
|
||||
|
||||
/// DisableGVCompilation - If called, the JIT will abort if it's asked to
|
||||
@ -485,15 +500,8 @@ class EngineBuilder {
|
||||
}
|
||||
|
||||
ExecutionEngine *create();
|
||||
|
||||
};
|
||||
|
||||
inline bool operator<(const ExecutionEngineState::MapUpdatingCVH& lhs,
|
||||
const ExecutionEngineState::MapUpdatingCVH& rhs) {
|
||||
return static_cast<const GlobalValue*>(lhs) <
|
||||
static_cast<const GlobalValue*>(rhs);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define GENERIC_VALUE_H
|
||||
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
|
||||
#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
|
||||
#include <vector>
|
||||
@ -63,8 +63,11 @@ class JITEventListener {
|
||||
/// NotifyFreeingMachineCode - This is called inside of
|
||||
/// freeMachineCodeForFunction(), after the global mapping is removed, but
|
||||
/// before the machine code is returned to the allocator. OldPtr is the
|
||||
/// address of the machine code.
|
||||
virtual void NotifyFreeingMachineCode(const Function &F, void *OldPtr) {}
|
||||
/// address of the machine code and will be the same as the Code parameter to
|
||||
/// a previous NotifyFunctionEmitted call. The Function passed to
|
||||
/// NotifyFunctionEmitted may have been destroyed by the time of the matching
|
||||
/// NotifyFreeingMachineCode call.
|
||||
virtual void NotifyFreeingMachineCode(void *OldPtr) {}
|
||||
};
|
||||
|
||||
// This returns NULL if support isn't available.
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
|
||||
#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -51,10 +51,9 @@ class TerminatorInst : public Instruction {
|
||||
virtual BasicBlock *getSuccessorV(unsigned idx) const = 0;
|
||||
virtual unsigned getNumSuccessorsV() const = 0;
|
||||
virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0;
|
||||
virtual TerminatorInst *clone_impl() const = 0;
|
||||
public:
|
||||
|
||||
virtual TerminatorInst *clone() const = 0;
|
||||
|
||||
/// getNumSuccessors - Return the number of successors that this terminator
|
||||
/// has.
|
||||
unsigned getNumSuccessors() const {
|
||||
@ -117,7 +116,6 @@ class UnaryInstruction : public Instruction {
|
||||
static inline bool classof(const UnaryInstruction *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::Alloca ||
|
||||
I->getOpcode() == Instruction::Free ||
|
||||
I->getOpcode() == Instruction::Load ||
|
||||
I->getOpcode() == Instruction::VAArg ||
|
||||
I->getOpcode() == Instruction::ExtractValue ||
|
||||
@ -146,6 +144,7 @@ class BinaryOperator : public Instruction {
|
||||
const Twine &Name, Instruction *InsertBefore);
|
||||
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
|
||||
const Twine &Name, BasicBlock *InsertAtEnd);
|
||||
virtual BinaryOperator *clone_impl() const;
|
||||
public:
|
||||
// allocate space for exactly two operands
|
||||
void *operator new(size_t s) {
|
||||
@ -298,8 +297,6 @@ class BinaryOperator : public Instruction {
|
||||
return static_cast<BinaryOps>(Instruction::getOpcode());
|
||||
}
|
||||
|
||||
virtual BinaryOperator *clone() const;
|
||||
|
||||
/// swapOperands - Exchange the two operands to this instruction.
|
||||
/// This instruction is safe to use on any binary instruction and
|
||||
/// does not modify the semantics of the instruction. If the instruction
|
||||
@ -718,6 +715,30 @@ class CmpInst: public Instruction {
|
||||
/// @brief Determine if this is an equals/not equals predicate.
|
||||
bool isEquality();
|
||||
|
||||
/// @returns true if the comparison is signed, false otherwise.
|
||||
/// @brief Determine if this instruction is using a signed comparison.
|
||||
bool isSigned() const {
|
||||
return isSigned(getPredicate());
|
||||
}
|
||||
|
||||
/// @returns true if the comparison is unsigned, false otherwise.
|
||||
/// @brief Determine if this instruction is using an unsigned comparison.
|
||||
bool isUnsigned() const {
|
||||
return isUnsigned(getPredicate());
|
||||
}
|
||||
|
||||
/// This is just a convenience.
|
||||
/// @brief Determine if this is true when both operands are the same.
|
||||
bool isTrueWhenEqual() const {
|
||||
return isTrueWhenEqual(getPredicate());
|
||||
}
|
||||
|
||||
/// This is just a convenience.
|
||||
/// @brief Determine if this is false when both operands are the same.
|
||||
bool isFalseWhenEqual() const {
|
||||
return isFalseWhenEqual(getPredicate());
|
||||
}
|
||||
|
||||
/// @returns true if the predicate is unsigned, false otherwise.
|
||||
/// @brief Determine if the predicate is an unsigned operation.
|
||||
static bool isUnsigned(unsigned short predicate);
|
||||
@ -732,6 +753,12 @@ class CmpInst: public Instruction {
|
||||
/// @brief Determine if the predicate is an unordered operation.
|
||||
static bool isUnordered(unsigned short predicate);
|
||||
|
||||
/// Determine if the predicate is true when comparing a value with itself.
|
||||
static bool isTrueWhenEqual(unsigned short predicate);
|
||||
|
||||
/// Determine if the predicate is false when comparing a value with itself.
|
||||
static bool isFalseWhenEqual(unsigned short predicate);
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const CmpInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
|
@ -97,38 +97,38 @@
|
||||
HANDLE_TERM_INST ( 1, Ret , ReturnInst)
|
||||
HANDLE_TERM_INST ( 2, Br , BranchInst)
|
||||
HANDLE_TERM_INST ( 3, Switch , SwitchInst)
|
||||
HANDLE_TERM_INST ( 4, Invoke , InvokeInst)
|
||||
HANDLE_TERM_INST ( 5, Unwind , UnwindInst)
|
||||
HANDLE_TERM_INST ( 6, Unreachable, UnreachableInst)
|
||||
LAST_TERM_INST ( 6)
|
||||
HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
|
||||
HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
|
||||
HANDLE_TERM_INST ( 6, Unwind , UnwindInst)
|
||||
HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst)
|
||||
LAST_TERM_INST ( 7)
|
||||
|
||||
// Standard binary operators...
|
||||
FIRST_BINARY_INST( 7)
|
||||
HANDLE_BINARY_INST( 7, Add , BinaryOperator)
|
||||
HANDLE_BINARY_INST( 8, FAdd , BinaryOperator)
|
||||
HANDLE_BINARY_INST( 9, Sub , BinaryOperator)
|
||||
HANDLE_BINARY_INST(10, FSub , BinaryOperator)
|
||||
HANDLE_BINARY_INST(11, Mul , BinaryOperator)
|
||||
HANDLE_BINARY_INST(12, FMul , BinaryOperator)
|
||||
HANDLE_BINARY_INST(13, UDiv , BinaryOperator)
|
||||
HANDLE_BINARY_INST(14, SDiv , BinaryOperator)
|
||||
HANDLE_BINARY_INST(15, FDiv , BinaryOperator)
|
||||
HANDLE_BINARY_INST(16, URem , BinaryOperator)
|
||||
HANDLE_BINARY_INST(17, SRem , BinaryOperator)
|
||||
HANDLE_BINARY_INST(18, FRem , BinaryOperator)
|
||||
FIRST_BINARY_INST( 8)
|
||||
HANDLE_BINARY_INST( 8, Add , BinaryOperator)
|
||||
HANDLE_BINARY_INST( 9, FAdd , BinaryOperator)
|
||||
HANDLE_BINARY_INST(10, Sub , BinaryOperator)
|
||||
HANDLE_BINARY_INST(11, FSub , BinaryOperator)
|
||||
HANDLE_BINARY_INST(12, Mul , BinaryOperator)
|
||||
HANDLE_BINARY_INST(13, FMul , BinaryOperator)
|
||||
HANDLE_BINARY_INST(14, UDiv , BinaryOperator)
|
||||
HANDLE_BINARY_INST(15, SDiv , BinaryOperator)
|
||||
HANDLE_BINARY_INST(16, FDiv , BinaryOperator)
|
||||
HANDLE_BINARY_INST(17, URem , BinaryOperator)
|
||||
HANDLE_BINARY_INST(18, SRem , BinaryOperator)
|
||||
HANDLE_BINARY_INST(19, FRem , BinaryOperator)
|
||||
|
||||
// Logical operators (integer operands)
|
||||
HANDLE_BINARY_INST(19, Shl , BinaryOperator) // Shift left (logical)
|
||||
HANDLE_BINARY_INST(20, LShr , BinaryOperator) // Shift right (logical)
|
||||
HANDLE_BINARY_INST(21, AShr , BinaryOperator) // Shift right (arithmetic)
|
||||
HANDLE_BINARY_INST(22, And , BinaryOperator)
|
||||
HANDLE_BINARY_INST(23, Or , BinaryOperator)
|
||||
HANDLE_BINARY_INST(24, Xor , BinaryOperator)
|
||||
LAST_BINARY_INST(24)
|
||||
HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical)
|
||||
HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical)
|
||||
HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic)
|
||||
HANDLE_BINARY_INST(23, And , BinaryOperator)
|
||||
HANDLE_BINARY_INST(24, Or , BinaryOperator)
|
||||
HANDLE_BINARY_INST(25, Xor , BinaryOperator)
|
||||
LAST_BINARY_INST(25)
|
||||
|
||||
// Memory operators...
|
||||
FIRST_MEMORY_INST(25)
|
||||
HANDLE_MEMORY_INST(25, Free , FreeInst ) // Heap management instructions
|
||||
FIRST_MEMORY_INST(26)
|
||||
HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management
|
||||
HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs
|
||||
HANDLE_MEMORY_INST(28, Store , StoreInst )
|
||||
|
@ -38,6 +38,7 @@ class Instruction : public User, public ilist_node<Instruction> {
|
||||
Instruction *InsertBefore = 0);
|
||||
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
|
||||
BasicBlock *InsertAtEnd);
|
||||
virtual Instruction *clone_impl() const = 0;
|
||||
public:
|
||||
// Out of line virtual method, so the vtable, etc has a home.
|
||||
~Instruction();
|
||||
@ -47,7 +48,7 @@ class Instruction : public User, public ilist_node<Instruction> {
|
||||
/// * The instruction has no parent
|
||||
/// * The instruction has no name
|
||||
///
|
||||
virtual Instruction *clone() const = 0;
|
||||
Instruction *clone() const;
|
||||
|
||||
/// isIdenticalTo - Return true if the specified instruction is exactly
|
||||
/// identical to the current one. This means that all operands match and any
|
||||
|
@ -19,9 +19,7 @@
|
||||
#include "llvm/InstrTypes.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Attributes.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/CallingConv.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <iterator>
|
||||
|
||||
@ -34,22 +32,30 @@ class LLVMContext;
|
||||
class DominatorTree;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// AllocationInst Class
|
||||
// AllocaInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// AllocationInst - This class is the base class of AllocaInst.
|
||||
/// AllocaInst - an instruction to allocate memory on the stack
|
||||
///
|
||||
class AllocationInst : public UnaryInstruction {
|
||||
class AllocaInst : public UnaryInstruction {
|
||||
protected:
|
||||
AllocationInst(const Type *Ty, Value *ArraySize,
|
||||
unsigned iTy, unsigned Align, const Twine &Name = "",
|
||||
Instruction *InsertBefore = 0);
|
||||
AllocationInst(const Type *Ty, Value *ArraySize,
|
||||
unsigned iTy, unsigned Align, const Twine &Name,
|
||||
BasicBlock *InsertAtEnd);
|
||||
virtual AllocaInst *clone_impl() const;
|
||||
public:
|
||||
explicit AllocaInst(const Type *Ty, Value *ArraySize = 0,
|
||||
const Twine &Name = "", Instruction *InsertBefore = 0);
|
||||
AllocaInst(const Type *Ty, Value *ArraySize,
|
||||
const Twine &Name, BasicBlock *InsertAtEnd);
|
||||
|
||||
AllocaInst(const Type *Ty, const Twine &Name, Instruction *InsertBefore = 0);
|
||||
AllocaInst(const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd);
|
||||
|
||||
AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align,
|
||||
const Twine &Name = "", Instruction *InsertBefore = 0);
|
||||
AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align,
|
||||
const Twine &Name, BasicBlock *InsertAtEnd);
|
||||
|
||||
// Out of line virtual method, so the vtable, etc. has a home.
|
||||
virtual ~AllocationInst();
|
||||
virtual ~AllocaInst();
|
||||
|
||||
/// isArrayAllocation - Return true if there is an allocation size parameter
|
||||
/// to the allocation instruction that is not 1.
|
||||
@ -79,58 +85,6 @@ class AllocationInst : public UnaryInstruction {
|
||||
unsigned getAlignment() const { return (1u << SubclassData) >> 1; }
|
||||
void setAlignment(unsigned Align);
|
||||
|
||||
virtual AllocationInst *clone() const = 0;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const AllocationInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::Alloca;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// AllocaInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// AllocaInst - an instruction to allocate memory on the stack
|
||||
///
|
||||
class AllocaInst : public AllocationInst {
|
||||
public:
|
||||
explicit AllocaInst(const Type *Ty,
|
||||
Value *ArraySize = 0,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0)
|
||||
: AllocationInst(Ty, ArraySize, Alloca,
|
||||
0, NameStr, InsertBefore) {}
|
||||
AllocaInst(const Type *Ty,
|
||||
Value *ArraySize, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: AllocationInst(Ty, ArraySize, Alloca, 0, NameStr, InsertAtEnd) {}
|
||||
|
||||
AllocaInst(const Type *Ty, const Twine &NameStr,
|
||||
Instruction *InsertBefore = 0)
|
||||
: AllocationInst(Ty, 0, Alloca, 0, NameStr, InsertBefore) {}
|
||||
AllocaInst(const Type *Ty, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: AllocationInst(Ty, 0, Alloca, 0, NameStr, InsertAtEnd) {}
|
||||
|
||||
AllocaInst(const Type *Ty, Value *ArraySize,
|
||||
unsigned Align, const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0)
|
||||
: AllocationInst(Ty, ArraySize, Alloca,
|
||||
Align, NameStr, InsertBefore) {}
|
||||
AllocaInst(const Type *Ty, Value *ArraySize,
|
||||
unsigned Align, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: AllocationInst(Ty, ArraySize, Alloca,
|
||||
Align, NameStr, InsertAtEnd) {}
|
||||
|
||||
virtual AllocaInst *clone() const;
|
||||
|
||||
/// isStaticAlloca - Return true if this alloca is in the entry block of the
|
||||
/// function and is a constant size. If so, the code generator will fold it
|
||||
/// into the prolog/epilog code, so it is basically free.
|
||||
@ -147,35 +101,6 @@ class AllocaInst : public AllocationInst {
|
||||
};
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FreeInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// FreeInst - an instruction to deallocate memory
|
||||
///
|
||||
class FreeInst : public UnaryInstruction {
|
||||
void AssertOK();
|
||||
public:
|
||||
explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0);
|
||||
FreeInst(Value *Ptr, BasicBlock *InsertAfter);
|
||||
|
||||
virtual FreeInst *clone() const;
|
||||
|
||||
// Accessor methods for consistency with other memory operations
|
||||
Value *getPointerOperand() { return getOperand(0); }
|
||||
const Value *getPointerOperand() const { return getOperand(0); }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const FreeInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return (I->getOpcode() == Instruction::Free);
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LoadInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -185,6 +110,8 @@ class FreeInst : public UnaryInstruction {
|
||||
///
|
||||
class LoadInst : public UnaryInstruction {
|
||||
void AssertOK();
|
||||
protected:
|
||||
virtual LoadInst *clone_impl() const;
|
||||
public:
|
||||
LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore);
|
||||
LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
@ -215,8 +142,6 @@ class LoadInst : public UnaryInstruction {
|
||||
SubclassData = (SubclassData & ~1) | (V ? 1 : 0);
|
||||
}
|
||||
|
||||
virtual LoadInst *clone() const;
|
||||
|
||||
/// getAlignment - Return the alignment of the access that is being performed
|
||||
///
|
||||
unsigned getAlignment() const {
|
||||
@ -254,6 +179,8 @@ class LoadInst : public UnaryInstruction {
|
||||
class StoreInst : public Instruction {
|
||||
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
|
||||
void AssertOK();
|
||||
protected:
|
||||
virtual StoreInst *clone_impl() const;
|
||||
public:
|
||||
// allocate space for exactly two operands
|
||||
void *operator new(size_t s) {
|
||||
@ -292,8 +219,6 @@ class StoreInst : public Instruction {
|
||||
|
||||
void setAlignment(unsigned Align);
|
||||
|
||||
virtual StoreInst *clone() const;
|
||||
|
||||
Value *getPointerOperand() { return getOperand(1); }
|
||||
const Value *getPointerOperand() const { return getOperand(1); }
|
||||
static unsigned getPointerOperandIndex() { return 1U; }
|
||||
@ -402,6 +327,8 @@ class GetElementPtrInst : public Instruction {
|
||||
Instruction *InsertBefore = 0);
|
||||
GetElementPtrInst(Value *Ptr, Value *Idx,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual GetElementPtrInst *clone_impl() const;
|
||||
public:
|
||||
template<typename InputIterator>
|
||||
static GetElementPtrInst *Create(Value *Ptr, InputIterator IdxBegin,
|
||||
@ -475,8 +402,6 @@ class GetElementPtrInst : public Instruction {
|
||||
return GEP;
|
||||
}
|
||||
|
||||
virtual GetElementPtrInst *clone() const;
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
@ -623,6 +548,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
|
||||
/// must be identical types.
|
||||
/// @brief Represent an integer comparison operator.
|
||||
class ICmpInst: public CmpInst {
|
||||
protected:
|
||||
/// @brief Clone an indentical ICmpInst
|
||||
virtual ICmpInst *clone_impl() const;
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics.
|
||||
ICmpInst(
|
||||
@ -737,30 +665,6 @@ class ICmpInst: public CmpInst {
|
||||
return !isEquality(P);
|
||||
}
|
||||
|
||||
/// @returns true if the predicate of this ICmpInst is signed, false otherwise
|
||||
/// @brief Determine if this instruction's predicate is signed.
|
||||
bool isSignedPredicate() const { return isSignedPredicate(getPredicate()); }
|
||||
|
||||
/// @returns true if the predicate provided is signed, false otherwise
|
||||
/// @brief Determine if the predicate is signed.
|
||||
static bool isSignedPredicate(Predicate pred);
|
||||
|
||||
/// @returns true if the specified compare predicate is
|
||||
/// true when both operands are equal...
|
||||
/// @brief Determine if the icmp is true when both operands are equal
|
||||
static bool isTrueWhenEqual(ICmpInst::Predicate pred) {
|
||||
return pred == ICmpInst::ICMP_EQ || pred == ICmpInst::ICMP_UGE ||
|
||||
pred == ICmpInst::ICMP_SGE || pred == ICmpInst::ICMP_ULE ||
|
||||
pred == ICmpInst::ICMP_SLE;
|
||||
}
|
||||
|
||||
/// @returns true if the specified compare instruction is
|
||||
/// true when both operands are equal...
|
||||
/// @brief Determine if the ICmpInst returns true when both operands are equal
|
||||
bool isTrueWhenEqual() {
|
||||
return isTrueWhenEqual(getPredicate());
|
||||
}
|
||||
|
||||
/// Initialize a set of values that all satisfy the predicate with C.
|
||||
/// @brief Make a ConstantRange for a relation with a constant value.
|
||||
static ConstantRange makeConstantRange(Predicate pred, const APInt &C);
|
||||
@ -775,8 +679,6 @@ class ICmpInst: public CmpInst {
|
||||
Op<0>().swap(Op<1>());
|
||||
}
|
||||
|
||||
virtual ICmpInst *clone() const;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const ICmpInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -797,6 +699,9 @@ class ICmpInst: public CmpInst {
|
||||
/// vectors of floating point values. The operands must be identical types.
|
||||
/// @brief Represents a floating point comparison operator.
|
||||
class FCmpInst: public CmpInst {
|
||||
protected:
|
||||
/// @brief Clone an indentical FCmpInst
|
||||
virtual FCmpInst *clone_impl() const;
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics.
|
||||
FCmpInst(
|
||||
@ -884,8 +789,6 @@ class FCmpInst: public CmpInst {
|
||||
Op<0>().swap(Op<1>());
|
||||
}
|
||||
|
||||
virtual FCmpInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const FCmpInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -953,6 +856,8 @@ class CallInst : public Instruction {
|
||||
explicit CallInst(Value *F, const Twine &NameStr,
|
||||
Instruction *InsertBefore);
|
||||
CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual CallInst *clone_impl() const;
|
||||
public:
|
||||
template<typename InputIterator>
|
||||
static CallInst *Create(Value *Func,
|
||||
@ -1000,6 +905,9 @@ class CallInst : public Instruction {
|
||||
const Type *IntPtrTy, const Type *AllocTy,
|
||||
Value *ArraySize = 0, Function* MallocF = 0,
|
||||
const Twine &Name = "");
|
||||
/// CreateFree - Generate the IR for a call to the builtin free function.
|
||||
static void CreateFree(Value* Source, Instruction *InsertBefore);
|
||||
static Instruction* CreateFree(Value* Source, BasicBlock *InsertAtEnd);
|
||||
|
||||
~CallInst();
|
||||
|
||||
@ -1008,8 +916,6 @@ class CallInst : public Instruction {
|
||||
SubclassData = (SubclassData & ~1) | unsigned(isTC);
|
||||
}
|
||||
|
||||
virtual CallInst *clone() const;
|
||||
|
||||
/// Provide fast operand accessors
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
@ -1177,6 +1083,8 @@ class SelectInst : public Instruction {
|
||||
init(C, S1, S2);
|
||||
setName(NameStr);
|
||||
}
|
||||
protected:
|
||||
virtual SelectInst *clone_impl() const;
|
||||
public:
|
||||
static SelectInst *Create(Value *C, Value *S1, Value *S2,
|
||||
const Twine &NameStr = "",
|
||||
@ -1207,8 +1115,6 @@ class SelectInst : public Instruction {
|
||||
return static_cast<OtherOps>(Instruction::getOpcode());
|
||||
}
|
||||
|
||||
virtual SelectInst *clone() const;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SelectInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -1233,6 +1139,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value)
|
||||
/// an argument of the specified type given a va_list and increments that list
|
||||
///
|
||||
class VAArgInst : public UnaryInstruction {
|
||||
protected:
|
||||
virtual VAArgInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
VAArgInst(Value *List, const Type *Ty, const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0)
|
||||
@ -1245,8 +1154,6 @@ class VAArgInst : public UnaryInstruction {
|
||||
setName(NameStr);
|
||||
}
|
||||
|
||||
virtual VAArgInst *clone() const;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const VAArgInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -1269,6 +1176,9 @@ class ExtractElementInst : public Instruction {
|
||||
Instruction *InsertBefore = 0);
|
||||
ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual ExtractElementInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
static ExtractElementInst *Create(Value *Vec, Value *Idx,
|
||||
const Twine &NameStr = "",
|
||||
@ -1285,8 +1195,6 @@ class ExtractElementInst : public Instruction {
|
||||
/// formed with the specified operands.
|
||||
static bool isValidOperands(const Value *Vec, const Value *Idx);
|
||||
|
||||
virtual ExtractElementInst *clone() const;
|
||||
|
||||
Value *getVectorOperand() { return Op<0>(); }
|
||||
Value *getIndexOperand() { return Op<1>(); }
|
||||
const Value *getVectorOperand() const { return Op<0>(); }
|
||||
@ -1329,6 +1237,9 @@ class InsertElementInst : public Instruction {
|
||||
Instruction *InsertBefore = 0);
|
||||
InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual InsertElementInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
|
||||
const Twine &NameStr = "",
|
||||
@ -1346,8 +1257,6 @@ class InsertElementInst : public Instruction {
|
||||
static bool isValidOperands(const Value *Vec, const Value *NewElt,
|
||||
const Value *Idx);
|
||||
|
||||
virtual InsertElementInst *clone() const;
|
||||
|
||||
/// getType - Overload to return most specific vector type.
|
||||
///
|
||||
const VectorType *getType() const {
|
||||
@ -1381,6 +1290,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
|
||||
/// input vectors.
|
||||
///
|
||||
class ShuffleVectorInst : public Instruction {
|
||||
protected:
|
||||
virtual ShuffleVectorInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
// allocate space for exactly three operands
|
||||
void *operator new(size_t s) {
|
||||
@ -1397,8 +1309,6 @@ class ShuffleVectorInst : public Instruction {
|
||||
static bool isValidOperands(const Value *V1, const Value *V2,
|
||||
const Value *Mask);
|
||||
|
||||
virtual ShuffleVectorInst *clone() const;
|
||||
|
||||
/// getType - Overload to return most specific vector type.
|
||||
///
|
||||
const VectorType *getType() const {
|
||||
@ -1507,6 +1417,8 @@ class ExtractValueInst : public UnaryInstruction {
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 1);
|
||||
}
|
||||
protected:
|
||||
virtual ExtractValueInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
template<typename InputIterator>
|
||||
@ -1541,8 +1453,6 @@ class ExtractValueInst : public UnaryInstruction {
|
||||
return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
virtual ExtractValueInst *clone() const;
|
||||
|
||||
/// getIndexedType - Returns the type of the element that would be extracted
|
||||
/// with an extractvalue instruction with the specified parameters.
|
||||
///
|
||||
@ -1674,6 +1584,8 @@ class InsertValueInst : public Instruction {
|
||||
Instruction *InsertBefore = 0);
|
||||
InsertValueInst(Value *Agg, Value *Val, unsigned Idx,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual InsertValueInst *clone_impl() const;
|
||||
public:
|
||||
// allocate space for exactly two operands
|
||||
void *operator new(size_t s) {
|
||||
@ -1711,8 +1623,6 @@ class InsertValueInst : public Instruction {
|
||||
return new InsertValueInst(Agg, Val, Idx, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
virtual InsertValueInst *clone() const;
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
@ -1821,6 +1731,8 @@ class PHINode : public Instruction {
|
||||
ReservedSpace(0) {
|
||||
setName(NameStr);
|
||||
}
|
||||
protected:
|
||||
virtual PHINode *clone_impl() const;
|
||||
public:
|
||||
static PHINode *Create(const Type *Ty, const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
@ -1840,8 +1752,6 @@ class PHINode : public Instruction {
|
||||
resizeOperands(NumValues*2);
|
||||
}
|
||||
|
||||
virtual PHINode *clone() const;
|
||||
|
||||
/// Provide fast operand accessors
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
@ -1891,7 +1801,7 @@ class PHINode : public Instruction {
|
||||
|
||||
|
||||
void setIncomingBlock(unsigned i, BasicBlock *BB) {
|
||||
setOperand(i*2+1, BB);
|
||||
setOperand(i*2+1, (Value*)BB);
|
||||
}
|
||||
static unsigned getOperandNumForIncomingBlock(unsigned i) {
|
||||
return i*2+1;
|
||||
@ -1914,7 +1824,7 @@ class PHINode : public Instruction {
|
||||
// Initialize some new operands.
|
||||
NumOperands = OpNo+2;
|
||||
OperandList[OpNo] = V;
|
||||
OperandList[OpNo+1] = BB;
|
||||
OperandList[OpNo+1] = (Value*)BB;
|
||||
}
|
||||
|
||||
/// removeIncomingValue - Remove an incoming value. This is useful if a
|
||||
@ -1939,7 +1849,7 @@ class PHINode : public Instruction {
|
||||
int getBasicBlockIndex(const BasicBlock *BB) const {
|
||||
Use *OL = OperandList;
|
||||
for (unsigned i = 0, e = getNumOperands(); i != e; i += 2)
|
||||
if (OL[i+1].get() == BB) return i/2;
|
||||
if (OL[i+1].get() == (const Value*)BB) return i/2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2003,6 +1913,8 @@ class ReturnInst : public TerminatorInst {
|
||||
Instruction *InsertBefore = 0);
|
||||
ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd);
|
||||
explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual ReturnInst *clone_impl() const;
|
||||
public:
|
||||
static ReturnInst* Create(LLVMContext &C, Value *retVal = 0,
|
||||
Instruction *InsertBefore = 0) {
|
||||
@ -2017,8 +1929,6 @@ class ReturnInst : public TerminatorInst {
|
||||
}
|
||||
virtual ~ReturnInst();
|
||||
|
||||
virtual ReturnInst *clone() const;
|
||||
|
||||
/// Provide fast operand accessors
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
@ -2078,6 +1988,8 @@ class BranchInst : public TerminatorInst {
|
||||
BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd);
|
||||
BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
|
||||
BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual BranchInst *clone_impl() const;
|
||||
public:
|
||||
static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = 0) {
|
||||
return new(1, true) BranchInst(IfTrue, InsertBefore);
|
||||
@ -2099,8 +2011,6 @@ class BranchInst : public TerminatorInst {
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
virtual BranchInst *clone() const;
|
||||
|
||||
bool isUnconditional() const { return getNumOperands() == 1; }
|
||||
bool isConditional() const { return getNumOperands() == 3; }
|
||||
|
||||
@ -2118,7 +2028,7 @@ class BranchInst : public TerminatorInst {
|
||||
// targeting the specified block.
|
||||
// FIXME: Eliminate this ugly method.
|
||||
void setUnconditionalDest(BasicBlock *Dest) {
|
||||
Op<-1>() = Dest;
|
||||
Op<-1>() = (Value*)Dest;
|
||||
if (isConditional()) { // Convert this to an uncond branch.
|
||||
Op<-2>() = 0;
|
||||
Op<-3>() = 0;
|
||||
@ -2136,7 +2046,7 @@ class BranchInst : public TerminatorInst {
|
||||
|
||||
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
|
||||
assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
|
||||
*(&Op<-1>() - idx) = NewSucc;
|
||||
*(&Op<-1>() - idx) = (Value*)NewSucc;
|
||||
}
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
@ -2172,7 +2082,7 @@ class SwitchInst : public TerminatorInst {
|
||||
// Operand[1] = Default basic block destination
|
||||
// Operand[2n ] = Value to match
|
||||
// Operand[2n+1] = BasicBlock to go to on match
|
||||
SwitchInst(const SwitchInst &RI);
|
||||
SwitchInst(const SwitchInst &SI);
|
||||
void init(Value *Value, BasicBlock *Default, unsigned NumCases);
|
||||
void resizeOperands(unsigned No);
|
||||
// allocate space for exactly zero operands
|
||||
@ -2184,7 +2094,7 @@ class SwitchInst : public TerminatorInst {
|
||||
/// be specified here to make memory allocation more efficient. This
|
||||
/// constructor can also autoinsert before another instruction.
|
||||
SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
|
||||
Instruction *InsertBefore = 0);
|
||||
Instruction *InsertBefore);
|
||||
|
||||
/// SwitchInst ctor - Create a new switch instruction, specifying a value to
|
||||
/// switch on and a default destination. The number of additional cases can
|
||||
@ -2192,6 +2102,8 @@ class SwitchInst : public TerminatorInst {
|
||||
/// constructor also autoinserts at the end of the specified BasicBlock.
|
||||
SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
|
||||
BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual SwitchInst *clone_impl() const;
|
||||
public:
|
||||
static SwitchInst *Create(Value *Value, BasicBlock *Default,
|
||||
unsigned NumCases, Instruction *InsertBefore = 0) {
|
||||
@ -2269,8 +2181,6 @@ class SwitchInst : public TerminatorInst {
|
||||
///
|
||||
void removeCase(unsigned idx);
|
||||
|
||||
virtual SwitchInst *clone() const;
|
||||
|
||||
unsigned getNumSuccessors() const { return getNumOperands()/2; }
|
||||
BasicBlock *getSuccessor(unsigned idx) const {
|
||||
assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
|
||||
@ -2278,7 +2188,7 @@ class SwitchInst : public TerminatorInst {
|
||||
}
|
||||
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
|
||||
assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
|
||||
setOperand(idx*2+1, NewSucc);
|
||||
setOperand(idx*2+1, (Value*)NewSucc);
|
||||
}
|
||||
|
||||
// getSuccessorValue - Return the value associated with the specified
|
||||
@ -2309,6 +2219,105 @@ struct OperandTraits<SwitchInst> : public HungoffOperandTraits<2> {
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// IndirectBrInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===---------------------------------------------------------------------------
|
||||
/// IndirectBrInst - Indirect Branch Instruction.
|
||||
///
|
||||
class IndirectBrInst : public TerminatorInst {
|
||||
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
|
||||
unsigned ReservedSpace;
|
||||
// Operand[0] = Value to switch on
|
||||
// Operand[1] = Default basic block destination
|
||||
// Operand[2n ] = Value to match
|
||||
// Operand[2n+1] = BasicBlock to go to on match
|
||||
IndirectBrInst(const IndirectBrInst &IBI);
|
||||
void init(Value *Address, unsigned NumDests);
|
||||
void resizeOperands(unsigned No);
|
||||
// allocate space for exactly zero operands
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 0);
|
||||
}
|
||||
/// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an
|
||||
/// Address to jump to. The number of expected destinations can be specified
|
||||
/// here to make memory allocation more efficient. This constructor can also
|
||||
/// autoinsert before another instruction.
|
||||
IndirectBrInst(Value *Address, unsigned NumDests, Instruction *InsertBefore);
|
||||
|
||||
/// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an
|
||||
/// Address to jump to. The number of expected destinations can be specified
|
||||
/// here to make memory allocation more efficient. This constructor also
|
||||
/// autoinserts at the end of the specified BasicBlock.
|
||||
IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual IndirectBrInst *clone_impl() const;
|
||||
public:
|
||||
static IndirectBrInst *Create(Value *Address, unsigned NumDests,
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new IndirectBrInst(Address, NumDests, InsertBefore);
|
||||
}
|
||||
static IndirectBrInst *Create(Value *Address, unsigned NumDests,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new IndirectBrInst(Address, NumDests, InsertAtEnd);
|
||||
}
|
||||
~IndirectBrInst();
|
||||
|
||||
/// Provide fast operand accessors.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
// Accessor Methods for IndirectBrInst instruction.
|
||||
Value *getAddress() { return getOperand(0); }
|
||||
const Value *getAddress() const { return getOperand(0); }
|
||||
void setAddress(Value *V) { setOperand(0, V); }
|
||||
|
||||
|
||||
/// getNumDestinations - return the number of possible destinations in this
|
||||
/// indirectbr instruction.
|
||||
unsigned getNumDestinations() const { return getNumOperands()-1; }
|
||||
|
||||
/// getDestination - Return the specified destination.
|
||||
BasicBlock *getDestination(unsigned i) { return getSuccessor(i); }
|
||||
const BasicBlock *getDestination(unsigned i) const { return getSuccessor(i); }
|
||||
|
||||
/// addDestination - Add a destination.
|
||||
///
|
||||
void addDestination(BasicBlock *Dest);
|
||||
|
||||
/// removeDestination - This method removes the specified successor from the
|
||||
/// indirectbr instruction.
|
||||
void removeDestination(unsigned i);
|
||||
|
||||
unsigned getNumSuccessors() const { return getNumOperands()-1; }
|
||||
BasicBlock *getSuccessor(unsigned i) const {
|
||||
return cast<BasicBlock>(getOperand(i+1));
|
||||
}
|
||||
void setSuccessor(unsigned i, BasicBlock *NewSucc) {
|
||||
setOperand(i+1, (Value*)NewSucc);
|
||||
}
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const IndirectBrInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::IndirectBr;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
private:
|
||||
virtual BasicBlock *getSuccessorV(unsigned idx) const;
|
||||
virtual unsigned getNumSuccessorsV() const;
|
||||
virtual void setSuccessorV(unsigned idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperandTraits<IndirectBrInst> : public HungoffOperandTraits<1> {
|
||||
};
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// InvokeInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -2361,6 +2370,8 @@ class InvokeInst : public TerminatorInst {
|
||||
InputIterator ArgBegin, InputIterator ArgEnd,
|
||||
unsigned Values,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
protected:
|
||||
virtual InvokeInst *clone_impl() const;
|
||||
public:
|
||||
template<typename InputIterator>
|
||||
static InvokeInst *Create(Value *Func,
|
||||
@ -2383,8 +2394,6 @@ class InvokeInst : public TerminatorInst {
|
||||
Values, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
virtual InvokeInst *clone() const;
|
||||
|
||||
/// Provide fast operand accessors
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
@ -2487,11 +2496,11 @@ class InvokeInst : public TerminatorInst {
|
||||
return cast<BasicBlock>(getOperand(2));
|
||||
}
|
||||
void setNormalDest(BasicBlock *B) {
|
||||
setOperand(1, B);
|
||||
setOperand(1, (Value*)B);
|
||||
}
|
||||
|
||||
void setUnwindDest(BasicBlock *B) {
|
||||
setOperand(2, B);
|
||||
setOperand(2, (Value*)B);
|
||||
}
|
||||
|
||||
BasicBlock *getSuccessor(unsigned i) const {
|
||||
@ -2501,7 +2510,7 @@ class InvokeInst : public TerminatorInst {
|
||||
|
||||
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
|
||||
assert(idx < 2 && "Successor # out of range for invoke!");
|
||||
setOperand(idx+1, NewSucc);
|
||||
setOperand(idx+1, (Value*)NewSucc);
|
||||
}
|
||||
|
||||
unsigned getNumSuccessors() const { return 2; }
|
||||
@ -2565,6 +2574,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value)
|
||||
///
|
||||
class UnwindInst : public TerminatorInst {
|
||||
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
|
||||
protected:
|
||||
virtual UnwindInst *clone_impl() const;
|
||||
public:
|
||||
// allocate space for exactly zero operands
|
||||
void *operator new(size_t s) {
|
||||
@ -2573,8 +2584,6 @@ class UnwindInst : public TerminatorInst {
|
||||
explicit UnwindInst(LLVMContext &C, Instruction *InsertBefore = 0);
|
||||
explicit UnwindInst(LLVMContext &C, BasicBlock *InsertAtEnd);
|
||||
|
||||
virtual UnwindInst *clone() const;
|
||||
|
||||
unsigned getNumSuccessors() const { return 0; }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
@ -2602,6 +2611,9 @@ class UnwindInst : public TerminatorInst {
|
||||
///
|
||||
class UnreachableInst : public TerminatorInst {
|
||||
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
|
||||
protected:
|
||||
virtual UnreachableInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
// allocate space for exactly zero operands
|
||||
void *operator new(size_t s) {
|
||||
@ -2610,8 +2622,6 @@ class UnreachableInst : public TerminatorInst {
|
||||
explicit UnreachableInst(LLVMContext &C, Instruction *InsertBefore = 0);
|
||||
explicit UnreachableInst(LLVMContext &C, BasicBlock *InsertAtEnd);
|
||||
|
||||
virtual UnreachableInst *clone() const;
|
||||
|
||||
unsigned getNumSuccessors() const { return 0; }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
@ -2634,6 +2644,10 @@ class UnreachableInst : public TerminatorInst {
|
||||
|
||||
/// @brief This class represents a truncation of integer types.
|
||||
class TruncInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical TruncInst
|
||||
virtual TruncInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
TruncInst(
|
||||
@ -2651,9 +2665,6 @@ class TruncInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical TruncInst
|
||||
virtual TruncInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const TruncInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2670,6 +2681,10 @@ class TruncInst : public CastInst {
|
||||
|
||||
/// @brief This class represents zero extension of integer types.
|
||||
class ZExtInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical ZExtInst
|
||||
virtual ZExtInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
ZExtInst(
|
||||
@ -2687,9 +2702,6 @@ class ZExtInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical ZExtInst
|
||||
virtual ZExtInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const ZExtInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2706,6 +2718,10 @@ class ZExtInst : public CastInst {
|
||||
|
||||
/// @brief This class represents a sign extension of integer types.
|
||||
class SExtInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical SExtInst
|
||||
virtual SExtInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
SExtInst(
|
||||
@ -2723,9 +2739,6 @@ class SExtInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical SExtInst
|
||||
virtual SExtInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SExtInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2742,6 +2755,10 @@ class SExtInst : public CastInst {
|
||||
|
||||
/// @brief This class represents a truncation of floating point types.
|
||||
class FPTruncInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical FPTruncInst
|
||||
virtual FPTruncInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
FPTruncInst(
|
||||
@ -2759,9 +2776,6 @@ class FPTruncInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical FPTruncInst
|
||||
virtual FPTruncInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const FPTruncInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2778,6 +2792,10 @@ class FPTruncInst : public CastInst {
|
||||
|
||||
/// @brief This class represents an extension of floating point types.
|
||||
class FPExtInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical FPExtInst
|
||||
virtual FPExtInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
FPExtInst(
|
||||
@ -2795,9 +2813,6 @@ class FPExtInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical FPExtInst
|
||||
virtual FPExtInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const FPExtInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2814,6 +2829,10 @@ class FPExtInst : public CastInst {
|
||||
|
||||
/// @brief This class represents a cast unsigned integer to floating point.
|
||||
class UIToFPInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical UIToFPInst
|
||||
virtual UIToFPInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
UIToFPInst(
|
||||
@ -2831,9 +2850,6 @@ class UIToFPInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical UIToFPInst
|
||||
virtual UIToFPInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const UIToFPInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2850,6 +2866,10 @@ class UIToFPInst : public CastInst {
|
||||
|
||||
/// @brief This class represents a cast from signed integer to floating point.
|
||||
class SIToFPInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical SIToFPInst
|
||||
virtual SIToFPInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
SIToFPInst(
|
||||
@ -2867,9 +2887,6 @@ class SIToFPInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical SIToFPInst
|
||||
virtual SIToFPInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SIToFPInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2886,6 +2903,10 @@ class SIToFPInst : public CastInst {
|
||||
|
||||
/// @brief This class represents a cast from floating point to unsigned integer
|
||||
class FPToUIInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical FPToUIInst
|
||||
virtual FPToUIInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
FPToUIInst(
|
||||
@ -2903,9 +2924,6 @@ class FPToUIInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< Where to insert the new instruction
|
||||
);
|
||||
|
||||
/// @brief Clone an identical FPToUIInst
|
||||
virtual FPToUIInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const FPToUIInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2922,6 +2940,10 @@ class FPToUIInst : public CastInst {
|
||||
|
||||
/// @brief This class represents a cast from floating point to signed integer.
|
||||
class FPToSIInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical FPToSIInst
|
||||
virtual FPToSIInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
FPToSIInst(
|
||||
@ -2939,9 +2961,6 @@ class FPToSIInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical FPToSIInst
|
||||
virtual FPToSIInst *clone() const;
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const FPToSIInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -2976,7 +2995,7 @@ class IntToPtrInst : public CastInst {
|
||||
);
|
||||
|
||||
/// @brief Clone an identical IntToPtrInst
|
||||
virtual IntToPtrInst *clone() const;
|
||||
virtual IntToPtrInst *clone_impl() const;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const IntToPtrInst *) { return true; }
|
||||
@ -2994,6 +3013,10 @@ class IntToPtrInst : public CastInst {
|
||||
|
||||
/// @brief This class represents a cast from a pointer to an integer
|
||||
class PtrToIntInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical PtrToIntInst
|
||||
virtual PtrToIntInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
PtrToIntInst(
|
||||
@ -3011,9 +3034,6 @@ class PtrToIntInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical PtrToIntInst
|
||||
virtual PtrToIntInst *clone() const;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const PtrToIntInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
@ -3030,6 +3050,10 @@ class PtrToIntInst : public CastInst {
|
||||
|
||||
/// @brief This class represents a no-op cast from one type to another.
|
||||
class BitCastInst : public CastInst {
|
||||
protected:
|
||||
/// @brief Clone an identical BitCastInst
|
||||
virtual BitCastInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
/// @brief Constructor with insert-before-instruction semantics
|
||||
BitCastInst(
|
||||
@ -3047,9 +3071,6 @@ class BitCastInst : public CastInst {
|
||||
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
|
||||
);
|
||||
|
||||
/// @brief Clone an identical BitCastInst
|
||||
virtual BitCastInst *clone() const;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const BitCastInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
|
@ -259,6 +259,11 @@ def int_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>;
|
||||
def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>;
|
||||
def int_siglongjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>;
|
||||
|
||||
// Internal interface for object size checking
|
||||
def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i32_ty],
|
||||
[IntrReadArgMem]>,
|
||||
GCCBuiltin<"__builtin_object_size">;
|
||||
|
||||
//===-------------------- Bit Manipulation Intrinsics ---------------------===//
|
||||
//
|
||||
|
||||
|
@ -91,7 +91,6 @@ namespace {
|
||||
(void) llvm::createLoopUnswitchPass();
|
||||
(void) llvm::createLoopRotatePass();
|
||||
(void) llvm::createLoopIndexSplitPass();
|
||||
(void) llvm::createLowerAllocationsPass();
|
||||
(void) llvm::createLowerInvokePass();
|
||||
(void) llvm::createLowerSetJmpPass();
|
||||
(void) llvm::createLowerSwitchPass();
|
||||
@ -107,7 +106,6 @@ namespace {
|
||||
(void) llvm::createPostDomPrinterPass();
|
||||
(void) llvm::createPostDomOnlyViewerPass();
|
||||
(void) llvm::createPostDomViewerPass();
|
||||
(void) llvm::createRaiseAllocationsPass();
|
||||
(void) llvm::createReassociatePass();
|
||||
(void) llvm::createSCCPPass();
|
||||
(void) llvm::createScalarReplAggregatesPass();
|
||||
@ -125,7 +123,6 @@ namespace {
|
||||
(void) llvm::createNullProfilerRSPass();
|
||||
(void) llvm::createRSProfilingPass();
|
||||
(void) llvm::createInstCountPass();
|
||||
(void) llvm::createCodeGenLICMPass();
|
||||
(void) llvm::createCodeGenPreparePass();
|
||||
(void) llvm::createGVNPass();
|
||||
(void) llvm::createMemCpyOptPass();
|
||||
@ -142,6 +139,9 @@ namespace {
|
||||
(void) llvm::createPartialInliningPass();
|
||||
(void) llvm::createSSIPass();
|
||||
(void) llvm::createSSIEverythingPass();
|
||||
(void) llvm::createGEPSplitterPass();
|
||||
(void) llvm::createSCCVNPass();
|
||||
(void) llvm::createABCDPass();
|
||||
|
||||
(void)new llvm::IntervalPartition();
|
||||
(void)new llvm::FindUsedTypes();
|
||||
|
@ -11,7 +11,7 @@
|
||||
#define LLVM_MC_MCASMLEXER_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCAsmLexer;
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef LLVM_MC_MCASMPARSER_H
|
||||
#define LLVM_MC_MCASMPARSER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCAsmLexer;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <vector> // FIXME: Shouldn't be needed.
|
||||
|
||||
namespace llvm {
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef MCDISASSEMBLER_H
|
||||
#define MCDISASSEMBLER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#define LLVM_MC_MCEXPR_H
|
||||
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCAsmInfo;
|
||||
|
@ -17,7 +17,7 @@
|
||||
#define LLVM_MC_MCINST_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
@ -43,7 +43,6 @@ class MCOperand {
|
||||
public:
|
||||
|
||||
MCOperand() : Kind(kInvalid) {}
|
||||
MCOperand(const MCOperand &RHS) { *this = RHS; }
|
||||
|
||||
bool isValid() const { return Kind != kInvalid; }
|
||||
bool isReg() const { return Kind == kRegister; }
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_MC_MCSTREAMER_H
|
||||
#define LLVM_MC_MCSTREAMER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCAsmInfo;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include <string>
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCAsmInfo;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_MC_MCVALUE_H
|
||||
#define LLVM_MC_MCVALUE_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include <cassert>
|
||||
|
||||
|
@ -63,7 +63,7 @@ class MDString : public MetadataBase {
|
||||
|
||||
StringRef getString() const { return Str; }
|
||||
|
||||
unsigned getLength() const { return Str.size(); }
|
||||
unsigned getLength() const { return (unsigned)Str.size(); }
|
||||
|
||||
typedef StringRef::iterator iterator;
|
||||
|
||||
@ -191,7 +191,7 @@ class NamedMDNode : public MetadataBase, public ilist_node<NamedMDNode> {
|
||||
|
||||
/// getNumElements - Return number of NamedMDNode elements.
|
||||
unsigned getNumElements() const {
|
||||
return Node.size();
|
||||
return (unsigned)Node.size();
|
||||
}
|
||||
|
||||
/// addElement - Add metadata element.
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/GlobalAlias.h"
|
||||
#include "llvm/Metadata.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
@ -252,6 +252,7 @@ class Module {
|
||||
AttrListPtr AttributeList,
|
||||
const Type *RetTy, ...) END_WITH_NULL;
|
||||
|
||||
/// getOrInsertFunction - Same as above, but without the attributes.
|
||||
Constant *getOrInsertFunction(const StringRef &Name, const Type *RetTy, ...)
|
||||
END_WITH_NULL;
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#ifndef LLVM_PASS_H
|
||||
#define LLVM_PASS_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define LLVM_SUPPORT_ALLOCATOR_H
|
||||
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#define LLVM_SUPPORT_CONSTANT_RANGE_H
|
||||
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -28,39 +28,47 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// DebugFlag - This boolean is set to true if the '-debug' command line option
|
||||
// is specified. This should probably not be referenced directly, instead, use
|
||||
// the DEBUG macro below.
|
||||
//
|
||||
/// DEBUG_TYPE macro - Files can specify a DEBUG_TYPE as a string, which causes
|
||||
/// all of their DEBUG statements to be activatable with -debug-only=thatstring.
|
||||
#ifndef DEBUG_TYPE
|
||||
#define DEBUG_TYPE ""
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
/// DebugFlag - This boolean is set to true if the '-debug' command line option
|
||||
/// is specified. This should probably not be referenced directly, instead, use
|
||||
/// the DEBUG macro below.
|
||||
///
|
||||
extern bool DebugFlag;
|
||||
#endif
|
||||
|
||||
// isCurrentDebugType - Return true if the specified string is the debug type
|
||||
// specified on the command line, or if none was specified on the command line
|
||||
// with the -debug-only=X option.
|
||||
//
|
||||
#ifndef NDEBUG
|
||||
|
||||
/// isCurrentDebugType - Return true if the specified string is the debug type
|
||||
/// specified on the command line, or if none was specified on the command line
|
||||
/// with the -debug-only=X option.
|
||||
///
|
||||
bool isCurrentDebugType(const char *Type);
|
||||
#else
|
||||
#define isCurrentDebugType(X) (false)
|
||||
#endif
|
||||
|
||||
// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
|
||||
// information. In the '-debug' option is specified on the commandline, and if
|
||||
// this is a debug build, then the code specified as the option to the macro
|
||||
// will be executed. Otherwise it will not be. Example:
|
||||
//
|
||||
// DEBUG_WITH_TYPE("bitset", errs() << "Bitset contains: " << Bitset << "\n");
|
||||
//
|
||||
// This will emit the debug information if -debug is present, and -debug-only is
|
||||
// not specified, or is specified as "bitset".
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0)
|
||||
#else
|
||||
/// SetCurrentDebugType - Set the current debug type, as if the -debug-only=X
|
||||
/// option were specified. Note that DebugFlag also needs to be set to true for
|
||||
/// debug output to be produced.
|
||||
///
|
||||
void SetCurrentDebugType(const char *Type);
|
||||
|
||||
/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
|
||||
/// information. In the '-debug' option is specified on the commandline, and if
|
||||
/// this is a debug build, then the code specified as the option to the macro
|
||||
/// will be executed. Otherwise it will not be. Example:
|
||||
///
|
||||
/// DEBUG_WITH_TYPE("bitset", errs() << "Bitset contains: " << Bitset << "\n");
|
||||
///
|
||||
/// This will emit the debug information if -debug is present, and -debug-only
|
||||
/// is not specified, or is specified as "bitset".
|
||||
#define DEBUG_WITH_TYPE(TYPE, X) \
|
||||
do { if (DebugFlag && isCurrentDebugType(TYPE)) { X; } } while (0)
|
||||
|
||||
#else
|
||||
#define isCurrentDebugType(X) (false)
|
||||
#define SetCurrentDebugType(X)
|
||||
#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0)
|
||||
#endif
|
||||
|
||||
// DEBUG macro - This macro should be used by passes to emit debug information.
|
||||
@ -70,11 +78,6 @@ bool isCurrentDebugType(const char *Type);
|
||||
//
|
||||
// DEBUG(errs() << "Bitset contains: " << Bitset << "\n");
|
||||
//
|
||||
|
||||
#ifndef DEBUG_TYPE
|
||||
#define DEBUG_TYPE ""
|
||||
#endif
|
||||
|
||||
#define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X)
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifndef LLVM_SUPPORT_ELF_H
|
||||
#define LLVM_SUPPORT_ELF_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -253,6 +253,13 @@ class IRBuilder : public Inserter {
|
||||
return Insert(SwitchInst::Create(V, Dest, NumCases));
|
||||
}
|
||||
|
||||
/// CreateIndirectBr - Create an indirect branch instruction with the
|
||||
/// specified address operand, with an optional hint for the number of
|
||||
/// destinations that will be added (for efficient allocation).
|
||||
IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) {
|
||||
return Insert(IndirectBrInst::Create(Addr, NumDests));
|
||||
}
|
||||
|
||||
/// CreateInvoke - Create an invoke instruction.
|
||||
template<typename InputIterator>
|
||||
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
|
||||
@ -383,15 +390,21 @@ class IRBuilder : public Inserter {
|
||||
return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS))
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS)) {
|
||||
if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue())
|
||||
return LHS; // LHS & -1 -> LHS
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateAnd(LC, RC);
|
||||
}
|
||||
return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS))
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS)) {
|
||||
if (RC->isNullValue())
|
||||
return LHS; // LHS | 0 -> LHS
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateOr(LC, RC);
|
||||
}
|
||||
return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
@ -433,9 +446,6 @@ class IRBuilder : public Inserter {
|
||||
const Twine &Name = "") {
|
||||
return Insert(new AllocaInst(Ty, ArraySize), Name);
|
||||
}
|
||||
FreeInst *CreateFree(Value *Ptr) {
|
||||
return Insert(new FreeInst(Ptr));
|
||||
}
|
||||
// Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
|
||||
// converting the string to 'bool' for the isVolatile parameter.
|
||||
LoadInst *CreateLoad(Value *Ptr, const char *Name) {
|
||||
|
@ -160,13 +160,13 @@ class InstVisitor {
|
||||
RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
|
||||
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
|
||||
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
|
||||
RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); }
|
||||
@ -198,7 +198,6 @@ class InstVisitor {
|
||||
//
|
||||
RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
|
||||
RetTy visitAllocationInst(AllocationInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); }
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_SUPPORT_MATHEXTRAS_H
|
||||
#define LLVM_SUPPORT_MATHEXTRAS_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define LLVM_SUPPORT_MEMORYBUFFER_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef MEMORYOBJECT_H
|
||||
#define MEMORYOBJECT_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user